af 0.3.22 → 0.5.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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