olympe 0.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.
- data/LICENSE +24 -0
- data/README.md +103 -0
- data/Rakefile +101 -0
- data/bin/olympe +6 -0
- data/caldecott_helper/Gemfile +10 -0
- data/caldecott_helper/Gemfile.lock +48 -0
- data/caldecott_helper/server.rb +43 -0
- data/config/clients.yml +17 -0
- data/config/micro/offline.conf +2 -0
- data/config/micro/paths.yml +22 -0
- data/config/micro/refresh_ip.rb +20 -0
- data/lib/cli/commands/admin.rb +80 -0
- data/lib/cli/commands/apps.rb +1208 -0
- data/lib/cli/commands/base.rb +233 -0
- data/lib/cli/commands/manifest.rb +56 -0
- data/lib/cli/commands/micro.rb +115 -0
- data/lib/cli/commands/misc.rb +140 -0
- data/lib/cli/commands/services.rb +217 -0
- data/lib/cli/commands/user.rb +65 -0
- data/lib/cli/config.rb +170 -0
- data/lib/cli/console_helper.rb +163 -0
- data/lib/cli/core_ext.rb +122 -0
- data/lib/cli/errors.rb +19 -0
- data/lib/cli/file_helper.rb +123 -0
- data/lib/cli/frameworks.rb +265 -0
- data/lib/cli/manifest_helper.rb +316 -0
- data/lib/cli/runner.rb +568 -0
- data/lib/cli/services_helper.rb +104 -0
- data/lib/cli/tunnel_helper.rb +336 -0
- data/lib/cli/usage.rb +125 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/zip_util.rb +77 -0
- data/lib/cli.rb +48 -0
- data/lib/vmc/client.rb +558 -0
- data/lib/vmc/const.rb +27 -0
- data/lib/vmc/micro/switcher/base.rb +97 -0
- data/lib/vmc/micro/switcher/darwin.rb +19 -0
- data/lib/vmc/micro/switcher/dummy.rb +15 -0
- data/lib/vmc/micro/switcher/linux.rb +16 -0
- data/lib/vmc/micro/switcher/windows.rb +31 -0
- data/lib/vmc/micro/vmrun.rb +158 -0
- data/lib/vmc/micro.rb +56 -0
- data/lib/vmc.rb +3 -0
- metadata +279 -0
data/lib/cli/runner.rb
ADDED
@@ -0,0 +1,568 @@
|
|
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('--no-start') { @options[:nostart] = true }
|
44
|
+
opts.on('--nostart') { @options[:nostart] = true }
|
45
|
+
opts.on('--force') { @options[:force] = true }
|
46
|
+
opts.on('--all') { @options[:all] = true }
|
47
|
+
|
48
|
+
# generic tracing and debugging
|
49
|
+
opts.on('-t [TKEY]') { |tkey| @options[:trace] = tkey || true }
|
50
|
+
opts.on('--trace [TKEY]') { |tkey| @options[:trace] = tkey || true }
|
51
|
+
|
52
|
+
# start application in debug mode
|
53
|
+
opts.on('-d [MODE]') { |mode| @options[:debug] = mode || "run" }
|
54
|
+
opts.on('--debug [MODE]') { |mode| @options[:debug] = mode || "run" }
|
55
|
+
|
56
|
+
# override manifest file
|
57
|
+
opts.on('-m FILE') { |file| @options[:manifest] = file }
|
58
|
+
opts.on('--manifest FILE') { |file| @options[:manifest] = file }
|
59
|
+
|
60
|
+
opts.on('-q', '--quiet') { @options[:quiet] = true }
|
61
|
+
|
62
|
+
# micro cloud options
|
63
|
+
opts.on('--vmx FILE') { |file| @options[:vmx] = file }
|
64
|
+
opts.on('--vmrun FILE') { |file| @options[:vmrun] = file }
|
65
|
+
opts.on('--save') { @options[:save] = true }
|
66
|
+
|
67
|
+
# Don't use builtin zip
|
68
|
+
opts.on('--no-zip') { @options[:nozip] = true }
|
69
|
+
opts.on('--nozip') { @options[:nozip] = true }
|
70
|
+
|
71
|
+
opts.on('--no-resources') { @options[:noresources] = true }
|
72
|
+
opts.on('--noresources') { @options[:noresources] = true }
|
73
|
+
|
74
|
+
opts.on('--no-color') { @options[:colorize] = false }
|
75
|
+
opts.on('--verbose') { @options[:verbose] = true }
|
76
|
+
|
77
|
+
opts.on('-n','--no-prompt') { @options[:noprompts] = true }
|
78
|
+
opts.on('--noprompt') { @options[:noprompts] = true }
|
79
|
+
opts.on('--non-interactive') { @options[:noprompts] = true }
|
80
|
+
|
81
|
+
opts.on('--prefix') { @options[:prefixlogs] = true }
|
82
|
+
opts.on('--prefix-logs') { @options[:prefixlogs] = true }
|
83
|
+
opts.on('--prefixlogs') { @options[:prefixlogs] = true }
|
84
|
+
|
85
|
+
opts.on('--json') { @options[:json] = true }
|
86
|
+
|
87
|
+
opts.on('-v', '--version') { set_cmd(:misc, :version) }
|
88
|
+
opts.on('-h', '--help') { puts "#{command_usage}\n"; exit }
|
89
|
+
|
90
|
+
opts.on('--port PORT') { |port| @options[:port] = port }
|
91
|
+
|
92
|
+
opts.on('--runtime RUNTIME') { |rt| @options[:runtime] = rt }
|
93
|
+
|
94
|
+
# deprecated
|
95
|
+
opts.on('--exec EXEC') { |exec| @options[:exec] = exec }
|
96
|
+
opts.on('--noframework') { @options[:noframework] = true }
|
97
|
+
opts.on('--canary') { @options[:canary] = true }
|
98
|
+
|
99
|
+
# Proxying for another user, requires admin privileges
|
100
|
+
opts.on('-u PROXY') { |proxy| @options[:proxy] = proxy }
|
101
|
+
|
102
|
+
# Select infrastructure
|
103
|
+
opts.on('--infra INFRA') { |infra| @options[:infra] = infra }
|
104
|
+
|
105
|
+
opts.on_tail('--options') { puts "#{opts}\n"; exit }
|
106
|
+
end
|
107
|
+
instances_delta_arg = check_instances_delta!
|
108
|
+
@args = opts_parser.parse!(@args)
|
109
|
+
@args.concat instances_delta_arg
|
110
|
+
convert_options!
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
def check_instances_delta!
|
115
|
+
return unless @args
|
116
|
+
instance_args = @args.select { |arg| /^[-]\d+$/ =~ arg } || []
|
117
|
+
@args.delete_if { |arg| instance_args.include? arg}
|
118
|
+
instance_args
|
119
|
+
end
|
120
|
+
|
121
|
+
def display_help
|
122
|
+
puts command_usage
|
123
|
+
exit
|
124
|
+
end
|
125
|
+
|
126
|
+
def convert_options!
|
127
|
+
# make sure certain options are valid and in correct form.
|
128
|
+
@options[:instances] = Integer(@options[:instances]) if @options[:instances]
|
129
|
+
end
|
130
|
+
|
131
|
+
def set_cmd(namespace, action, args_range=0)
|
132
|
+
return if @help_only
|
133
|
+
unless args_range == "*" || args_range.is_a?(Range)
|
134
|
+
args_range = (args_range.to_i..args_range.to_i)
|
135
|
+
end
|
136
|
+
|
137
|
+
if args_range == "*" || args_range.include?(@args.size)
|
138
|
+
@namespace = namespace
|
139
|
+
@action = action
|
140
|
+
else
|
141
|
+
@exit_status = false
|
142
|
+
if @args.size > args_range.last
|
143
|
+
usage_error("Too many arguments for [#{action}]: %s" % [ @args[args_range.last..-1].map{|a| "'#{a}'"}.join(', ') ])
|
144
|
+
else
|
145
|
+
usage_error("Not enough arguments for [#{action}]")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def parse_command!
|
151
|
+
# just return if already set, happends with -v, -h
|
152
|
+
return if @namespace && @action
|
153
|
+
|
154
|
+
verb = @args.shift
|
155
|
+
case verb
|
156
|
+
|
157
|
+
when 'version'
|
158
|
+
usage('olympe version')
|
159
|
+
set_cmd(:misc, :version)
|
160
|
+
|
161
|
+
when 'target'
|
162
|
+
usage('olympe target [url] [--url]')
|
163
|
+
if @args.size == 1
|
164
|
+
set_cmd(:misc, :set_target, 1)
|
165
|
+
else
|
166
|
+
set_cmd(:misc, :target)
|
167
|
+
end
|
168
|
+
|
169
|
+
when 'targets'
|
170
|
+
usage('olympe targets')
|
171
|
+
set_cmd(:misc, :targets)
|
172
|
+
|
173
|
+
when 'tokens'
|
174
|
+
usage('olympe tokens')
|
175
|
+
set_cmd(:misc, :tokens)
|
176
|
+
|
177
|
+
when 'info'
|
178
|
+
usage('olympe info')
|
179
|
+
set_cmd(:misc, :info)
|
180
|
+
|
181
|
+
when 'runtimes'
|
182
|
+
usage('olympe runtimes')
|
183
|
+
set_cmd(:misc, :runtimes)
|
184
|
+
|
185
|
+
when 'frameworks'
|
186
|
+
usage('olympe frameworks')
|
187
|
+
set_cmd(:misc, :frameworks)
|
188
|
+
|
189
|
+
when 'infras'
|
190
|
+
usage('olympe infras')
|
191
|
+
set_cmd(:misc, :infras)
|
192
|
+
|
193
|
+
when 'user'
|
194
|
+
usage('olympe user')
|
195
|
+
set_cmd(:user, :info)
|
196
|
+
|
197
|
+
when 'login'
|
198
|
+
usage('olympe login [email] [--email EMAIL] [--passwd PASS]')
|
199
|
+
if @args.size == 1
|
200
|
+
set_cmd(:user, :login, 1)
|
201
|
+
else
|
202
|
+
set_cmd(:user, :login)
|
203
|
+
end
|
204
|
+
|
205
|
+
when 'logout'
|
206
|
+
usage('olympe logout')
|
207
|
+
set_cmd(:user, :logout)
|
208
|
+
|
209
|
+
when 'passwd'
|
210
|
+
usage('olympe passwd')
|
211
|
+
if @args.size == 1
|
212
|
+
set_cmd(:user, :change_password, 1)
|
213
|
+
else
|
214
|
+
set_cmd(:user, :change_password)
|
215
|
+
end
|
216
|
+
|
217
|
+
when 'add-user', 'add_user', 'create_user', 'create-user', 'register'
|
218
|
+
usage('olympe add-user [user] [--email EMAIL] [--passwd PASS]')
|
219
|
+
if @args.size == 1
|
220
|
+
set_cmd(:admin, :add_user, 1)
|
221
|
+
else
|
222
|
+
set_cmd(:admin, :add_user)
|
223
|
+
end
|
224
|
+
|
225
|
+
when 'delete-user', 'delete_user', 'unregister'
|
226
|
+
usage('olympe delete-user <user>')
|
227
|
+
set_cmd(:admin, :delete_user, 1)
|
228
|
+
|
229
|
+
when 'users'
|
230
|
+
usage('olympe users')
|
231
|
+
set_cmd(:admin, :users)
|
232
|
+
|
233
|
+
when 'apps'
|
234
|
+
usage('olympe apps')
|
235
|
+
set_cmd(:apps, :apps)
|
236
|
+
|
237
|
+
when 'list'
|
238
|
+
usage('olympe list')
|
239
|
+
set_cmd(:apps, :list)
|
240
|
+
|
241
|
+
when 'start'
|
242
|
+
usage('olympe start <appname>')
|
243
|
+
set_cmd(:apps, :start, @args.size == 1 ? 1 : 0)
|
244
|
+
|
245
|
+
when 'stop'
|
246
|
+
usage('olympe stop <appname>')
|
247
|
+
set_cmd(:apps, :stop, @args.size == 1 ? 1 : 0)
|
248
|
+
|
249
|
+
when 'restart'
|
250
|
+
usage('olympe restart <appname>')
|
251
|
+
set_cmd(:apps, :restart, @args.size == 1 ? 1 : 0)
|
252
|
+
|
253
|
+
when 'mem'
|
254
|
+
usage('olympe mem <appname> [memsize]')
|
255
|
+
if @args.size == 2
|
256
|
+
set_cmd(:apps, :mem, 2)
|
257
|
+
else
|
258
|
+
set_cmd(:apps, :mem, 1)
|
259
|
+
end
|
260
|
+
|
261
|
+
when 'stats'
|
262
|
+
usage('olympe stats <appname>')
|
263
|
+
set_cmd(:apps, :stats, @args.size == 1 ? 1 : 0)
|
264
|
+
|
265
|
+
when 'map'
|
266
|
+
usage('olympe map <appname> <url>')
|
267
|
+
set_cmd(:apps, :map, 2)
|
268
|
+
|
269
|
+
when 'unmap'
|
270
|
+
usage('olympe unmap <appname> <url>')
|
271
|
+
set_cmd(:apps, :unmap, 2)
|
272
|
+
|
273
|
+
when 'delete'
|
274
|
+
usage('olympe delete <appname>')
|
275
|
+
if @options[:all] && @args.size == 0
|
276
|
+
set_cmd(:apps, :delete)
|
277
|
+
else
|
278
|
+
set_cmd(:apps, :delete, 1)
|
279
|
+
end
|
280
|
+
|
281
|
+
when 'files'
|
282
|
+
usage('olympe files <appname> [path] [--instance N] [--all] [--prefix]')
|
283
|
+
if @args.size == 1
|
284
|
+
set_cmd(:apps, :files, 1)
|
285
|
+
else
|
286
|
+
set_cmd(:apps, :files, 2)
|
287
|
+
end
|
288
|
+
|
289
|
+
when 'download'
|
290
|
+
usage('olympe download <appname> [path]')
|
291
|
+
if @args.size == 1
|
292
|
+
set_cmd(:apps, :download, 1)
|
293
|
+
else
|
294
|
+
set_cmd(:apps, :download, 2)
|
295
|
+
end
|
296
|
+
|
297
|
+
when 'pull'
|
298
|
+
usage('olympe pull <appname> [path]')
|
299
|
+
if @args.size == 1
|
300
|
+
set_cmd(:apps, :pull, 1)
|
301
|
+
else
|
302
|
+
set_cmd(:apps, :pull, 2)
|
303
|
+
end
|
304
|
+
|
305
|
+
when 'logs'
|
306
|
+
usage('olympe logs <appname> [--instance N] [--all] [--prefix]')
|
307
|
+
set_cmd(:apps, :logs, 1)
|
308
|
+
|
309
|
+
when 'instances', 'scale'
|
310
|
+
if @args.size > 1
|
311
|
+
usage('olympe instances <appname> <num|delta>')
|
312
|
+
set_cmd(:apps, :instances, 2)
|
313
|
+
else
|
314
|
+
usage('olympe instances <appname>')
|
315
|
+
set_cmd(:apps, :instances, 1)
|
316
|
+
end
|
317
|
+
|
318
|
+
when 'crashes'
|
319
|
+
usage('olympe crashes <appname>')
|
320
|
+
set_cmd(:apps, :crashes, 1)
|
321
|
+
|
322
|
+
when 'crashlogs'
|
323
|
+
usage('olympe crashlogs <appname>')
|
324
|
+
set_cmd(:apps, :crashlogs, 1)
|
325
|
+
|
326
|
+
when 'push'
|
327
|
+
usage('olympe push [appname] [--path PATH] [--url URL] [--instances N] [--mem] [--runtime RUNTIME] [--no-start] [--infra infraname]')
|
328
|
+
if @args.size == 1
|
329
|
+
set_cmd(:apps, :push, 1)
|
330
|
+
else
|
331
|
+
set_cmd(:apps, :push, 0)
|
332
|
+
end
|
333
|
+
|
334
|
+
when 'update'
|
335
|
+
usage('olympe update <appname> [--path PATH]')
|
336
|
+
set_cmd(:apps, :update, @args.size == 1 ? 1 : 0)
|
337
|
+
|
338
|
+
when 'services'
|
339
|
+
usage('olympe services')
|
340
|
+
set_cmd(:services, :services)
|
341
|
+
|
342
|
+
when 'env'
|
343
|
+
usage('olympe env <appname>')
|
344
|
+
set_cmd(:apps, :environment, 1)
|
345
|
+
|
346
|
+
when 'env-add'
|
347
|
+
usage('olympe env-add <appname> <variable[=]value>')
|
348
|
+
if @args.size == 2
|
349
|
+
set_cmd(:apps, :environment_add, 2)
|
350
|
+
elsif @args.size == 3
|
351
|
+
set_cmd(:apps, :environment_add, 3)
|
352
|
+
end
|
353
|
+
|
354
|
+
when 'env-del'
|
355
|
+
usage('olympe env-del <appname> <variable>')
|
356
|
+
set_cmd(:apps, :environment_del, 2)
|
357
|
+
|
358
|
+
when 'create-service', 'create_service'
|
359
|
+
usage('olympe create-service [service] [servicename] [appname] [--name servicename] [--bind appname] [--infra infraname]')
|
360
|
+
set_cmd(:services, :create_service) if @args.size == 0
|
361
|
+
set_cmd(:services, :create_service, 1) if @args.size == 1
|
362
|
+
set_cmd(:services, :create_service, 2) if @args.size == 2
|
363
|
+
set_cmd(:services, :create_service, 3) if @args.size == 3
|
364
|
+
|
365
|
+
when 'delete-service', 'delete_service'
|
366
|
+
usage('olympe delete-service <service>')
|
367
|
+
if @args.size == 1
|
368
|
+
set_cmd(:services, :delete_service, 1)
|
369
|
+
else
|
370
|
+
set_cmd(:services, :delete_service)
|
371
|
+
end
|
372
|
+
|
373
|
+
when 'bind-service', 'bind_service'
|
374
|
+
usage('olympe bind-service <servicename> <appname>')
|
375
|
+
set_cmd(:services, :bind_service, 2)
|
376
|
+
|
377
|
+
when 'unbind-service', 'unbind_service'
|
378
|
+
usage('olympe unbind-service <servicename> <appname>')
|
379
|
+
set_cmd(:services, :unbind_service, 2)
|
380
|
+
|
381
|
+
when 'clone-services'
|
382
|
+
usage('olympe clone-services <src-app> <dest-app>')
|
383
|
+
set_cmd(:services, :clone_services, 2)
|
384
|
+
|
385
|
+
when 'export-service'
|
386
|
+
usage('olympe export-service <service-name>')
|
387
|
+
set_cmd(:services, :export_service, 1)
|
388
|
+
|
389
|
+
when 'import-service'
|
390
|
+
usage('olympe import-service <service-name> <url>')
|
391
|
+
set_cmd(:services, :import_service, 2)
|
392
|
+
|
393
|
+
when 'clone'
|
394
|
+
usage('olympe clone <src-app> <dest-app> [<infra>]')
|
395
|
+
set_cmd(:apps, :clone, 2) if @args.size == 2
|
396
|
+
set_cmd(:apps, :clone, 3) if @args.size == 3
|
397
|
+
|
398
|
+
when 'aliases'
|
399
|
+
usage('olympe aliases')
|
400
|
+
set_cmd(:misc, :aliases)
|
401
|
+
|
402
|
+
when 'alias'
|
403
|
+
usage('olympe alias <alias[=]command>')
|
404
|
+
if @args.size == 1
|
405
|
+
set_cmd(:misc, :alias, 1)
|
406
|
+
elsif @args.size == 2
|
407
|
+
set_cmd(:misc, :alias, 2)
|
408
|
+
end
|
409
|
+
|
410
|
+
when 'unalias'
|
411
|
+
usage('olympe unalias <alias>')
|
412
|
+
set_cmd(:misc, :unalias, 1)
|
413
|
+
|
414
|
+
when 'tunnel'
|
415
|
+
usage('olympe tunnel [servicename] [clientcmd] [--port port]')
|
416
|
+
set_cmd(:services, :tunnel, 0) if @args.size == 0
|
417
|
+
set_cmd(:services, :tunnel, 1) if @args.size == 1
|
418
|
+
set_cmd(:services, :tunnel, 2) if @args.size == 2
|
419
|
+
|
420
|
+
when 'rails-console'
|
421
|
+
usage('olympe rails-console <appname>')
|
422
|
+
set_cmd(:apps, :console, 1)
|
423
|
+
|
424
|
+
when 'micro'
|
425
|
+
usage('olympe micro <online|offline|status> [--password password] [--save] [--vmx file] [--vmrun executable]')
|
426
|
+
if %w[online offline status].include?(@args[0])
|
427
|
+
set_cmd(:micro, @args[0].to_sym, 1)
|
428
|
+
end
|
429
|
+
|
430
|
+
when 'help'
|
431
|
+
display_help if @args.size == 0
|
432
|
+
@help_only = true
|
433
|
+
parse_command!
|
434
|
+
|
435
|
+
when 'usage'
|
436
|
+
display basic_usage
|
437
|
+
exit(true)
|
438
|
+
|
439
|
+
when 'options'
|
440
|
+
# Simulate --options
|
441
|
+
@args = @args.unshift('--options')
|
442
|
+
parse_options!
|
443
|
+
|
444
|
+
when 'manifest'
|
445
|
+
usage('olympe manifest')
|
446
|
+
set_cmd(:manifest, :edit)
|
447
|
+
|
448
|
+
when 'extend-manifest'
|
449
|
+
usage('olympe extend-manifest')
|
450
|
+
set_cmd(:manifest, :extend, 1)
|
451
|
+
|
452
|
+
else
|
453
|
+
if verb
|
454
|
+
display "olympe: Unknown command [#{verb}]"
|
455
|
+
display basic_usage
|
456
|
+
exit(false)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
def process_aliases!
|
462
|
+
return if @args.empty?
|
463
|
+
aliases = VMC::Cli::Config.aliases
|
464
|
+
aliases.each_pair do |k,v|
|
465
|
+
if @args[0] == k
|
466
|
+
display "[#{@args[0]} aliased to #{aliases.invert[key]}]" if @options[:verbose]
|
467
|
+
@args[0] = v
|
468
|
+
break;
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def usage(msg = nil)
|
474
|
+
@usage = msg if msg
|
475
|
+
@usage
|
476
|
+
end
|
477
|
+
|
478
|
+
def usage_error(msg = nil)
|
479
|
+
@usage_error = msg if msg
|
480
|
+
@usage_error
|
481
|
+
end
|
482
|
+
|
483
|
+
def run
|
484
|
+
|
485
|
+
trap('TERM') { print "\nTerminated\n"; exit(false)}
|
486
|
+
|
487
|
+
parse_options!
|
488
|
+
|
489
|
+
@options[:colorize] = false unless STDOUT.tty?
|
490
|
+
|
491
|
+
VMC::Cli::Config.colorize = @options.delete(:colorize)
|
492
|
+
VMC::Cli::Config.nozip = @options.delete(:nozip)
|
493
|
+
VMC::Cli::Config.trace = @options.delete(:trace)
|
494
|
+
VMC::Cli::Config.output ||= STDOUT unless @options[:quiet]
|
495
|
+
VMC::Cli::Config.infra = @options[:infra]
|
496
|
+
|
497
|
+
process_aliases!
|
498
|
+
parse_command!
|
499
|
+
|
500
|
+
if @namespace && @action
|
501
|
+
cmd = VMC::Cli::Command.const_get(@namespace.to_s.capitalize)
|
502
|
+
cmd.new(@options).send(@action, *@args.collect(&:dup))
|
503
|
+
elsif @help_only || @usage
|
504
|
+
display_usage
|
505
|
+
else
|
506
|
+
display basic_usage
|
507
|
+
exit(false)
|
508
|
+
end
|
509
|
+
|
510
|
+
rescue OptionParser::InvalidOption => e
|
511
|
+
puts(e.message.red)
|
512
|
+
puts("\n")
|
513
|
+
puts(basic_usage)
|
514
|
+
@exit_status = false
|
515
|
+
rescue OptionParser::AmbiguousOption => e
|
516
|
+
puts(e.message.red)
|
517
|
+
puts("\n")
|
518
|
+
puts(basic_usage)
|
519
|
+
@exit_status = false
|
520
|
+
rescue VMC::Client::AuthError => e
|
521
|
+
if VMC::Cli::Config.auth_token.nil?
|
522
|
+
puts "Login Required".red
|
523
|
+
else
|
524
|
+
puts "Not Authorized".red
|
525
|
+
end
|
526
|
+
@exit_status = false
|
527
|
+
rescue VMC::Client::TargetError, VMC::Client::NotFound, VMC::Client::BadTarget => e
|
528
|
+
puts e.message.red
|
529
|
+
@exit_status = false
|
530
|
+
rescue VMC::Client::HTTPException => e
|
531
|
+
puts e.message.red
|
532
|
+
@exit_status = false
|
533
|
+
rescue VMC::Cli::GracefulExit => e
|
534
|
+
# Redirected commands end up generating this exception (kind of goto)
|
535
|
+
rescue VMC::Cli::CliExit => e
|
536
|
+
puts e.message.red
|
537
|
+
@exit_status = false
|
538
|
+
rescue VMC::Cli::CliError => e
|
539
|
+
say("Error #{e.error_code}: #{e.message}".red)
|
540
|
+
@exit_status = false
|
541
|
+
rescue SystemExit => e
|
542
|
+
@exit_status = e.success?
|
543
|
+
rescue SyntaxError => e
|
544
|
+
puts e.message.red
|
545
|
+
puts e.backtrace
|
546
|
+
@exit_status = false
|
547
|
+
rescue Interrupt => e
|
548
|
+
say("\nInterrupted".red)
|
549
|
+
@exit_status = false
|
550
|
+
rescue Exception => e
|
551
|
+
puts e.message.red
|
552
|
+
puts e.backtrace
|
553
|
+
@exit_status = false
|
554
|
+
ensure
|
555
|
+
say("\n")
|
556
|
+
@exit_status == true if @exit_status.nil?
|
557
|
+
if @options[:verbose]
|
558
|
+
if @exit_status
|
559
|
+
puts "[#{@namespace}:#{@action}] SUCCEEDED".green
|
560
|
+
else
|
561
|
+
puts "[#{@namespace}:#{@action}] FAILED".red
|
562
|
+
end
|
563
|
+
say("\n")
|
564
|
+
end
|
565
|
+
exit(@exit_status)
|
566
|
+
end
|
567
|
+
|
568
|
+
end
|
@@ -0,0 +1,104 @@
|
|
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
|
+
displayed_services = []
|
12
|
+
services.each do |service_type, value|
|
13
|
+
value.each do |vendor, version|
|
14
|
+
version.each do |version_str, service|
|
15
|
+
displayed_services << [ vendor, version_str, service[:description] ]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
displayed_services.sort! { |a, b| a.first.to_s <=> b.first.to_s}
|
20
|
+
|
21
|
+
services_table = table do |t|
|
22
|
+
t.headings = 'Service', 'Version', 'Description'
|
23
|
+
displayed_services.each { |s| t << s }
|
24
|
+
end
|
25
|
+
display services_table
|
26
|
+
end
|
27
|
+
|
28
|
+
def display_provisioned_services(services=nil)
|
29
|
+
services ||= client.services
|
30
|
+
display "\n=========== Provisioned Services ============\n\n"
|
31
|
+
display_provisioned_services_table(services)
|
32
|
+
end
|
33
|
+
|
34
|
+
def display_provisioned_services_table(services)
|
35
|
+
return unless services && !services.empty?
|
36
|
+
|
37
|
+
infra_supported = !services.detect { |a| a[:infra] }.nil?
|
38
|
+
services_table = table do |t|
|
39
|
+
t.headings = 'Name', 'Service'
|
40
|
+
t.headings << 'In' if infra_supported
|
41
|
+
services.each do |service|
|
42
|
+
s = [ service[:name], service[:vendor] ]
|
43
|
+
if infra_supported
|
44
|
+
s << ( service[:infra] ? service[:infra][:provider] : " " )
|
45
|
+
end
|
46
|
+
t << s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
display services_table
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_service_banner(service, name, display_name=false, infra=nil)
|
53
|
+
sn = " [#{name}]" if display_name
|
54
|
+
display "Creating Service#{sn}: ", false
|
55
|
+
client.create_service(infra,service, name)
|
56
|
+
display 'OK'.green
|
57
|
+
end
|
58
|
+
|
59
|
+
def bind_service_banner(service, appname, check_restart=true)
|
60
|
+
display "Binding Service [#{service}]: ", false
|
61
|
+
client.bind_service(service, appname)
|
62
|
+
display 'OK'.green
|
63
|
+
check_app_for_restart(appname) if check_restart
|
64
|
+
end
|
65
|
+
|
66
|
+
def unbind_service_banner(service, appname, check_restart=true)
|
67
|
+
display "Unbinding Service [#{service}]: ", false
|
68
|
+
client.unbind_service(service, appname)
|
69
|
+
display 'OK'.green
|
70
|
+
check_app_for_restart(appname) if check_restart
|
71
|
+
end
|
72
|
+
|
73
|
+
def delete_service_banner(service)
|
74
|
+
display "Deleting service [#{service}]: ", false
|
75
|
+
client.delete_service(service)
|
76
|
+
display 'OK'.green
|
77
|
+
end
|
78
|
+
|
79
|
+
def random_service_name(service)
|
80
|
+
r = "%04x" % [rand(0x0100000)]
|
81
|
+
"#{service.to_s}-#{r}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_cloned_service_name(src_appname,dest_appname,src_servicename,dest_infra)
|
85
|
+
r = "%04x" % [rand(0x0100000)]
|
86
|
+
dest_servicename = src_servicename.sub(src_appname,dest_appname).sub(/-[0-9A-Fa-f]{4,5}/,"-#{r}")
|
87
|
+
if src_servicename == dest_servicename
|
88
|
+
if dest_infra
|
89
|
+
dest_servicename = "#{dest_servicename}-#{dest_infra}"
|
90
|
+
else
|
91
|
+
dest_servicename = "#{dest_servicename}-#{r}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
dest_servicename
|
95
|
+
end
|
96
|
+
|
97
|
+
def check_app_for_restart(appname)
|
98
|
+
app = client.app_info(appname)
|
99
|
+
cmd = VMC::Cli::Command::Apps.new(@options)
|
100
|
+
cmd.restart(appname) if app[:state] == 'STARTED'
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|