vmc 0.0.8 → 0.2.4

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 (63) hide show
  1. data/LICENSE +8 -3
  2. data/README.md +83 -0
  3. data/Rakefile +11 -65
  4. data/bin/vmc +3 -2
  5. data/lib/cli/commands/admin.rb +57 -0
  6. data/lib/cli/commands/apps.rb +828 -0
  7. data/lib/cli/commands/base.rb +56 -0
  8. data/lib/cli/commands/misc.rb +99 -0
  9. data/lib/cli/commands/services.rb +84 -0
  10. data/lib/cli/commands/user.rb +60 -0
  11. data/lib/cli/config.rb +109 -0
  12. data/lib/cli/core_ext.rb +119 -0
  13. data/lib/cli/errors.rb +19 -0
  14. data/lib/cli/frameworks.rb +97 -0
  15. data/lib/cli/runner.rb +437 -0
  16. data/lib/cli/services_helper.rb +74 -0
  17. data/lib/cli/usage.rb +94 -0
  18. data/lib/cli/version.rb +5 -0
  19. data/lib/cli/zip_util.rb +61 -0
  20. data/lib/cli.rb +30 -0
  21. data/lib/vmc/client.rb +415 -0
  22. data/lib/vmc/const.rb +19 -0
  23. data/lib/vmc.rb +2 -1589
  24. data/spec/assets/app_info.txt +9 -0
  25. data/spec/assets/app_listings.txt +9 -0
  26. data/spec/assets/bad_create_app.txt +9 -0
  27. data/spec/assets/delete_app.txt +9 -0
  28. data/spec/assets/global_service_listings.txt +9 -0
  29. data/spec/assets/good_create_app.txt +9 -0
  30. data/spec/assets/good_create_service.txt +9 -0
  31. data/spec/assets/info_authenticated.txt +27 -0
  32. data/spec/assets/info_return.txt +15 -0
  33. data/spec/assets/info_return_bad.txt +16 -0
  34. data/spec/assets/login_fail.txt +9 -0
  35. data/spec/assets/login_success.txt +9 -0
  36. data/spec/assets/sample_token.txt +1 -0
  37. data/spec/assets/service_already_exists.txt +9 -0
  38. data/spec/assets/service_listings.txt +9 -0
  39. data/spec/assets/service_not_found.txt +9 -0
  40. data/spec/assets/user_info.txt +9 -0
  41. data/spec/spec_helper.rb +11 -0
  42. data/spec/unit/cli_opts_spec.rb +73 -0
  43. data/spec/unit/client_spec.rb +284 -0
  44. metadata +114 -71
  45. data/README +0 -58
  46. data/lib/parse.rb +0 -719
  47. data/lib/vmc_base.rb +0 -205
  48. data/vendor/gems/httpclient/VERSION +0 -1
  49. data/vendor/gems/httpclient/lib/http-access2/cookie.rb +0 -1
  50. data/vendor/gems/httpclient/lib/http-access2/http.rb +0 -1
  51. data/vendor/gems/httpclient/lib/http-access2.rb +0 -53
  52. data/vendor/gems/httpclient/lib/httpclient/auth.rb +0 -522
  53. data/vendor/gems/httpclient/lib/httpclient/cacert.p7s +0 -1579
  54. data/vendor/gems/httpclient/lib/httpclient/cacert_sha1.p7s +0 -1579
  55. data/vendor/gems/httpclient/lib/httpclient/connection.rb +0 -84
  56. data/vendor/gems/httpclient/lib/httpclient/cookie.rb +0 -562
  57. data/vendor/gems/httpclient/lib/httpclient/http.rb +0 -867
  58. data/vendor/gems/httpclient/lib/httpclient/session.rb +0 -864
  59. data/vendor/gems/httpclient/lib/httpclient/ssl_config.rb +0 -417
  60. data/vendor/gems/httpclient/lib/httpclient/timeout.rb +0 -136
  61. data/vendor/gems/httpclient/lib/httpclient/util.rb +0 -86
  62. data/vendor/gems/httpclient/lib/httpclient.rb +0 -1020
  63. data/vendor/gems/httpclient/lib/tags +0 -908
data/lib/cli/runner.rb ADDED
@@ -0,0 +1,437 @@
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('--app NAME') { |name| @options[:name] = name }
35
+ opts.on('--name NAME') { |name| @options[:name] = name }
36
+ opts.on('--bind BIND') { |bind| @options[:bind] = bind }
37
+ opts.on('--instance INST') { |inst| @options[:instance] = inst }
38
+ opts.on('--instances INST') { |inst| @options[:instances] = inst }
39
+ opts.on('--url URL') { |url| @options[:url] = url }
40
+ opts.on('--mem MEM') { |mem| @options[:mem] = mem }
41
+ opts.on('--path PATH') { |path| @options[:path] = path }
42
+ opts.on('--no-start') { @options[:nostart] = true }
43
+ opts.on('--nostart') { @options[:nostart] = true }
44
+ opts.on('--force') { @options[:force] = true }
45
+ opts.on('--all') { @options[:all] = true }
46
+
47
+ # generic tracing and debugging
48
+ opts.on('-t', '--trace') { @options[:trace] = true }
49
+ opts.on('-q', '--quiet') { @options[:quiet] = true }
50
+
51
+ # Don't use builtin zip
52
+ opts.on('--no-zip') { @options[:nozip] = true }
53
+ opts.on('--nozip') { @options[:nozip] = true }
54
+
55
+ opts.on('--no-resources') { @options[:noresources] = true }
56
+ opts.on('--noresources') { @options[:noresources] = true }
57
+
58
+ opts.on('--no-color') { @options[:colorize] = false }
59
+ opts.on('--verbose') { @options[:verbose] = true }
60
+
61
+ opts.on('-n','--no-prompt') { @options[:noprompts] = true }
62
+ opts.on('--noprompt') { @options[:noprompts] = true }
63
+ opts.on('--non-interactive') { @options[:noprompts] = true }
64
+
65
+ opts.on('--prefix') { @options[:prefixlogs] = true }
66
+ opts.on('--prefix-logs') { @options[:prefixlogs] = true }
67
+ opts.on('--prefixlogs') { @options[:prefixlogs] = true }
68
+
69
+ opts.on('--json') { @options[:json] = true }
70
+
71
+ opts.on('-v', '--version') { set_cmd(:misc, :version) }
72
+ opts.on('-h', '--help') { puts "#{command_usage}\n"; exit }
73
+
74
+ # deprecated
75
+ opts.on('--exec EXEC') { |exec| @options[:exec] = exec }
76
+ opts.on('--noframework') { @options[:noframework] = true }
77
+ opts.on('--canary') { @options[:canary] = true }
78
+
79
+ # Proxying for another user, requires admin privileges
80
+ opts.on('-u PROXY') { |proxy| @options[:proxy] = proxy }
81
+
82
+ opts.on_tail('--options') { puts "#{opts}\n"; exit }
83
+ end
84
+ @args = opts_parser.parse!(@args)
85
+ convert_options!
86
+ self
87
+ end
88
+
89
+ def display_help
90
+ puts command_usage
91
+ exit
92
+ end
93
+
94
+ def convert_options!
95
+ # make sure certain options are valid and in correct form.
96
+ @options[:instances] = Integer(@options[:instances]) if @options[:instances]
97
+ @options[:instance] = Integer(@options[:instance]) if @options[:instance]
98
+ end
99
+
100
+ def set_cmd(namespace, action, args_range=0)
101
+ return if @help_only
102
+ unless args_range == "*" || args_range.is_a?(Range)
103
+ args_range = (args_range.to_i..args_range.to_i)
104
+ end
105
+
106
+ if args_range == "*" || args_range.include?(@args.size)
107
+ @namespace = namespace
108
+ @action = action
109
+ else
110
+ @exit_status = false
111
+ if @args.size > args_range.last
112
+ usage_error("Too many arguments for [#{action}]: %s" % [ @args[args_range.last..-1].map{|a| "'#{a}'"}.join(', ') ])
113
+ else
114
+ usage_error("Not enough arguments for [#{action}]")
115
+ end
116
+ end
117
+ end
118
+
119
+ def parse_command!
120
+ # just return if already set, happends with -v, -h
121
+ return if @namespace && @action
122
+
123
+ verb = @args.shift
124
+ case verb
125
+
126
+ when 'version'
127
+ usage('vmc version')
128
+ set_cmd(:misc, :version)
129
+
130
+ when 'target'
131
+ usage('vmc target [url] [--url]')
132
+ if @args.size == 1
133
+ set_cmd(:misc, :set_target, 1)
134
+ else
135
+ set_cmd(:misc, :target)
136
+ end
137
+
138
+ when 'targets'
139
+ usage('vmc targets')
140
+ set_cmd(:misc, :targets)
141
+
142
+ when 'tokens'
143
+ usage('vmc tokens')
144
+ set_cmd(:misc, :tokens)
145
+
146
+ when 'info'
147
+ usage('vmc info')
148
+ set_cmd(:misc, :info)
149
+
150
+ when 'user'
151
+ usage('vmc user')
152
+ set_cmd(:user, :info)
153
+
154
+ when 'login'
155
+ usage('vmc login [email] [--email EMAIL] [--passwd PASS]')
156
+ if @args.size == 1
157
+ set_cmd(:user, :login, 1)
158
+ else
159
+ set_cmd(:user, :login)
160
+ end
161
+
162
+ when 'logout'
163
+ usage('vmc logout')
164
+ set_cmd(:user, :logout)
165
+
166
+ when 'passwd'
167
+ usage('vmc passwd')
168
+ if @args.size == 1
169
+ set_cmd(:user, :change_password, 1)
170
+ else
171
+ set_cmd(:user, :change_password)
172
+ end
173
+
174
+ when 'add-user', 'add_user', 'create_user', 'create-user', 'register'
175
+ usage('vmc add-user [user] [--email EMAIL] [--passwd PASS]')
176
+ if @args.size == 1
177
+ set_cmd(:admin, :add_user, 1)
178
+ else
179
+ set_cmd(:admin, :add_user)
180
+ end
181
+
182
+ when 'delete-user', 'delete_user', 'unregister'
183
+ usage('vmc delete-user <user>')
184
+ set_cmd(:admin, :delete_user, 1)
185
+
186
+ when 'apps'
187
+ usage('vmc apps')
188
+ set_cmd(:apps, :apps)
189
+
190
+ when 'list'
191
+ usage('vmc list')
192
+ set_cmd(:apps, :list)
193
+
194
+ when 'start'
195
+ usage('vmc start <appname>')
196
+ set_cmd(:apps, :start, 1)
197
+
198
+ when 'stop'
199
+ usage('vmc stop <appname>')
200
+ set_cmd(:apps, :stop, 1)
201
+
202
+ when 'restart'
203
+ usage('vmc restart <appname>')
204
+ set_cmd(:apps, :restart, 1)
205
+
206
+ when 'rename'
207
+ usage('vmc rename <appname> <newname>')
208
+ set_cmd(:apps, :rename, 2)
209
+
210
+ when 'mem'
211
+ usage('vmc mem <appname> [memsize]')
212
+ if @args.size == 2
213
+ set_cmd(:apps, :mem, 2)
214
+ else
215
+ set_cmd(:apps, :mem, 1)
216
+ end
217
+
218
+ when 'stats'
219
+ usage('vmc stats <appname>')
220
+ set_cmd(:apps, :stats, 1)
221
+
222
+ when 'map'
223
+ usage('vmc map <appname> <url>')
224
+ set_cmd(:apps, :map, 2)
225
+
226
+ when 'unmap'
227
+ usage('vmc unmap <appname> <url>')
228
+ set_cmd(:apps, :unmap, 2)
229
+
230
+ when 'delete'
231
+ usage('vmc delete <appname>')
232
+ if @options[:all] && @args.size == 0
233
+ set_cmd(:apps, :delete)
234
+ else
235
+ set_cmd(:apps, :delete, 1)
236
+ end
237
+
238
+ when 'files'
239
+ usage('vmc files <appname> [path] [--instance N] [--all] [--prefix]')
240
+ if @args.size == 1
241
+ set_cmd(:apps, :files, 1)
242
+ else
243
+ set_cmd(:apps, :files, 2)
244
+ end
245
+
246
+ when 'logs'
247
+ usage('vmc logs <appname> [--instance N] [--all] [--prefix]')
248
+ set_cmd(:apps, :logs, 1)
249
+
250
+ when 'instances', 'scale'
251
+ if @args.size == 1
252
+ usage('vmc instances <appname>')
253
+ set_cmd(:apps, :instances, 1)
254
+ else
255
+ usage('vmc instances <appname> <num|delta>')
256
+ set_cmd(:apps, :instances, 2)
257
+ end
258
+
259
+ when 'crashes'
260
+ usage('vmc crashes <appname>')
261
+ set_cmd(:apps, :crashes, 1)
262
+
263
+ when 'crashlogs'
264
+ usage('vmc crashlogs <appname>')
265
+ set_cmd(:apps, :crashlogs, 1)
266
+
267
+ when 'push'
268
+ usage('vmc push [appname] [--path PATH] [--url URL] [--instances N] [--mem] [--no-start]')
269
+ if @args.size == 1
270
+ set_cmd(:apps, :push, 1)
271
+ else
272
+ set_cmd(:apps, :push, 0)
273
+ end
274
+
275
+ when 'update'
276
+ usage('vmc update <appname> [--path PATH]')
277
+ set_cmd(:apps, :update, 1)
278
+
279
+ when 'services'
280
+ usage('vmc services')
281
+ set_cmd(:services, :services)
282
+
283
+ when 'create-service', 'create_service'
284
+ usage('vmc create-service [service] [servicename] [appname] [--name servicename] [--bind appname]')
285
+ set_cmd(:services, :create_service) if @args.size == 0
286
+ set_cmd(:services, :create_service, 1) if @args.size == 1
287
+ set_cmd(:services, :create_service, 2) if @args.size == 2
288
+ set_cmd(:services, :create_service, 3) if @args.size == 3
289
+
290
+ when 'delete-service', 'delete_service'
291
+ usage('vmc delete-service <service>')
292
+ if @args.size == 1
293
+ set_cmd(:services, :delete_service, 1)
294
+ else
295
+ set_cmd(:services, :delete_service)
296
+ end
297
+
298
+ when 'bind-service', 'bind_service'
299
+ usage('vmc bind-service <servicename> <appname>')
300
+ set_cmd(:services, :bind_service, 2)
301
+
302
+ when 'unbind-service', 'unbind_service'
303
+ usage('vmc unbind-service <servicename> <appname>')
304
+ set_cmd(:services, :unbind_service, 2)
305
+
306
+ when 'clone-services'
307
+ usage('vmc clone-services <src-app> <dest-app>')
308
+ set_cmd(:services, :clone_services, 2)
309
+
310
+ when 'aliases'
311
+ usage('vmc aliases')
312
+ set_cmd(:misc, :aliases)
313
+
314
+ when 'alias'
315
+ usage('vmc alias <alias[=]command>')
316
+ if @args.size == 1
317
+ set_cmd(:misc, :alias, 1)
318
+ elsif @args.size == 2
319
+ set_cmd(:misc, :alias, 2)
320
+ end
321
+
322
+ when 'unalias'
323
+ usage('vmc unalias <alias>')
324
+ set_cmd(:misc, :unalias, 1)
325
+
326
+ when 'help'
327
+ display_help if @args.size == 0
328
+ @help_only = true
329
+ parse_command!
330
+
331
+ when 'usage'
332
+ display basic_usage
333
+ exit(true)
334
+
335
+ when 'options'
336
+ # Simulate --options
337
+ @args = @args.unshift('--options')
338
+ parse_options!
339
+
340
+ else
341
+ if verb
342
+ display "vmc: Unknown command [#{verb}]"
343
+ display basic_usage
344
+ exit(false)
345
+ end
346
+ end
347
+ end
348
+
349
+ def process_aliases!
350
+ return if @args.empty?
351
+ aliases = VMC::Cli::Config.aliases
352
+ if key = aliases.values.grep(@args[0]).first
353
+ display "[#{@args[0]} aliased to #{aliases.invert[key]}]" if @options[:verbose]
354
+ @args[0] = aliases.invert[key]
355
+ end
356
+ end
357
+
358
+ def usage(msg = nil)
359
+ @usage = msg if msg
360
+ @usage
361
+ end
362
+
363
+ def usage_error(msg = nil)
364
+ @usage_error = msg if msg
365
+ @usage_error
366
+ end
367
+
368
+ def run
369
+ trap('TERM') { print "\nInterupted\n"; exit(false)}
370
+ trap("INT") { print "\nInterupted\n"; exit(false)}
371
+
372
+ parse_options!
373
+
374
+ @options[:colorize] = false unless STDOUT.tty?
375
+
376
+ VMC::Cli::Config.colorize = @options.delete(:colorize)
377
+ VMC::Cli::Config.trace = @options.delete(:trace)
378
+ VMC::Cli::Config.nozip = @options.delete(:nozip)
379
+ VMC::Cli::Config.output ||= STDOUT unless @options[:quiet]
380
+
381
+ process_aliases!
382
+ parse_command!
383
+
384
+ if @namespace && @action
385
+ eval("VMC::Cli::Command::#{@namespace.to_s.capitalize}").new(@options).send(@action.to_sym, *@args)
386
+ elsif @help_only || @usage
387
+ display_usage
388
+ else
389
+ display basic_usage
390
+ exit(false)
391
+ end
392
+
393
+ rescue OptionParser::InvalidOption => e
394
+ rescue OptionParser::AmbiguousOption => e
395
+ puts(e.message.red)
396
+ puts("\n")
397
+ puts(basic_usage)
398
+ @exit_status = false
399
+ rescue VMC::Client::AuthError => e
400
+ if VMC::Cli::Config.auth_token.nil?
401
+ puts "Login Required".red
402
+ else
403
+ puts "Not Authorized".red
404
+ end
405
+ @exit_status = false
406
+ rescue VMC::Client::TargetError, VMC::Client::NotFound, VMC::Client::BadTarget => e
407
+ puts e.message.red
408
+ @exit_status = false
409
+ rescue VMC::Cli::GracefulExit => e
410
+ # Redirected commands end up generating this exception (kind of goto)
411
+ rescue VMC::Cli::CliExit => e
412
+ puts e.message.red
413
+ @exit_status = false
414
+ rescue VMC::Cli::CliError => e
415
+ say("Error #{e.error_code}: #{e.message}".red)
416
+ @exit_status = false
417
+ rescue SystemExit => e
418
+ @exit_status = e.success?
419
+ rescue => e
420
+ puts e.message.red
421
+ puts e.backtrace
422
+ @exit_status = false
423
+ ensure
424
+ say("\n")
425
+ @exit_status == true if @exit_status.nil?
426
+ if @options[:verbose]
427
+ if @exit_status
428
+ puts "[#{@namespace}:#{@action}] SUCCEEDED".green
429
+ else
430
+ puts "[#{@namespace}:#{@action}] FAILED".red
431
+ end
432
+ say("\n")
433
+ end
434
+ exit(@exit_status)
435
+ end
436
+
437
+ end
@@ -0,0 +1,74 @@
1
+
2
+ module VMC::Cli
3
+ module ServicesHelper
4
+ def display_system_services(services=nil)
5
+ services ||= client.services_info
6
+
7
+ display "\n============== System Services ==============\n\n"
8
+
9
+ return display "No system services available" if services.empty?
10
+
11
+ services_table = table do |t|
12
+ t.headings = 'Service', 'Version', 'Description'
13
+ services.each do |service_type, value|
14
+ value.each do |vendor, version|
15
+ version.each do |version_str, service|
16
+ t << [ vendor, version_str, service[:description] ]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ display services_table
22
+ end
23
+
24
+ def display_provisioned_services(services=nil)
25
+ services ||= client.services
26
+ display "\n=========== Provisioned Services ============\n\n"
27
+ display_provisioned_services_table(services)
28
+ end
29
+
30
+ def display_provisioned_services_table(services)
31
+ return unless services && !services.empty?
32
+ services_table = table do |t|
33
+ t.headings = 'Name', 'Service'
34
+ services.each do |service|
35
+ t << [ service[:name], service[:vendor] ]
36
+ end
37
+ end
38
+ display services_table
39
+ end
40
+
41
+ def create_service_banner(service, name, display_name=false)
42
+ sn = " [#{name}]" if display_name
43
+ display "Creating Service#{sn}: ", false
44
+ client.create_service(service, name)
45
+ display 'OK'.green
46
+ end
47
+
48
+ def bind_service_banner(service, appname, check_restart=true)
49
+ display "Binding Service: ", false
50
+ client.bind_service(service, appname)
51
+ display 'OK'.green
52
+ check_app_for_restart(appname) if check_restart
53
+ end
54
+
55
+ def unbind_service_banner(service, appname, check_restart=true)
56
+ display "Unbinding Service: ", false
57
+ client.unbind_service(service, appname)
58
+ display 'OK'.green
59
+ check_app_for_restart(appname) if check_restart
60
+ end
61
+
62
+ def random_service_name(service)
63
+ r = "%04x" % [rand(0x0100000)]
64
+ "#{service.to_s}-#{r}"
65
+ end
66
+
67
+ def check_app_for_restart(appname)
68
+ app = client.app_info(appname)
69
+ cmd = VMC::Cli::Command::Apps.new(@options)
70
+ cmd.restart(appname) if app[:state] == 'STARTED'
71
+ end
72
+
73
+ end
74
+ end
data/lib/cli/usage.rb ADDED
@@ -0,0 +1,94 @@
1
+ class VMC::Cli::Runner
2
+
3
+ def basic_usage
4
+ "Usage: vmc [options] command [<args>] [command_options]\n" +
5
+ "Try 'vmc help [command]' or 'vmc help options' for more information."
6
+ end
7
+
8
+ def display_usage
9
+ if @usage
10
+ say @usage_error if @usage_error
11
+ say "Usage: #{@usage}"
12
+ return
13
+ elsif @verb_usage
14
+ say @verb_usage
15
+ return
16
+ end
17
+ say command_usage
18
+ end
19
+
20
+ def command_usage
21
+ <<-USAGE
22
+
23
+ #{basic_usage}
24
+
25
+ Currently available vmc commands are:
26
+
27
+ Getting Started
28
+ target [url] Reports current target or sets a new target
29
+ login [email] [--email, --passwd] Login
30
+ info System and account information
31
+
32
+ Applications
33
+ apps List deployed applications
34
+
35
+ Application Creation
36
+ push [appname] Create, push, map, and start a new application
37
+ push [appname] --path Push application from specified path
38
+ push [appname] --url Set the url for the application
39
+ push [appname] --instances <N> Set the expected number <N> of instances
40
+ push [appname] --mem M Set the memory reservation for the application
41
+ push [appname] --no-start Do not auto-start the application
42
+
43
+ Application Operations
44
+ start <appname> Start the application
45
+ stop <appname> Stop the application
46
+ restart <appname> Restart the application
47
+ delete <appname> Delete the application
48
+ rename <appname> <newname> Rename the application
49
+
50
+ Application Updates
51
+ update <appname> [--path] Update the application bits
52
+ mem <appname> [memsize] Update the memory reservation for an application
53
+ map <appname> <url> Register the application to the url
54
+ unmap <appname> <url> Unregister the application from the url
55
+ instances <appname> <num|delta> Scale the application instances up or down
56
+
57
+ Application Information
58
+ crashes <appname> List recent application crashes
59
+ crashlogs <appname> Display log information for crashed applications
60
+ logs <appname> [--all] Display log information for the application
61
+ files <appname> [path] [--all] Display directory listing or file download for [path]
62
+ stats <appname> Display resource usage for the application
63
+ instances <appname> List application instances
64
+
65
+ Services
66
+ services Lists of services available and provisioned
67
+ create-service <service> [--name,--bind] Create a provisioned service
68
+ create-service <service> <name> Create a provisioned service and assign it <name>
69
+ create-service <service> <name> <app> Create a provisioned service and assign it <name>, and bind to <app>
70
+ delete-service [servicename] Delete a provisioned service
71
+ bind-service <servicename> <appname> Bind a service to an application
72
+ unbind-service <servicename> <appname> Unbind service from the application
73
+ clone-services <src-app> <dest-app> Clone service bindings from <src-app> application to <dest-app>
74
+
75
+ Administration
76
+ user Display user account information
77
+ passwd Change the password for the current user
78
+ logout Logs current user out of the target system
79
+ add-user [--email, --passwd] Register a new user (requires admin privileges)
80
+ delete-user <user> Delete a user and all apps and services (requires admin privileges)
81
+
82
+ Misc
83
+ aliases List aliases
84
+ alias <alias[=]command> Create an alias for a command
85
+ unalias <alias> Remove an alias
86
+ targets List known targets and associated authorization tokens
87
+
88
+ Help
89
+ help [command] Get general help or help on a specific command
90
+ help options Get help on available options
91
+ USAGE
92
+
93
+ end
94
+ end
@@ -0,0 +1,5 @@
1
+ module VMC
2
+ module Cli
3
+ VERSION = '0.2.4'
4
+ end
5
+ end
@@ -0,0 +1,61 @@
1
+
2
+ require 'zip/zipfilesystem'
3
+
4
+ module VMC::Cli
5
+
6
+ class ZipUtil
7
+
8
+ class << self
9
+ def entry_lines(file)
10
+ contents = nil
11
+ unless VMC::Cli::Config.nozip
12
+ contents = `unzip -l #{file} 2> /dev/null`
13
+ contents = nil if $? != 0
14
+ end
15
+ # Do Ruby version if told to or native version failed
16
+ unless contents
17
+ entries = []
18
+ Zip::ZipFile.foreach(file) { |zentry| entries << zentry }
19
+ contents = entries.join("\n")
20
+ end
21
+ contents
22
+ end
23
+
24
+ def unpack(file, dest)
25
+ unless VMC::Cli::Config.nozip
26
+ FileUtils.mkdir(dest)
27
+ `unzip -q #{file} -d #{dest} 2> /dev/null`
28
+ return unless $? != 0
29
+ end
30
+ # Do Ruby version if told to or native version failed
31
+ Zip::ZipFile.foreach(file) do |zentry|
32
+ epath = "#{dest}/#{zentry}"
33
+ dirname = File.dirname(epath)
34
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
35
+ zentry.extract(epath) unless File.exists?(epath)
36
+ end
37
+ end
38
+
39
+ def pack(dir, zipfile)
40
+ exclude = ['..', '.', '*~', '#*#', '*.log']
41
+ unless VMC::Cli::Config.nozip
42
+ excludes = exclude.map { |e| "\\#{e}" }
43
+ excludes = excludes.join(' ')
44
+ Dir.chdir(dir) do
45
+ `zip -q -r -x #{excludes} #{zipfile} . 2> /dev/null`
46
+ return unless $? != 0
47
+ end
48
+ end
49
+ # Do Ruby version if told to or native version failed
50
+ Zip::ZipFile::open(zipfile, true) do |zf|
51
+ Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).each do |f|
52
+ process = true
53
+ exclude.each { |e| process = false if File.fnmatch(e, File.basename(f)) }
54
+ zf.add(f.sub("#{dir}/",''), f) if (process && File.exists?(f))
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,30 @@
1
+
2
+ ROOT = File.expand_path(File.dirname(__FILE__))
3
+
4
+ module VMC
5
+
6
+ autoload :Client, "#{ROOT}/vmc/client"
7
+
8
+ module Cli
9
+
10
+ autoload :Config, "#{ROOT}/cli/config"
11
+ autoload :Framework, "#{ROOT}/cli/frameworks"
12
+ autoload :Runner, "#{ROOT}/cli/runner"
13
+ autoload :ZipUtil, "#{ROOT}/cli/zip_util"
14
+ autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
15
+
16
+ module Command
17
+ autoload :Base, "#{ROOT}/cli/commands/base"
18
+ autoload :Admin, "#{ROOT}/cli/commands/admin"
19
+ autoload :Apps, "#{ROOT}/cli/commands/apps"
20
+ autoload :Misc, "#{ROOT}/cli/commands/misc"
21
+ autoload :Services, "#{ROOT}/cli/commands/services"
22
+ autoload :User, "#{ROOT}/cli/commands/user"
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ require "#{ROOT}/cli/version"
29
+ require "#{ROOT}/cli/core_ext"
30
+ require "#{ROOT}/cli/errors"