af 0.3.22 → 0.5.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +14 -6
  2. data/LICENSE +1277 -24
  3. data/Rakefile +24 -87
  4. data/bin/af +7 -2
  5. data/lib/af/version.rb +3 -0
  6. data/lib/vmc.rb +7 -2
  7. data/lib/vmc/cli.rb +475 -0
  8. data/lib/vmc/cli/app/app.rb +45 -0
  9. data/lib/vmc/cli/app/apps.rb +105 -0
  10. data/lib/vmc/cli/app/base.rb +82 -0
  11. data/lib/vmc/cli/app/crashes.rb +46 -0
  12. data/lib/vmc/cli/app/delete.rb +95 -0
  13. data/lib/vmc/cli/app/deprecated.rb +11 -0
  14. data/lib/vmc/cli/app/env.rb +78 -0
  15. data/lib/vmc/cli/app/files.rb +137 -0
  16. data/lib/vmc/cli/app/health.rb +26 -0
  17. data/lib/vmc/cli/app/instances.rb +53 -0
  18. data/lib/vmc/cli/app/logs.rb +76 -0
  19. data/lib/vmc/cli/app/push.rb +107 -0
  20. data/lib/vmc/cli/app/push/create.rb +150 -0
  21. data/lib/vmc/cli/app/push/interactions.rb +100 -0
  22. data/lib/vmc/cli/app/push/sync.rb +64 -0
  23. data/lib/vmc/cli/app/rename.rb +39 -0
  24. data/lib/vmc/cli/app/restart.rb +20 -0
  25. data/lib/vmc/cli/app/scale.rb +71 -0
  26. data/lib/vmc/cli/app/start.rb +93 -0
  27. data/lib/vmc/cli/app/stats.rb +67 -0
  28. data/lib/vmc/cli/app/stop.rb +27 -0
  29. data/lib/vmc/cli/domain/base.rb +12 -0
  30. data/lib/vmc/cli/domain/domains.rb +40 -0
  31. data/lib/vmc/cli/domain/map.rb +55 -0
  32. data/lib/vmc/cli/domain/unmap.rb +56 -0
  33. data/lib/vmc/cli/help.rb +16 -0
  34. data/lib/vmc/cli/interactive.rb +105 -0
  35. data/lib/vmc/cli/organization/base.rb +14 -0
  36. data/lib/vmc/cli/organization/create.rb +32 -0
  37. data/lib/vmc/cli/organization/delete.rb +73 -0
  38. data/lib/vmc/cli/organization/org.rb +45 -0
  39. data/lib/vmc/cli/organization/orgs.rb +35 -0
  40. data/lib/vmc/cli/organization/rename.rb +36 -0
  41. data/lib/vmc/cli/route/base.rb +12 -0
  42. data/lib/vmc/cli/route/map.rb +80 -0
  43. data/lib/vmc/cli/route/routes.rb +26 -0
  44. data/lib/vmc/cli/route/unmap.rb +94 -0
  45. data/lib/vmc/cli/service/base.rb +8 -0
  46. data/lib/vmc/cli/service/bind.rb +44 -0
  47. data/lib/vmc/cli/service/create.rb +126 -0
  48. data/lib/vmc/cli/service/delete.rb +86 -0
  49. data/lib/vmc/cli/service/rename.rb +35 -0
  50. data/lib/vmc/cli/service/service.rb +42 -0
  51. data/lib/vmc/cli/service/services.rb +115 -0
  52. data/lib/vmc/cli/service/unbind.rb +38 -0
  53. data/lib/vmc/cli/space/base.rb +21 -0
  54. data/lib/vmc/cli/space/create.rb +56 -0
  55. data/lib/vmc/cli/space/delete.rb +95 -0
  56. data/lib/vmc/cli/space/rename.rb +39 -0
  57. data/lib/vmc/cli/space/space.rb +64 -0
  58. data/lib/vmc/cli/space/spaces.rb +55 -0
  59. data/lib/vmc/cli/space/take.rb +16 -0
  60. data/lib/vmc/cli/start/base.rb +80 -0
  61. data/lib/vmc/cli/start/colors.rb +13 -0
  62. data/lib/vmc/cli/start/info.rb +122 -0
  63. data/lib/vmc/cli/start/login.rb +92 -0
  64. data/lib/vmc/cli/start/logout.rb +13 -0
  65. data/lib/vmc/cli/start/target.rb +64 -0
  66. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  67. data/lib/vmc/cli/start/targets.rb +16 -0
  68. data/lib/vmc/cli/user/base.rb +29 -0
  69. data/lib/vmc/cli/user/create.rb +39 -0
  70. data/lib/vmc/cli/user/delete.rb +25 -0
  71. data/lib/vmc/cli/user/passwd.rb +50 -0
  72. data/lib/vmc/cli/user/register.rb +42 -0
  73. data/lib/vmc/cli/user/users.rb +32 -0
  74. data/lib/vmc/constants.rb +13 -0
  75. data/lib/vmc/detect.rb +134 -0
  76. data/lib/vmc/errors.rb +17 -0
  77. data/lib/vmc/plugin.rb +56 -0
  78. data/lib/vmc/spacing.rb +89 -0
  79. data/lib/vmc/spec_helper.rb +1 -0
  80. data/lib/vmc/test_support.rb +4 -0
  81. data/lib/vmc/test_support/command_helper.rb +32 -0
  82. data/lib/vmc/test_support/common_input_examples.rb +14 -0
  83. data/lib/vmc/test_support/fake_home_dir.rb +16 -0
  84. data/lib/vmc/test_support/interact_helper.rb +29 -0
  85. data/lib/vmc/version.rb +3 -0
  86. data/spec/assets/hello-sinatra/Gemfile +3 -0
  87. data/spec/assets/hello-sinatra/main.rb +6 -0
  88. data/spec/features/new_user_flow_spec.rb +71 -0
  89. data/spec/spec_helper.rb +63 -0
  90. data/spec/vmc/cli/app/base_spec.rb +17 -0
  91. data/spec/vmc/cli/app/delete_spec.rb +188 -0
  92. data/spec/vmc/cli/app/instances_spec.rb +65 -0
  93. data/spec/vmc/cli/app/push/create_spec.rb +571 -0
  94. data/spec/vmc/cli/app/push_spec.rb +369 -0
  95. data/spec/vmc/cli/app/rename_spec.rb +104 -0
  96. data/spec/vmc/cli/app/scale_spec.rb +81 -0
  97. data/spec/vmc/cli/app/stats_spec.rb +62 -0
  98. data/spec/vmc/cli/domain/map_spec.rb +140 -0
  99. data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
  100. data/spec/vmc/cli/organization/orgs_spec.rb +108 -0
  101. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  102. data/spec/vmc/cli/route/map_spec.rb +138 -0
  103. data/spec/vmc/cli/route/unmap_spec.rb +215 -0
  104. data/spec/vmc/cli/service/bind_spec.rb +25 -0
  105. data/spec/vmc/cli/service/delete_spec.rb +22 -0
  106. data/spec/vmc/cli/service/rename_spec.rb +105 -0
  107. data/spec/vmc/cli/service/service_spec.rb +23 -0
  108. data/spec/vmc/cli/service/unbind_spec.rb +25 -0
  109. data/spec/vmc/cli/space/rename_spec.rb +102 -0
  110. data/spec/vmc/cli/space/spaces_spec.rb +104 -0
  111. data/spec/vmc/cli/start/info_spec.rb +153 -0
  112. data/spec/vmc/cli/start/login_spec.rb +71 -0
  113. data/spec/vmc/cli/user/create_spec.rb +54 -0
  114. data/spec/vmc/cli/user/passwd_spec.rb +102 -0
  115. data/spec/vmc/cli/user/register_spec.rb +148 -0
  116. data/spec/vmc/cli_spec.rb +448 -0
  117. data/spec/vmc/detect_spec.rb +54 -0
  118. metadata +231 -124
  119. data/README.md +0 -155
  120. data/caldecott_helper/Gemfile +0 -10
  121. data/caldecott_helper/Gemfile.lock +0 -48
  122. data/caldecott_helper/server.rb +0 -43
  123. data/config/clients.yml +0 -17
  124. data/config/micro/offline.conf +0 -2
  125. data/config/micro/paths.yml +0 -22
  126. data/config/micro/refresh_ip.rb +0 -20
  127. data/lib/cli.rb +0 -48
  128. data/lib/cli/commands/admin.rb +0 -81
  129. data/lib/cli/commands/apps.rb +0 -1358
  130. data/lib/cli/commands/base.rb +0 -233
  131. data/lib/cli/commands/manifest.rb +0 -56
  132. data/lib/cli/commands/micro.rb +0 -115
  133. data/lib/cli/commands/misc.rb +0 -147
  134. data/lib/cli/commands/services.rb +0 -217
  135. data/lib/cli/commands/user.rb +0 -70
  136. data/lib/cli/config.rb +0 -176
  137. data/lib/cli/console_helper.rb +0 -163
  138. data/lib/cli/core_ext.rb +0 -122
  139. data/lib/cli/errors.rb +0 -19
  140. data/lib/cli/file_helper.rb +0 -123
  141. data/lib/cli/frameworks.rb +0 -265
  142. data/lib/cli/manifest_helper.rb +0 -316
  143. data/lib/cli/runner.rb +0 -633
  144. data/lib/cli/services_helper.rb +0 -104
  145. data/lib/cli/tunnel_helper.rb +0 -336
  146. data/lib/cli/usage.rb +0 -129
  147. data/lib/cli/version.rb +0 -7
  148. data/lib/cli/zip_util.rb +0 -102
  149. data/lib/vmc/client.rb +0 -574
  150. data/lib/vmc/const.rb +0 -27
  151. data/lib/vmc/micro.rb +0 -56
  152. data/lib/vmc/micro/switcher/base.rb +0 -97
  153. data/lib/vmc/micro/switcher/darwin.rb +0 -19
  154. data/lib/vmc/micro/switcher/dummy.rb +0 -15
  155. data/lib/vmc/micro/switcher/linux.rb +0 -16
  156. data/lib/vmc/micro/switcher/windows.rb +0 -31
  157. data/lib/vmc/micro/vmrun.rb +0 -158
@@ -1,316 +0,0 @@
1
- require "set"
2
-
3
- module VMC::Cli::ManifestHelper
4
- include VMC::Cli::ServicesHelper
5
-
6
- DEFAULTS = {
7
- "url" => "${name}.${target-base}",
8
- "mem" => "128M",
9
- "instances" => 1
10
- }
11
-
12
- MANIFEST = "manifest.yml"
13
-
14
- YES_SET = Set.new(["y", "Y", "yes", "YES"])
15
-
16
- # take a block and call it once for each app to push/update.
17
- # with @application and @app_info set appropriately
18
- def each_app(panic=true)
19
- if @manifest and all_apps = @manifest["applications"]
20
- where = File.expand_path(@path)
21
- single = false
22
-
23
- all_apps.each do |path, info|
24
- app = File.expand_path("../" + path, manifest_file)
25
- if where.start_with?(app)
26
- @application = app
27
- @app_info = info
28
- yield info["name"]
29
- single = true
30
- break
31
- end
32
- end
33
-
34
- unless single
35
- if where == File.expand_path("../", manifest_file)
36
- ordered_by_deps(all_apps).each do |path, info|
37
- app = File.expand_path("../" + path, manifest_file)
38
- @application = app
39
- @app_info = info
40
- yield info["name"]
41
- end
42
- else
43
- err "Path '#{@path}' is not known to manifest '#{manifest_file}'."
44
- end
45
- end
46
- else
47
- @application = @path
48
- @app_info = @manifest
49
- if @app_info
50
- yield @app_info["name"]
51
- elsif panic
52
- err "No applications."
53
- end
54
- end
55
-
56
- nil
57
- ensure
58
- @application = nil
59
- @app_info = nil
60
- end
61
-
62
- def interact(many=false)
63
- @manifest ||= {}
64
- configure_app(many)
65
- end
66
-
67
- def target_manifest
68
- @options[:manifest] || MANIFEST
69
- end
70
-
71
- def save_manifest(save_to = nil)
72
- save_to ||= target_manifest
73
-
74
- File.open(save_to, "w") do |f|
75
- f.write @manifest.to_yaml
76
- end
77
-
78
- say "Manifest written to #{save_to}."
79
- end
80
-
81
- def configure_app(many=false)
82
- name = manifest("name") ||
83
- set(ask("Application Name", :default => manifest("name")), "name")
84
-
85
- if manifest "framework"
86
- framework = VMC::Cli::Framework.lookup_by_framework manifest("framework","name")
87
- else
88
- framework = detect_framework
89
- set framework.name, "framework", "name"
90
- set(
91
- { "mem" => framework.mem,
92
- "description" => framework.description,
93
- "exec" => framework.exec
94
- },
95
- "framework",
96
- "info"
97
- )
98
- end
99
-
100
- default_runtime = manifest "runtime"
101
- if not default_runtime
102
- default_runtime = framework.default_runtime(@application)
103
- set(detect_runtime(default_runtime), "runtime") if framework.prompt_for_runtime?
104
- end
105
- default_command = manifest "command"
106
- set ask("Start Command", :default => default_command), "command" if framework.require_start_command?
107
-
108
- if client.infra_supported?
109
- infra = @options[:infra] || manifest("infra") ||
110
- client.infra_name_for_description(
111
- ask("Select Infrastructure",:indexed => true, :choices => client.infra_descriptions))
112
- set infra.dup, "infra"
113
- client.infra = infra
114
- end
115
-
116
- url_template = manifest("url") || DEFAULTS["url"]
117
- url_resolved = url_template.dup
118
- resolve_lexically(url_resolved)
119
-
120
- if !framework.require_url?
121
- url_resolved = "None"
122
- end
123
- url = ask("Application Deployed URL", :default => url_resolved)
124
-
125
- if url == url_resolved && url != "None"
126
- url = url_template
127
- end
128
-
129
- # common error case is for prompted users to answer y or Y or yes or
130
- # YES to this ask() resulting in an unintended URL of y. Special
131
- # case this common error
132
- url = url_resolved if YES_SET.member? url
133
-
134
- if(url == "None")
135
- url = nil
136
- end
137
-
138
- set url, "url"
139
-
140
- default_mem = manifest("mem")
141
- default_mem = framework.memory(manifest("runtime")) if not default_mem
142
- set ask(
143
- "Memory reservation",
144
- :default =>
145
- default_mem ||
146
- DEFAULTS["mem"],
147
- :choices => ["128M", "256M", "512M", "1G", "2G"]
148
- ), "mem"
149
-
150
- set ask(
151
- "How many instances?",
152
- :default => manifest("instances") || DEFAULTS["instances"]
153
- ), "instances"
154
-
155
- unless manifest "services"
156
- user_services = services_for_infra(manifest("infra"))
157
- user_services.sort! {|a, b| a[:name] <=> b[:name] }
158
-
159
- unless user_services.empty?
160
- if ask "Bind existing services to '#{name}'?", :default => false
161
- bind_services(user_services)
162
- end
163
- end
164
-
165
- services = client.services_info
166
- unless services.empty?
167
- if ask "Create services to bind to '#{name}'?", :default => false
168
- create_services(services.values.collect(&:keys).flatten)
169
- end
170
- end
171
- end
172
-
173
- if many and ask("Configure for another application?", :default => false)
174
- @application = ask "Application path?"
175
- configure_app
176
- end
177
- end
178
-
179
- def set(what, *where)
180
- where.unshift "applications", @application
181
-
182
- which = @manifest
183
- where.each_with_index do |k, i|
184
- if i + 1 == where.size
185
- which[k] = what
186
- else
187
- which = (which[k] ||= {})
188
- end
189
- end
190
-
191
- what
192
- end
193
-
194
- # Detect the appropriate framework.
195
- def detect_framework(prompt_ok = true)
196
- framework = VMC::Cli::Framework.detect(@application, frameworks_info)
197
- framework_correct = ask("Detected a #{framework}, is this correct?", :default => true) if prompt_ok && framework
198
- if prompt_ok && (framework.nil? || !framework_correct)
199
- display "#{"[WARNING]".yellow} Can't determine the Application Type." unless framework
200
- framework = nil if !framework_correct
201
- framework = VMC::Cli::Framework.lookup(
202
- ask(
203
- "Select Application Type",
204
- :indexed => true,
205
- :default => framework,
206
- :choices => VMC::Cli::Framework.known_frameworks(frameworks_info)
207
- )
208
- )
209
- display "Selected #{framework}"
210
- end
211
-
212
- framework
213
- end
214
-
215
- # Detect the appropriate runtime.
216
- def detect_runtime(default, prompt_ok=true)
217
- runtime = nil
218
- runtime_keys=[]
219
- runtimes_info.keys.each {|runtime_key| runtime_keys << runtime_key.dup }
220
- runtime_keys.sort!
221
- if prompt_ok
222
- runtime = ask(
223
- "Select Runtime",
224
- :indexed => true,
225
- :default => default,
226
- :choices => runtime_keys
227
- )
228
- display "Selected #{runtime}"
229
- end
230
- runtime
231
- end
232
-
233
- def bind_services(user_services, chosen = 0)
234
- svcname = ask(
235
- "Which one?",
236
- :indexed => true,
237
- :choices => user_services.collect { |p| p[:name] })
238
-
239
- svc = user_services.find { |p| p[:name] == svcname }
240
-
241
- set svc[:vendor], "services", svcname, "type"
242
-
243
- if chosen + 1 < user_services.size && ask("Bind another?", :default => false)
244
- bind_services(user_services, chosen + 1)
245
- end
246
- end
247
-
248
- def create_services(services)
249
- svcs = services.collect(&:to_s).sort!
250
-
251
- configure_service(
252
- ask(
253
- "What kind of service?",
254
- :indexed => true,
255
- :choices => svcs
256
- )
257
- )
258
-
259
- if ask "Create another?", :default => false
260
- create_services(services)
261
- end
262
- end
263
-
264
- def configure_service(vendor)
265
- default_name = random_service_name(vendor)
266
- name = ask "Specify the name of the service", :default => default_name
267
-
268
- set vendor, "services", name, "type"
269
- end
270
-
271
- private
272
- def services_for_infra(infra)
273
- if client.infra_supported?
274
- client.services.select { |s| s[:infra] && s[:infra][:provider] == manifest("infra") }
275
- else
276
- client.services
277
- end
278
- end
279
-
280
- def ordered_by_deps(apps, abspaths = nil, processed = Set[])
281
- unless abspaths
282
- abspaths = {}
283
- apps.each do |p, i|
284
- ep = File.expand_path("../" + p, manifest_file)
285
- abspaths[ep] = i
286
- end
287
- end
288
-
289
- ordered = []
290
- apps.each do |path, info|
291
- epath = File.expand_path("../" + path, manifest_file)
292
-
293
- if deps = info["depends-on"]
294
- dep_apps = {}
295
- deps.each do |dep|
296
- edep = File.expand_path("../" + dep, manifest_file)
297
-
298
- err "Circular dependency detected." if processed.include? edep
299
-
300
- dep_apps[dep] = abspaths[edep]
301
- end
302
-
303
- processed.add(epath)
304
-
305
- ordered += ordered_by_deps(dep_apps, abspaths, processed)
306
- ordered << [path, info]
307
- elsif not processed.include? epath
308
- ordered << [path, info]
309
- processed.add(epath)
310
- end
311
- end
312
-
313
- ordered
314
- end
315
-
316
- end
@@ -1,633 +0,0 @@
1
-
2
- require 'optparse'
3
-
4
- require File.dirname(__FILE__) + '/usage'
5
-
6
- class VMC::Cli::Runner
7
-
8
- attr_reader :namespace
9
- attr_reader :action
10
- attr_reader :args
11
- attr_reader :options
12
-
13
- def self.run(args)
14
- new(args).run
15
- end
16
-
17
- def initialize(args=[])
18
- @args = args
19
- @options = { :colorize => true }
20
- @exit_status = true
21
- end
22
-
23
- # Collect all the available options for all commands
24
- # Some duplicates exists to capture all scenarios
25
- def parse_options!
26
- opts_parser = OptionParser.new do |opts|
27
- opts.banner = "\nAvailable options:\n\n"
28
-
29
- opts.on('--email EMAIL') { |email| @options[:email] = email }
30
- opts.on('--user EMAIL') { |email| @options[:email] = email }
31
- opts.on('--passwd PASS') { |pass| @options[:password] = pass }
32
- opts.on('--pass PASS') { |pass| @options[:password] = pass }
33
- opts.on('--password PASS') { |pass| @options[:password] = pass }
34
- opts.on('--token-file TOKEN_FILE') { |token_file| @options[:token_file] = token_file }
35
- opts.on('--app NAME') { |name| @options[:name] = name }
36
- opts.on('--name NAME') { |name| @options[:name] = name }
37
- opts.on('--bind BIND') { |bind| @options[:bind] = bind }
38
- opts.on('--instance INST') { |inst| @options[:instance] = inst }
39
- opts.on('--instances INST') { |inst| @options[:instances] = inst }
40
- opts.on('--url URL') { |url| @options[:url] = url }
41
- opts.on('--mem MEM') { |mem| @options[:mem] = mem }
42
- opts.on('--path PATH') { |path| @options[:path] = path }
43
- opts.on('--label LABEL') { |label| @options[:label] = label }
44
- opts.on('--no-start') { @options[:nostart] = true }
45
- opts.on('--nostart') { @options[:nostart] = true }
46
- opts.on('--force') { @options[:force] = true }
47
- opts.on('--all') { @options[:all] = true }
48
- opts.on('--full') { @options[:full] = true }
49
-
50
- # generic tracing and debugging
51
- opts.on('-t [TKEY]') { |tkey| @options[:trace] = tkey || true }
52
- opts.on('--trace [TKEY]') { |tkey| @options[:trace] = tkey || true }
53
- opts.on('--crash') { @options[:crash] = true }
54
-
55
- # start application in debug mode
56
- opts.on('-d [MODE]') { |mode| @options[:debug] = mode || "run" }
57
- opts.on('--debug [MODE]') { |mode| @options[:debug] = mode || "run" }
58
-
59
- # override manifest file
60
- opts.on('-m FILE') { |file| @options[:manifest] = file }
61
- opts.on('--manifest FILE') { |file| @options[:manifest] = file }
62
-
63
- opts.on('-q', '--quiet') { @options[:quiet] = true }
64
-
65
- # micro cloud options
66
- opts.on('--vmx FILE') { |file| @options[:vmx] = file }
67
- opts.on('--vmrun FILE') { |file| @options[:vmrun] = file }
68
- opts.on('--save') { @options[:save] = true }
69
-
70
- # Don't use builtin zip
71
- opts.on('--no-zip') { @options[:nozip] = true }
72
- opts.on('--nozip') { @options[:nozip] = true }
73
-
74
- opts.on('--no-resources') { @options[:noresources] = true }
75
- opts.on('--noresources') { @options[:noresources] = true }
76
-
77
- opts.on('--no-color') { @options[:colorize] = false }
78
- opts.on('--verbose') { @options[:verbose] = true }
79
-
80
- opts.on('-n','--no-prompt') { @options[:noprompts] = true }
81
- opts.on('--noprompt') { @options[:noprompts] = true }
82
- opts.on('--non-interactive') { @options[:noprompts] = true }
83
-
84
- opts.on('--prefix') { @options[:prefixlogs] = true }
85
- opts.on('--prefix-logs') { @options[:prefixlogs] = true }
86
- opts.on('--prefixlogs') { @options[:prefixlogs] = true }
87
-
88
- opts.on('--json') { @options[:json] = true }
89
-
90
- opts.on('-v', '--version') { set_cmd(:misc, :version) }
91
- opts.on('-h', '--help') { puts "#{command_usage}\n"; exit }
92
-
93
- opts.on('--port PORT') { |port| @options[:port] = port }
94
-
95
- opts.on('--runtime RUNTIME') { |rt| @options[:runtime] = rt }
96
-
97
- # deprecated
98
- opts.on('--exec EXEC') { |exec| @options[:exec] = exec }
99
- opts.on('--noframework') { @options[:noframework] = true }
100
- opts.on('--canary') { @options[:canary] = true }
101
-
102
- # Proxying for another user, requires admin privileges
103
- opts.on('-u PROXY') { |proxy| @options[:proxy] = proxy }
104
-
105
- # Select infrastructure
106
- opts.on('--infra INFRA') { |infra| @options[:infra] = infra }
107
-
108
- opts.on_tail('--options') { puts "#{opts}\n"; exit }
109
- end
110
- instances_delta_arg = check_instances_delta!
111
- @args = opts_parser.parse!(@args)
112
- @args.concat instances_delta_arg
113
- convert_options!
114
- self
115
- end
116
-
117
- def check_instances_delta!
118
- return unless @args
119
- instance_args = @args.select { |arg| /^[-]\d+$/ =~ arg } || []
120
- @args.delete_if { |arg| instance_args.include? arg}
121
- instance_args
122
- end
123
-
124
- def display_help
125
- puts command_usage
126
- exit
127
- end
128
-
129
- def convert_options!
130
- # make sure certain options are valid and in correct form.
131
- @options[:instances] = Integer(@options[:instances]) if @options[:instances]
132
- end
133
-
134
- def set_cmd(namespace, action, args_range=0)
135
- return if @help_only
136
- unless args_range == "*" || args_range.is_a?(Range)
137
- args_range = (args_range.to_i..args_range.to_i)
138
- end
139
-
140
- if args_range == "*" || args_range.include?(@args.size)
141
- @namespace = namespace
142
- @action = action
143
- else
144
- @exit_status = false
145
- if @args.size > args_range.last
146
- usage_error("Too many arguments for [#{action}]: %s" % [ @args[args_range.last..-1].map{|a| "'#{a}'"}.join(', ') ])
147
- else
148
- usage_error("Not enough arguments for [#{action}]")
149
- end
150
- end
151
- end
152
-
153
- def parse_command!
154
- # just return if already set, happends with -v, -h
155
- return if @namespace && @action
156
-
157
- verb = @args.shift
158
- case verb
159
-
160
- when 'version'
161
- usage('af version')
162
- set_cmd(:misc, :version)
163
-
164
- when 'target'
165
- usage('af target [url] [--url]')
166
- if @args.size == 1
167
- set_cmd(:misc, :set_target, 1)
168
- else
169
- set_cmd(:misc, :target)
170
- end
171
-
172
- when 'targets'
173
- usage('af targets')
174
- set_cmd(:misc, :targets)
175
-
176
- when 'tokens'
177
- usage('af tokens')
178
- set_cmd(:misc, :tokens)
179
-
180
- when 'info'
181
- usage('af info')
182
- set_cmd(:misc, :info)
183
-
184
- when 'runtimes'
185
- usage('af runtimes')
186
- set_cmd(:misc, :runtimes)
187
-
188
- when 'frameworks'
189
- usage('af frameworks')
190
- set_cmd(:misc, :frameworks)
191
-
192
- when 'infras'
193
- usage('af infras')
194
- set_cmd(:misc, :infras)
195
-
196
- when 'user'
197
- usage('af user')
198
- set_cmd(:user, :info)
199
-
200
- when 'login'
201
- usage('af login [email] [--email EMAIL] [--passwd PASS]')
202
- if @args.size == 1
203
- set_cmd(:user, :login, 1)
204
- else
205
- set_cmd(:user, :login)
206
- end
207
-
208
- when 'logout'
209
- usage('af logout')
210
- set_cmd(:user, :logout)
211
-
212
- when 'passwd'
213
- usage('af passwd')
214
- if @args.size == 1
215
- set_cmd(:user, :change_password, 1)
216
- else
217
- set_cmd(:user, :change_password)
218
- end
219
-
220
- when 'add-user', 'add_user', 'create_user', 'create-user', 'register'
221
- usage('af add-user [user] [--email EMAIL] [--passwd PASS]')
222
- if @args.size == 1
223
- set_cmd(:admin, :add_user, 1)
224
- else
225
- set_cmd(:admin, :add_user)
226
- end
227
-
228
- when 'delete-user', 'delete_user', 'unregister'
229
- usage('af delete-user <user>')
230
- set_cmd(:admin, :delete_user, 1)
231
-
232
- when 'users'
233
- usage('af users')
234
- set_cmd(:admin, :users)
235
-
236
- when 'apps'
237
- usage('af apps')
238
- set_cmd(:apps, :apps)
239
-
240
- when 'list'
241
- usage('af list')
242
- set_cmd(:apps, :list)
243
-
244
- when 'start'
245
- usage('af start <appname>')
246
- set_cmd(:apps, :start, @args.size == 1 ? 1 : 0)
247
-
248
- when 'stop'
249
- usage('af stop <appname>')
250
- set_cmd(:apps, :stop, @args.size == 1 ? 1 : 0)
251
-
252
- when 'restart'
253
- usage('af restart <appname>')
254
- set_cmd(:apps, :restart, @args.size == 1 ? 1 : 0)
255
-
256
- when 'mem'
257
- usage('af mem <appname> [memsize]')
258
- if @args.size == 2
259
- set_cmd(:apps, :mem, 2)
260
- else
261
- set_cmd(:apps, :mem, 1)
262
- end
263
-
264
- when 'stats'
265
- usage('af stats <appname>')
266
- set_cmd(:apps, :stats, @args.size == 1 ? 1 : 0)
267
-
268
- when 'map'
269
- usage('af map <appname> <url>')
270
- set_cmd(:apps, :map, 2)
271
-
272
- when 'unmap'
273
- usage('af unmap <appname> <url>')
274
- set_cmd(:apps, :unmap, 2)
275
-
276
- when 'delete'
277
- usage('af delete <appname>')
278
- if @options[:all] && @args.size == 0
279
- set_cmd(:apps, :delete)
280
- else
281
- set_cmd(:apps, :delete, 1)
282
- end
283
-
284
- when 'files'
285
- usage('af files <appname> [path] [--instance N] [--all] [--prefix]')
286
- if @args.size == 1
287
- set_cmd(:apps, :files, 1)
288
- else
289
- set_cmd(:apps, :files, 2)
290
- end
291
-
292
- when 'download'
293
- usage('af download <appname> [path]')
294
- if @args.size == 1
295
- set_cmd(:apps, :download, 1)
296
- else
297
- set_cmd(:apps, :download, 2)
298
- end
299
-
300
- when 'pull'
301
- usage('af pull <appname> [path]')
302
- if @args.size == 1
303
- set_cmd(:apps, :pull, 1)
304
- else
305
- set_cmd(:apps, :pull, 2)
306
- end
307
-
308
- when 'logs'
309
- usage('af logs <appname> [--instance N] [--all] [--prefix]')
310
- set_cmd(:apps, :logs, 1)
311
-
312
- when 'instances', 'scale'
313
- if @args.size > 1
314
- usage('af instances <appname> <num|delta>')
315
- set_cmd(:apps, :instances, 2)
316
- else
317
- usage('af instances <appname>')
318
- set_cmd(:apps, :instances, 1)
319
- end
320
-
321
- when 'crashes'
322
- usage('af crashes <appname>')
323
- set_cmd(:apps, :crashes, 1)
324
-
325
- when 'crashlogs'
326
- usage('af crashlogs <appname>')
327
- set_cmd(:apps, :crashlogs, 1)
328
-
329
- when 'push'
330
- usage('af push [appname] [--path PATH] [--url URL] [--instances N] [--mem] [--runtime RUNTIME] [--no-start] [--infra infraname] [--label LABEL]')
331
- if @args.size == 1
332
- set_cmd(:apps, :push, 1)
333
- else
334
- set_cmd(:apps, :push, 0)
335
- end
336
-
337
- when 'update'
338
- usage('af update <appname> [--path PATH] [--label LABEL]')
339
- set_cmd(:apps, :update, @args.size == 1 ? 1 : 0)
340
-
341
- when 'history'
342
- usage('af history <appname>')
343
- set_cmd(:apps, :history, 1)
344
-
345
- when 'hash'
346
- usage('hash [path] [--full]')
347
- if @args.size == 1
348
- set_cmd(:apps, :hash, 1)
349
- else
350
- set_cmd(:apps, :hash, 0)
351
- end
352
-
353
- when 'diff'
354
- usage('af diff <appname>')
355
- set_cmd(:apps, :diff, 1)
356
-
357
- when 'services'
358
- usage('af services')
359
- set_cmd(:services, :services)
360
-
361
- when 'env'
362
- usage('af env <appname>')
363
- set_cmd(:apps, :environment, 1)
364
-
365
- when 'env-add'
366
- usage('af env-add <appname> <variable[=]value>')
367
- if @args.size == 2
368
- set_cmd(:apps, :environment_add, 2)
369
- elsif @args.size == 3
370
- set_cmd(:apps, :environment_add, 3)
371
- end
372
-
373
- when 'env-del'
374
- usage('af env-del <appname> <variable>')
375
- set_cmd(:apps, :environment_del, 2)
376
-
377
- when 'rename'
378
- usage('af rename <curname> <newname>')
379
- set_cmd(:apps, :rename, 2)
380
-
381
- when 'create-service', 'create_service'
382
- usage('af create-service [service] [servicename] [appname] [--name servicename] [--bind appname] [--infra infraname]')
383
- set_cmd(:services, :create_service) if @args.size == 0
384
- set_cmd(:services, :create_service, 1) if @args.size == 1
385
- set_cmd(:services, :create_service, 2) if @args.size == 2
386
- set_cmd(:services, :create_service, 3) if @args.size == 3
387
-
388
- when 'delete-service', 'delete_service'
389
- usage('af delete-service <service>')
390
- if @args.size == 1
391
- set_cmd(:services, :delete_service, 1)
392
- else
393
- set_cmd(:services, :delete_service)
394
- end
395
-
396
- when 'bind-service', 'bind_service'
397
- usage('af bind-service <servicename> <appname>')
398
- set_cmd(:services, :bind_service, 2)
399
-
400
- when 'unbind-service', 'unbind_service'
401
- usage('af unbind-service <servicename> <appname>')
402
- set_cmd(:services, :unbind_service, 2)
403
-
404
- when 'clone-services'
405
- usage('af clone-services <src-app> <dest-app>')
406
- set_cmd(:services, :clone_services, 2)
407
-
408
- when 'export-service'
409
- usage('af export-service <service-name>')
410
- set_cmd(:services, :export_service, 1)
411
-
412
- when 'import-service'
413
- usage('af import-service <service-name> <url>')
414
- set_cmd(:services, :import_service, 2)
415
-
416
- when 'clone'
417
- usage('af clone <src-app> <dest-app> [<infra>] --label LABEL')
418
- set_cmd(:apps, :clone, 2) if @args.size == 2
419
- set_cmd(:apps, :clone, 3) if @args.size == 3
420
-
421
- when 'aliases'
422
- usage('af aliases')
423
- set_cmd(:misc, :aliases)
424
-
425
- when 'alias'
426
- usage('af alias <alias[=]command>')
427
- if @args.size == 1
428
- set_cmd(:misc, :alias, 1)
429
- elsif @args.size == 2
430
- set_cmd(:misc, :alias, 2)
431
- end
432
-
433
- when 'unalias'
434
- usage('af unalias <alias>')
435
- set_cmd(:misc, :unalias, 1)
436
-
437
- when 'tunnel'
438
- usage('af tunnel [servicename] [clientcmd] [--port port]')
439
- set_cmd(:services, :tunnel, 0) if @args.size == 0
440
- set_cmd(:services, :tunnel, 1) if @args.size == 1
441
- set_cmd(:services, :tunnel, 2) if @args.size == 2
442
-
443
- when 'rails-console'
444
- usage('af rails-console <appname>')
445
- set_cmd(:apps, :console, 1)
446
-
447
- when 'micro'
448
- usage('af micro <online|offline|status> [--password password] [--save] [--vmx file] [--vmrun executable]')
449
- if %w[online offline status].include?(@args[0])
450
- set_cmd(:micro, @args[0].to_sym, 1)
451
- end
452
-
453
- when 'help'
454
- display_help if @args.size == 0
455
- @help_only = true
456
- parse_command!
457
-
458
- when 'usage'
459
- display basic_usage
460
- exit(true)
461
-
462
- when 'options'
463
- # Simulate --options
464
- @args = @args.unshift('--options')
465
- parse_options!
466
-
467
- when 'manifest'
468
- usage('af manifest')
469
- set_cmd(:manifest, :edit)
470
-
471
- when 'extend-manifest'
472
- usage('af extend-manifest')
473
- set_cmd(:manifest, :extend, 1)
474
-
475
- else
476
- if verb
477
- display "af: Unknown command [#{verb}]"
478
- display basic_usage
479
- exit(false)
480
- end
481
- end
482
- end
483
-
484
- def process_aliases!
485
- return if @args.empty?
486
- aliases = VMC::Cli::Config.aliases
487
- aliases.each_pair do |k,v|
488
- if @args[0] == k
489
- display "[#{@args[0]} aliased to #{aliases.invert[key]}]" if @options[:verbose]
490
- @args[0] = v
491
- break;
492
- end
493
- end
494
- end
495
-
496
- def usage(msg = nil)
497
- @usage = msg if msg
498
- @usage
499
- end
500
-
501
- def usage_error(msg = nil)
502
- @usage_error = msg if msg
503
- @usage_error
504
- end
505
-
506
- def crash_log(e, message = nil)
507
- @finish_time = Time.now
508
- diff = @finish_time - @start_time
509
-
510
- if message != nil
511
- message = "#{message} (#{e.message})"
512
- else
513
- message = e.message
514
- end
515
-
516
- say message.red
517
-
518
- @options[:password] = "".rjust(@options[:password].length, '*') if @options[:password]
519
-
520
- log = ""
521
- log += "Action: #{@action}\n"
522
- log += "Arguments: #{@args.join(' ')}\n" if "#{@action}" != 'environment_add'
523
- log += "Options: #{@options.to_json}\n"
524
- log += "Execution Time: %.2fs\n" % diff
525
- log += "Target: #{VMC::Cli::Config.target_url}\n"
526
- log += "Client: v#{VMC::Cli::VERSION}\n"
527
- log += "Platform: #{RUBY_PLATFORM} - Ruby:#{RUBY_VERSION}-#{RUBY_PATCHLEVEL}\n"
528
- log += "Type: #{e.class}\n"
529
- log += "Message: #{e.message}\n"
530
- log += "Stack Trace:\n"
531
- e.backtrace.each do |trace|
532
- log += " #{trace}\n"
533
- end
534
-
535
- if @options[:crash] == true
536
- say "--- #{File.expand_path(VMC::Cli::Config::CRASH_FILE)} ---"
537
- say log
538
- end
539
-
540
- VMC::Cli::Config.store_crash(log)
541
- end
542
-
543
- def run
544
- @start_time = Time.now
545
-
546
- trap('TERM') { print "\nTerminated\n"; exit(false)}
547
-
548
- parse_options!
549
-
550
- @options[:colorize] = false unless STDOUT.tty?
551
-
552
- VMC::Cli::Config.colorize = @options.delete(:colorize)
553
- VMC::Cli::Config.nozip = @options.delete(:nozip)
554
- VMC::Cli::Config.trace = @options.delete(:trace)
555
- VMC::Cli::Config.output ||= STDOUT unless @options[:quiet]
556
- VMC::Cli::Config.infra = @options[:infra]
557
-
558
- process_aliases!
559
- parse_command!
560
-
561
- if @namespace && @action
562
- cmd = VMC::Cli::Command.const_get(@namespace.to_s.capitalize)
563
- cmd.new(@options).send(@action, *@args.collect(&:dup))
564
- elsif @help_only || @usage
565
- display_usage
566
- else
567
- display basic_usage
568
- exit(false)
569
- end
570
-
571
- rescue OptionParser::InvalidOption => e
572
- crash_log(e)
573
- puts("\n")
574
- puts(basic_usage)
575
- @exit_status = false
576
- rescue OptionParser::AmbiguousOption => e
577
- crash_log(e)
578
- puts("\n")
579
- puts(basic_usage)
580
- @exit_status = false
581
- rescue VMC::Cli::Command::User::InvalidLogin => e
582
- crash_log(e)
583
- @exit_status = false
584
- rescue VMC::Client::BadTarget => e
585
- crash_log(e, "Problem with login to '#{VMC::Cli::Config.target_url}', try again or register for an account.")
586
- @exit_status = false
587
- rescue VMC::Client::AuthError => e
588
- if VMC::Cli::Config.auth_token.nil?
589
- puts "Login Required".red
590
- else
591
- puts "Not Authorized".red
592
- end
593
- @exit_status = false
594
- rescue VMC::Client::TargetError, VMC::Client::NotFound, VMC::Client::BadTarget => e
595
- crash_log(e)
596
- @exit_status = false
597
- rescue VMC::Client::HTTPException => e
598
- crash_log(e, "There was a problem connecting to the target. Please try again in a few moments.")
599
- @exit_status = false
600
- rescue VMC::Cli::GracefulExit => e
601
- # Redirected commands end up generating this exception (kind of goto)
602
- rescue VMC::Cli::CliExit => e
603
- crash_log(e)
604
- @exit_status = false
605
- rescue VMC::Cli::CliError => e
606
- crash_log(e, "Error #{e.error_code}: #{e.message}")
607
- @exit_status = false
608
- rescue SystemExit => e
609
- @exit_status = e.success?
610
- rescue SyntaxError => e
611
- crash_log(e)
612
- @exit_status = false
613
- rescue Interrupt => e
614
- crash_log(e, "Interrupted")
615
- @exit_status = false
616
- rescue Exception => e
617
- crash_log(e)
618
- @exit_status = false
619
- ensure
620
- say("\n")
621
- @exit_status == true if @exit_status.nil?
622
- if @options[:verbose]
623
- if @exit_status
624
- puts "[#{@namespace}:#{@action}] SUCCEEDED".green
625
- else
626
- puts "[#{@namespace}:#{@action}] FAILED".red
627
- end
628
- say("\n")
629
- end
630
- exit(@exit_status)
631
- end
632
-
633
- end