vmc 0.0.8 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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"