vmc 0.4.0.beta.21 → 0.4.0.beta.22
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/vmc-ng/lib/vmc/cli/app.rb +155 -169
- data/vmc-ng/lib/vmc/cli/service.rb +90 -41
- data/vmc-ng/lib/vmc/cli/start.rb +1 -6
- data/vmc-ng/lib/vmc/cli.rb +12 -9
- data/vmc-ng/lib/vmc/version.rb +1 -1
- data/vmc-ng/spec/start/target_spec.rb +10 -0
- metadata +14 -14
data/vmc-ng/lib/vmc/cli/app.rb
CHANGED
@@ -40,14 +40,18 @@ module VMC
|
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
+
def self.by_name(what)
|
44
|
+
proc { |name|
|
45
|
+
client.send(:"#{what}_by_name", name) ||
|
46
|
+
fail("Unknown #{what} '#{name}'")
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
43
50
|
|
44
51
|
desc "List your applications"
|
45
52
|
group :apps
|
46
53
|
input :space, :desc => "Show apps in given space",
|
47
|
-
:from_given =>
|
48
|
-
client.space_by_name(name) || \
|
49
|
-
fail("Unknown space '#{name}'")
|
50
|
-
}
|
54
|
+
:from_given => by_name("space")
|
51
55
|
input :name, :desc => "Filter by name regexp"
|
52
56
|
input :runtime, :desc => "Filter by runtime regexp"
|
53
57
|
input :framework, :desc => "Filter by framework regexp"
|
@@ -56,7 +60,8 @@ module VMC
|
|
56
60
|
if space = input[:space] || client.current_space
|
57
61
|
apps =
|
58
62
|
with_progress("Getting applications in #{c(space.name, :name)}") do
|
59
|
-
|
63
|
+
# depth of 2 for service binding instance names
|
64
|
+
space.apps(2)
|
60
65
|
end
|
61
66
|
else
|
62
67
|
apps =
|
@@ -82,7 +87,8 @@ module VMC
|
|
82
87
|
input(:name, :argument => true, :desc => "Application name") {
|
83
88
|
ask("Name")
|
84
89
|
}
|
85
|
-
input :path, :
|
90
|
+
input :path, :default => ".",
|
91
|
+
:desc => "Path containing the application"
|
86
92
|
input(:url, :desc => "URL bound to app") { |default|
|
87
93
|
ask("URL", :default => default)
|
88
94
|
}
|
@@ -98,8 +104,8 @@ module VMC
|
|
98
104
|
:desc => "Number of instances to run") {
|
99
105
|
ask("Instances", :default => 1)
|
100
106
|
}
|
101
|
-
input(:framework, :
|
102
|
-
:
|
107
|
+
input(:framework, :from_given => find_by_name("framework"),
|
108
|
+
:desc => "Framework to use") { |choices, default, other|
|
103
109
|
choices = choices.sort_by(&:name)
|
104
110
|
choices << other if other
|
105
111
|
|
@@ -138,13 +144,13 @@ module VMC
|
|
138
144
|
ask "Bind other services to application?", :default => false
|
139
145
|
}
|
140
146
|
def push(input)
|
141
|
-
path = File.expand_path(input[:path]
|
147
|
+
path = File.expand_path(input[:path])
|
142
148
|
|
143
|
-
name = input[:name]
|
149
|
+
name = input[:name]
|
144
150
|
|
145
151
|
if exists = client.app_by_name(name)
|
146
152
|
upload_app(exists, path)
|
147
|
-
invoke :restart, :
|
153
|
+
invoke :restart, :app => exists if input[:restart]
|
148
154
|
return
|
149
155
|
end
|
150
156
|
|
@@ -193,43 +199,35 @@ module VMC
|
|
193
199
|
|
194
200
|
app.memory = megabytes(input[:memory, framework, runtime])
|
195
201
|
|
196
|
-
|
197
|
-
if !v2? && input[:create_services] && !force?
|
198
|
-
services = client.services
|
202
|
+
app = filter(:create_app, app)
|
199
203
|
|
200
|
-
|
201
|
-
|
204
|
+
with_progress("Creating #{c(app.name, :name)}") do
|
205
|
+
app.create!
|
206
|
+
end
|
202
207
|
|
203
|
-
|
208
|
+
bindings = []
|
204
209
|
|
210
|
+
if input[:create_services] && !force?
|
211
|
+
while true
|
212
|
+
invoke :create_service, :app => app
|
205
213
|
break unless ask "Create another service?", :default => false
|
206
214
|
end
|
207
215
|
end
|
208
216
|
|
209
|
-
if
|
210
|
-
|
217
|
+
if input[:bind_services] && !force?
|
218
|
+
instances = client.service_instances
|
211
219
|
|
212
220
|
while true
|
213
|
-
|
214
|
-
break if choices.empty?
|
221
|
+
invoke :bind_service, :app => app
|
215
222
|
|
216
|
-
|
223
|
+
break if (instances - app.services).empty?
|
217
224
|
|
218
|
-
unless
|
219
|
-
ask("Bind another service?", :default => false)
|
220
|
-
break
|
221
|
-
end
|
225
|
+
break unless ask("Bind another service?", :default => false)
|
222
226
|
end
|
223
227
|
end
|
224
228
|
|
225
|
-
app.services = bindings
|
226
|
-
|
227
229
|
app = filter(:push_app, app)
|
228
230
|
|
229
|
-
with_progress("Creating #{c(name, :name)}") do
|
230
|
-
app.create!
|
231
|
-
end
|
232
|
-
|
233
231
|
begin
|
234
232
|
upload_app(app, path)
|
235
233
|
rescue
|
@@ -237,32 +235,27 @@ module VMC
|
|
237
235
|
raise
|
238
236
|
end
|
239
237
|
|
240
|
-
invoke :start, :
|
238
|
+
invoke :start, :app => app if input[:start]
|
241
239
|
end
|
242
240
|
|
243
241
|
|
244
242
|
desc "Start an application"
|
245
243
|
group :apps, :manage
|
246
|
-
input :
|
247
|
-
:desc => "Applications to start"
|
244
|
+
input :apps, :argument => :splat, :singular => :app,
|
245
|
+
:desc => "Applications to start",
|
246
|
+
:from_given => find_by_name("app")
|
248
247
|
input :debug_mode, :aliases => "-d",
|
249
248
|
:desc => "Debug mode to start in"
|
250
249
|
def start(input)
|
251
|
-
|
252
|
-
fail "No applications given." if
|
253
|
-
|
254
|
-
apps = client.apps
|
255
|
-
|
256
|
-
names.each do |name|
|
257
|
-
app = apps.find { |a| a.name == name }
|
258
|
-
|
259
|
-
fail "Unknown application '#{name}'" unless app
|
250
|
+
apps = input[:apps, client.apps]
|
251
|
+
fail "No applications given." if apps.empty?
|
260
252
|
|
253
|
+
apps.each do |app|
|
261
254
|
app = filter(:start_app, app)
|
262
255
|
|
263
256
|
switch_mode(app, input[:debug_mode])
|
264
257
|
|
265
|
-
with_progress("Starting #{c(name, :name)}") do |s|
|
258
|
+
with_progress("Starting #{c(app.name, :name)}") do |s|
|
266
259
|
if app.started?
|
267
260
|
s.skip do
|
268
261
|
err "Already started."
|
@@ -279,7 +272,7 @@ module VMC
|
|
279
272
|
|
280
273
|
if app.debug_mode && !quiet?
|
281
274
|
puts ""
|
282
|
-
instances
|
275
|
+
invoke :instances, :app => app
|
283
276
|
end
|
284
277
|
end
|
285
278
|
end
|
@@ -287,20 +280,15 @@ module VMC
|
|
287
280
|
|
288
281
|
desc "Stop an application"
|
289
282
|
group :apps, :manage
|
290
|
-
input :
|
291
|
-
:desc => "Applications to
|
283
|
+
input :apps, :argument => :splat, :singular => :app,
|
284
|
+
:desc => "Applications to start",
|
285
|
+
:from_given => find_by_name("app")
|
292
286
|
def stop(input)
|
293
|
-
|
294
|
-
fail "No applications given." if
|
295
|
-
|
296
|
-
apps = client.apps
|
297
|
-
|
298
|
-
names.each do |name|
|
299
|
-
app = apps.find { |a| a.name == name }
|
287
|
+
apps = input[:apps, client.apps]
|
288
|
+
fail "No applications given." if apps.empty?
|
300
289
|
|
301
|
-
|
302
|
-
|
303
|
-
with_progress("Stopping #{c(name, :name)}") do |s|
|
290
|
+
apps.each do |app|
|
291
|
+
with_progress("Stopping #{c(app.name, :name)}") do |s|
|
304
292
|
if app.stopped?
|
305
293
|
s.skip do
|
306
294
|
err "Application is not running."
|
@@ -315,28 +303,31 @@ module VMC
|
|
315
303
|
|
316
304
|
desc "Stop and start an application"
|
317
305
|
group :apps, :manage
|
318
|
-
input :
|
319
|
-
:desc => "Applications to
|
306
|
+
input :apps, :argument => :splat, :singular => :app,
|
307
|
+
:desc => "Applications to start",
|
308
|
+
:from_given => find_by_name("app")
|
320
309
|
input :debug_mode, :aliases => "-d",
|
321
310
|
:desc => "Debug mode to start in"
|
322
311
|
def restart(input)
|
323
|
-
|
324
|
-
|
312
|
+
apps = client.apps
|
313
|
+
|
314
|
+
invoke :stop, :apps => input[:apps, apps]
|
315
|
+
invoke :start, :apps => input[:apps, apps],
|
325
316
|
:debug_mode => input[:debug_mode]
|
326
317
|
end
|
327
318
|
|
328
319
|
|
329
320
|
desc "Delete an application"
|
330
321
|
group :apps, :manage
|
331
|
-
input(:really, :type => :boolean, :forget => true) { |name, color|
|
332
|
-
force? || ask("Really delete #{c(name, color)}?", :default => false)
|
333
|
-
}
|
334
322
|
input(:apps, :argument => :splat, :singular => :app,
|
335
323
|
:desc => "Applications to delete",
|
336
|
-
:from_given => find_by_name("
|
324
|
+
:from_given => find_by_name("app")) { |apps|
|
337
325
|
[ask("Delete which application?", :choices => apps.sort_by(&:name),
|
338
326
|
:display => proc(&:name))]
|
339
327
|
}
|
328
|
+
input(:really, :type => :boolean, :forget => true) { |name, color|
|
329
|
+
force? || ask("Really delete #{c(name, color)}?", :default => false)
|
330
|
+
}
|
340
331
|
input :orphaned, :aliases => "-o", :type => :boolean,
|
341
332
|
:desc => "Delete orphaned instances"
|
342
333
|
input :all, :default => false,
|
@@ -387,18 +378,19 @@ module VMC
|
|
387
378
|
|
388
379
|
desc "List an app's instances"
|
389
380
|
group :apps, :info, :hidden => true
|
390
|
-
input :
|
391
|
-
:desc => "Applications to
|
381
|
+
input :apps, :argument => :splat, :singular => :app,
|
382
|
+
:desc => "Applications to start",
|
383
|
+
:from_given => find_by_name("app")
|
392
384
|
def instances(input)
|
393
385
|
no_v2
|
394
386
|
|
395
|
-
|
396
|
-
fail "No applications given." if
|
387
|
+
apps = input[:apps, client.apps]
|
388
|
+
fail "No applications given." if apps.empty?
|
397
389
|
|
398
|
-
|
390
|
+
apps.each do |app|
|
399
391
|
instances =
|
400
|
-
with_progress("Getting instances for #{c(name, :name)}") do
|
401
|
-
|
392
|
+
with_progress("Getting instances for #{c(app.name, :name)}") do
|
393
|
+
app.instances
|
402
394
|
end
|
403
395
|
|
404
396
|
instances.each do |i|
|
@@ -415,7 +407,8 @@ module VMC
|
|
415
407
|
|
416
408
|
desc "Update the instances/memory limit for an application"
|
417
409
|
group :apps, :info, :hidden => true
|
418
|
-
input :
|
410
|
+
input :app, :argument => true, :desc => "Application to update",
|
411
|
+
:from_given => by_name("app")
|
419
412
|
input(:instances, :type => :numeric,
|
420
413
|
:desc => "Number of instances to run") { |default|
|
421
414
|
ask("Instances", :default => default)
|
@@ -427,8 +420,7 @@ module VMC
|
|
427
420
|
input :restart, :type => :boolean, :default => true,
|
428
421
|
:desc => "Restart app after updating?"
|
429
422
|
def scale(input)
|
430
|
-
|
431
|
-
app = client.app_by_name(name)
|
423
|
+
app = input[:app]
|
432
424
|
|
433
425
|
instances = input.given(:instances)
|
434
426
|
memory = input.given(:memory)
|
@@ -445,22 +437,23 @@ module VMC
|
|
445
437
|
|
446
438
|
return unless memory_changed || instances_changed
|
447
439
|
|
448
|
-
with_progress("Scaling #{c(name, :name)}") do
|
440
|
+
with_progress("Scaling #{c(app.name, :name)}") do
|
449
441
|
app.total_instances = instances.to_i if instances
|
450
442
|
app.memory = megs if memory
|
451
443
|
app.update!
|
452
444
|
end
|
453
445
|
|
454
446
|
if memory_changed && app.started? && input[:restart]
|
455
|
-
invoke :restart, :
|
447
|
+
invoke :restart, :app => app
|
456
448
|
end
|
457
449
|
end
|
458
450
|
|
459
451
|
|
460
452
|
desc "Print out an app's logs"
|
461
453
|
group :apps, :info, :hidden => true
|
462
|
-
input :
|
463
|
-
:desc => "Application to get the logs of"
|
454
|
+
input :app, :argument => true,
|
455
|
+
:desc => "Application to get the logs of",
|
456
|
+
:from_given => by_name("app")
|
464
457
|
input :instance, :type => :numeric, :default => 0,
|
465
458
|
:desc => "Instance of application to get the logs of"
|
466
459
|
input :all, :default => false,
|
@@ -468,10 +461,7 @@ module VMC
|
|
468
461
|
def logs(input)
|
469
462
|
no_v2
|
470
463
|
|
471
|
-
|
472
|
-
|
473
|
-
app = client.app_by_name(name)
|
474
|
-
fail "Unknown application '#{name}'" unless app.exists?
|
464
|
+
app = input[:app]
|
475
465
|
|
476
466
|
instances =
|
477
467
|
if input[:all]
|
@@ -484,16 +474,15 @@ module VMC
|
|
484
474
|
if input[:all]
|
485
475
|
fail "No instances found."
|
486
476
|
else
|
487
|
-
fail "Instance #{name} \##{input[:instance]} not found."
|
477
|
+
fail "Instance #{app.name} \##{input[:instance]} not found."
|
488
478
|
end
|
489
479
|
end
|
490
480
|
|
491
481
|
instances.each do |i|
|
492
482
|
logs =
|
493
483
|
with_progress(
|
494
|
-
|
495
|
-
|
496
|
-
c("\##{i.index}", :instance)) do
|
484
|
+
"Getting logs for #{c(app.name, :name)}" +
|
485
|
+
c("\##{i.index}", :instance)) do
|
497
486
|
i.files("logs")
|
498
487
|
end
|
499
488
|
|
@@ -514,16 +503,19 @@ module VMC
|
|
514
503
|
|
515
504
|
desc "Print out an app's file contents"
|
516
505
|
group :apps, :info, :hidden => true
|
517
|
-
input :
|
518
|
-
:desc => "Application to inspect the files of"
|
506
|
+
input :app, :argument => true,
|
507
|
+
:desc => "Application to inspect the files of",
|
508
|
+
:from_given => by_name("app")
|
519
509
|
input :path, :argument => true, :default => "/",
|
520
510
|
:desc => "Path of file to read"
|
521
511
|
def file(input)
|
522
512
|
no_v2
|
523
513
|
|
514
|
+
app = input[:app]
|
515
|
+
|
524
516
|
file =
|
525
517
|
with_progress("Getting file contents") do
|
526
|
-
|
518
|
+
app.file(*input[:path].split("/"))
|
527
519
|
end
|
528
520
|
|
529
521
|
puts "" unless quiet?
|
@@ -533,16 +525,19 @@ module VMC
|
|
533
525
|
|
534
526
|
desc "Examine an app's files"
|
535
527
|
group :apps, :info, :hidden => true
|
536
|
-
input :
|
537
|
-
:desc => "Application to inspect the files of"
|
528
|
+
input :app, :argument => true,
|
529
|
+
:desc => "Application to inspect the files of",
|
530
|
+
:from_given => by_name("app")
|
538
531
|
input :path, :argument => true, :default => "/",
|
539
532
|
:desc => "Path of directory to list"
|
540
533
|
def files(input)
|
541
534
|
no_v2
|
542
535
|
|
536
|
+
app = input[:app]
|
537
|
+
|
543
538
|
files =
|
544
539
|
with_progress("Getting file listing") do
|
545
|
-
|
540
|
+
app.files(*input[:path].split("/"))
|
546
541
|
end
|
547
542
|
|
548
543
|
puts "" unless quiet?
|
@@ -554,22 +549,22 @@ module VMC
|
|
554
549
|
|
555
550
|
desc "Get application health"
|
556
551
|
group :apps, :info, :hidden => true
|
557
|
-
input :
|
558
|
-
:desc => "
|
552
|
+
input :apps, :argument => :splat, :singular => :app,
|
553
|
+
:desc => "Applications to start",
|
554
|
+
:from_given => find_by_name("application")
|
559
555
|
def health(input)
|
560
|
-
|
556
|
+
apps = input[:apps, client.apps]
|
557
|
+
fail "No applications given." if apps.empty?
|
561
558
|
|
562
|
-
|
563
|
-
with_progress("Getting
|
564
|
-
|
565
|
-
[n, app_status(client.app_by_name(n))]
|
566
|
-
end
|
559
|
+
health =
|
560
|
+
with_progress("Getting health status") do
|
561
|
+
apps.collect { |a| [a, app_status(a)] }
|
567
562
|
end
|
568
563
|
|
569
|
-
|
564
|
+
health.each do |app, status|
|
570
565
|
unless quiet?
|
571
566
|
puts ""
|
572
|
-
print "#{c(name, :name)}: "
|
567
|
+
print "#{c(app.name, :name)}: "
|
573
568
|
end
|
574
569
|
|
575
570
|
puts status
|
@@ -579,49 +574,53 @@ module VMC
|
|
579
574
|
|
580
575
|
desc "Display application instance status"
|
581
576
|
group :apps, :info, :hidden => true
|
582
|
-
input :
|
583
|
-
:desc => "Application to get the stats for"
|
577
|
+
input :app, :argument => true,
|
578
|
+
:desc => "Application to get the stats for",
|
579
|
+
:from_given => by_name("app")
|
584
580
|
def stats(input)
|
585
581
|
no_v2
|
586
582
|
|
583
|
+
app = input[:app]
|
584
|
+
|
587
585
|
stats =
|
588
|
-
with_progress("Getting stats for #{c(
|
589
|
-
|
586
|
+
with_progress("Getting stats for #{c(app.name, :name)}") do
|
587
|
+
app.stats
|
590
588
|
end
|
591
589
|
|
592
|
-
stats.sort_by
|
590
|
+
stats.sort_by(&:first).each do |idx, info|
|
593
591
|
puts ""
|
594
592
|
|
595
|
-
if info[
|
593
|
+
if info[:state] == "DOWN"
|
596
594
|
puts "Instance #{c("\##{idx}", :instance)} is down."
|
597
595
|
next
|
598
596
|
end
|
599
597
|
|
600
|
-
stats = info[
|
601
|
-
usage = stats[
|
598
|
+
stats = info[:stats]
|
599
|
+
usage = stats[:usage]
|
602
600
|
puts "instance #{c("\##{idx}", :instance)}:"
|
603
|
-
print " cpu: #{percentage(usage[
|
604
|
-
puts " #{b(stats[
|
605
|
-
puts " memory: #{usage(usage[
|
606
|
-
puts " disk: #{usage(usage[
|
601
|
+
print " cpu: #{percentage(usage[:cpu])} of"
|
602
|
+
puts " #{b(stats[:cores])} cores"
|
603
|
+
puts " memory: #{usage(usage[:mem] * 1024, stats[:mem_quota])}"
|
604
|
+
puts " disk: #{usage(usage[:disk], stats[:disk_quota])}"
|
607
605
|
end
|
608
606
|
end
|
609
607
|
|
610
608
|
|
611
609
|
desc "Add a URL mapping for an app"
|
612
610
|
group :apps, :info, :hidden => true
|
613
|
-
input :
|
614
|
-
:desc => "Application to add the URL to"
|
611
|
+
input :app, :argument => true,
|
612
|
+
:desc => "Application to add the URL to",
|
613
|
+
:from_given => by_name("app")
|
615
614
|
input :url, :argument => true,
|
616
615
|
:desc => "URL to route"
|
617
616
|
def map(input)
|
618
617
|
no_v2
|
619
618
|
|
620
|
-
|
619
|
+
app = input[:app]
|
620
|
+
|
621
621
|
simple = input[:url].sub(/^https?:\/\/(.*)\/?/i, '\1')
|
622
622
|
|
623
|
-
with_progress("Updating #{c(name, :name)}") do
|
624
|
-
app = client.app_by_name(name)
|
623
|
+
with_progress("Updating #{c(app.name, :name)}") do
|
625
624
|
app.urls << simple
|
626
625
|
app.update!
|
627
626
|
end
|
@@ -630,24 +629,21 @@ module VMC
|
|
630
629
|
|
631
630
|
desc "Remove a URL mapping from an app"
|
632
631
|
group :apps, :info, :hidden => true
|
633
|
-
input :
|
634
|
-
:desc => "Application to remove the URL from"
|
632
|
+
input :app, :argument => true,
|
633
|
+
:desc => "Application to remove the URL from",
|
634
|
+
:from_given => by_name("app")
|
635
635
|
input(:url, :argument => true, :desc => "URL to unmap") { |choices|
|
636
636
|
ask("Which URL?", :choices => choices)
|
637
637
|
}
|
638
638
|
def unmap(input)
|
639
639
|
no_v2
|
640
640
|
|
641
|
-
|
642
|
-
app = client.app_by_name(name)
|
643
|
-
|
641
|
+
app = input[:app]
|
644
642
|
url = input[:url, app.urls]
|
645
643
|
|
646
644
|
simple = url.sub(/^https?:\/\/(.*)\/?/i, '\1')
|
647
645
|
|
648
|
-
|
649
|
-
|
650
|
-
with_progress("Updating #{c(name, :name)}") do |s|
|
646
|
+
with_progress("Updating #{c(app.name, :name)}") do |s|
|
651
647
|
unless app.urls.delete(simple)
|
652
648
|
s.fail do
|
653
649
|
err "URL #{url} is not mapped to this application."
|
@@ -662,22 +658,14 @@ module VMC
|
|
662
658
|
|
663
659
|
desc "Show all environment variables set for an app"
|
664
660
|
group :apps, :info, :hidden => true
|
665
|
-
input :
|
666
|
-
:desc => "Application to inspect the environment of"
|
661
|
+
input :app, :argument => true,
|
662
|
+
:desc => "Application to inspect the environment of",
|
663
|
+
:from_given => by_name("app")
|
667
664
|
def env(input)
|
668
|
-
|
665
|
+
app = input[:app]
|
669
666
|
|
670
667
|
vars =
|
671
|
-
with_progress("Getting env for #{c(
|
672
|
-
app = client.app_by_name(appname)
|
673
|
-
|
674
|
-
unless app.exists?
|
675
|
-
s.fail do
|
676
|
-
err "Unknown application '#{appname}'"
|
677
|
-
return
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
668
|
+
with_progress("Getting env for #{c(app.name, :name)}") do |s|
|
681
669
|
app.env
|
682
670
|
end
|
683
671
|
|
@@ -693,20 +681,21 @@ module VMC
|
|
693
681
|
|
694
682
|
desc "Set an environment variable"
|
695
683
|
group :apps, :info, :hidden => true
|
684
|
+
input :app, :argument => true,
|
685
|
+
:desc => "Application to set the variable for",
|
686
|
+
:from_given => by_name("app")
|
696
687
|
input :name, :argument => true,
|
697
|
-
:desc => "Application to set the variable for"
|
698
|
-
input :var, :argument => true,
|
699
688
|
:desc => "Environment variable name"
|
700
689
|
input :value, :argument => :optional,
|
701
690
|
:desc => "Environment variable value"
|
702
691
|
input :restart, :type => :boolean, :default => true,
|
703
692
|
:desc => "Restart app after updating?"
|
704
693
|
def set_env(input)
|
705
|
-
|
706
|
-
name = input[:
|
694
|
+
app = input[:app]
|
695
|
+
name = input[:name]
|
707
696
|
|
708
697
|
if value = input[:value]
|
709
|
-
name = input[:
|
698
|
+
name = input[:name]
|
710
699
|
elsif name["="]
|
711
700
|
name, value = name.split("=")
|
712
701
|
end
|
@@ -715,16 +704,13 @@ module VMC
|
|
715
704
|
fail "Invalid variable name; must match #{VALID_ENV_VAR.inspect}"
|
716
705
|
end
|
717
706
|
|
718
|
-
app = client.app_by_name(appname)
|
719
|
-
fail "Unknown application '#{appname}'" unless app.exists?
|
720
|
-
|
721
707
|
with_progress("Updating #{c(app.name, :name)}") do
|
722
708
|
app.env[name] = value
|
723
709
|
app.update!
|
724
710
|
end
|
725
711
|
|
726
712
|
if app.started? && input[:restart]
|
727
|
-
invoke :restart, :
|
713
|
+
invoke :restart, :app => app
|
728
714
|
end
|
729
715
|
end
|
730
716
|
|
@@ -735,18 +721,16 @@ module VMC
|
|
735
721
|
|
736
722
|
desc "Remove an environment variable"
|
737
723
|
group :apps, :info, :hidden => true
|
724
|
+
input :app, :argument => true,
|
725
|
+
:desc => "Application to set the variable for",
|
726
|
+
:from_given => by_name("app")
|
738
727
|
input :name, :argument => true,
|
739
|
-
:desc => "Application to remove the variable from"
|
740
|
-
input :var, :argument => true,
|
741
728
|
:desc => "Environment variable name"
|
742
729
|
input :restart, :type => :boolean, :default => true,
|
743
730
|
:desc => "Restart app after updating?"
|
744
731
|
def delete_env(input)
|
745
|
-
|
746
|
-
name = input[:
|
747
|
-
|
748
|
-
app = client.app_by_name(appname)
|
749
|
-
fail "Unknown application '#{appname}'" unless app.exists?
|
732
|
+
app = input[:app]
|
733
|
+
name = input[:name]
|
750
734
|
|
751
735
|
with_progress("Updating #{c(app.name, :name)}") do
|
752
736
|
app.env.delete(name)
|
@@ -754,7 +738,7 @@ module VMC
|
|
754
738
|
end
|
755
739
|
|
756
740
|
if app.started? && input[:restart]
|
757
|
-
invoke :restart, :
|
741
|
+
invoke :restart, :app => app
|
758
742
|
end
|
759
743
|
end
|
760
744
|
|
@@ -814,7 +798,8 @@ module VMC
|
|
814
798
|
end
|
815
799
|
|
816
800
|
unless a.services.empty?
|
817
|
-
|
801
|
+
print " services: "
|
802
|
+
puts a.services.collect { |s| b(s.name) }.join(", ")
|
818
803
|
end
|
819
804
|
end
|
820
805
|
|
@@ -929,9 +914,9 @@ module VMC
|
|
929
914
|
orphaned = []
|
930
915
|
|
931
916
|
apps.each do |a|
|
932
|
-
a.services.each do |
|
933
|
-
if apps.none? { |x| x != a && x.services.include?(
|
934
|
-
orphaned <<
|
917
|
+
a.services.each do |i|
|
918
|
+
if apps.none? { |x| x != a && x.services.include?(i) }
|
919
|
+
orphaned << i
|
935
920
|
end
|
936
921
|
end
|
937
922
|
end
|
@@ -939,17 +924,18 @@ module VMC
|
|
939
924
|
orphaned
|
940
925
|
end
|
941
926
|
|
942
|
-
def delete_orphaned_services(
|
943
|
-
return if
|
927
|
+
def delete_orphaned_services(instances, orphaned)
|
928
|
+
return if instances.empty?
|
944
929
|
|
945
930
|
puts "" unless quiet?
|
946
931
|
|
947
|
-
|
932
|
+
instances.select { |i|
|
948
933
|
orphaned ||
|
949
|
-
ask("Delete orphaned service #{c(
|
950
|
-
|
934
|
+
ask("Delete orphaned service instance #{c(i.name, :name)}?",
|
935
|
+
:default => false)
|
936
|
+
}.each do |instance|
|
951
937
|
# TODO: splat
|
952
|
-
invoke :delete_service, :
|
938
|
+
invoke :delete_service, :instance => instance, :really => true
|
953
939
|
end
|
954
940
|
end
|
955
941
|
|
@@ -2,7 +2,21 @@ require "vmc/cli"
|
|
2
2
|
|
3
3
|
module VMC
|
4
4
|
class Service < CLI
|
5
|
-
|
5
|
+
def self.find_by_name(what)
|
6
|
+
proc { |name, choices|
|
7
|
+
choices.find { |c| c.name == name } ||
|
8
|
+
fail("Unknown #{what} '#{name}'")
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.by_name(what, obj = what)
|
13
|
+
proc { |name, *_|
|
14
|
+
client.send(:"#{obj}_by_name", name) ||
|
15
|
+
fail("Unknown #{what} '#{name}'")
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "List your service instances"
|
6
20
|
group :services
|
7
21
|
input :name, :desc => "Filter by name regexp"
|
8
22
|
input :app, :desc => "Filter by bound application regexp"
|
@@ -30,10 +44,6 @@ module VMC
|
|
30
44
|
services.select { |s| s.label == label }
|
31
45
|
}
|
32
46
|
|
33
|
-
plan_from_name = proc { |name, plans|
|
34
|
-
plans.find { |p| p.name == name }
|
35
|
-
}
|
36
|
-
|
37
47
|
desc "Create a service"
|
38
48
|
group :services, :manage
|
39
49
|
input(:service, :argument => true,
|
@@ -55,7 +65,7 @@ module VMC
|
|
55
65
|
ask "Name?", :default => "#{service.label}-#{random}"
|
56
66
|
}
|
57
67
|
input(:plan, :desc => "Service plan",
|
58
|
-
:from_given =>
|
68
|
+
:from_given => find_by_name("plan")) { |plans|
|
59
69
|
if d100 = plans.find { |p| p.name == "D100" }
|
60
70
|
d100
|
61
71
|
else
|
@@ -65,7 +75,8 @@ module VMC
|
|
65
75
|
end
|
66
76
|
}
|
67
77
|
input :provider, :desc => "Service provider"
|
68
|
-
input :
|
78
|
+
input :version, :desc => "Service version"
|
79
|
+
input :app, :alias => "--bind", :from_given => by_name("app"),
|
69
80
|
:desc => "Application to immediately bind to"
|
70
81
|
def create_service(input)
|
71
82
|
services = client.services
|
@@ -74,8 +85,13 @@ module VMC
|
|
74
85
|
services.reject! { |s| s.provider != input[:provider] }
|
75
86
|
end
|
76
87
|
|
88
|
+
if input[:version]
|
89
|
+
services.reject! { |s| s.version != input[:version] }
|
90
|
+
end
|
91
|
+
|
77
92
|
until services.size < 2
|
78
|
-
|
93
|
+
# cast to Array since it might be given as a Service with #invoke
|
94
|
+
services = Array(input[:service, services])
|
79
95
|
input.forget(:service)
|
80
96
|
end
|
81
97
|
|
@@ -103,61 +119,75 @@ module VMC
|
|
103
119
|
instance.create!
|
104
120
|
end
|
105
121
|
|
106
|
-
if app = input[:
|
107
|
-
invoke :bind_service, :
|
122
|
+
if app = input[:app]
|
123
|
+
invoke :bind_service, :instance => instance, :app => app
|
108
124
|
end
|
109
125
|
|
110
126
|
instance
|
111
127
|
end
|
112
128
|
|
113
129
|
|
114
|
-
desc "Bind a service to an application"
|
130
|
+
desc "Bind a service instance to an application"
|
115
131
|
group :services, :manage
|
116
|
-
input(:
|
117
|
-
:
|
118
|
-
|
132
|
+
input(:instance, :argument => true,
|
133
|
+
:from_given => by_name("instance", :service_instance),
|
134
|
+
:desc => "Service to bind") { |app|
|
135
|
+
instances = client.service_instances
|
136
|
+
fail "No service instances." if instances.empty?
|
137
|
+
|
138
|
+
ask "Which service instance?",
|
139
|
+
:choices => instances - app.services,
|
140
|
+
:display => proc(&:name)
|
119
141
|
}
|
120
142
|
input(:app, :argument => true,
|
121
|
-
:
|
122
|
-
|
143
|
+
:from_given => by_name("app"),
|
144
|
+
:desc => "Application to bind to") {
|
145
|
+
ask "Which application?", :choices => client.apps(2),
|
146
|
+
:display => proc(&:name)
|
123
147
|
}
|
124
148
|
def bind_service(input)
|
125
|
-
|
126
|
-
|
149
|
+
app = input[:app]
|
150
|
+
instance = input[:instance, app]
|
127
151
|
|
128
|
-
with_progress(
|
129
|
-
|
152
|
+
with_progress(
|
153
|
+
"Binding #{c(instance.name, :name)} to #{c(app.name, :name)}") do
|
154
|
+
app.bind(instance)
|
130
155
|
end
|
131
156
|
end
|
132
157
|
|
133
158
|
|
134
159
|
desc "Unbind a service from an application"
|
135
160
|
group :services, :manage
|
136
|
-
input(:
|
137
|
-
:
|
138
|
-
|
161
|
+
input(:instance, :argument => true,
|
162
|
+
:from_given => find_by_name("instance"),
|
163
|
+
:desc => "Service to bind") { |instances|
|
164
|
+
ask "Which service instance?", :choices => instances,
|
165
|
+
:display => proc(&:name)
|
139
166
|
}
|
140
167
|
input(:app, :argument => true,
|
141
|
-
:
|
142
|
-
|
168
|
+
:from_given => find_by_name("app"),
|
169
|
+
:desc => "Application to bind to") { |apps|
|
170
|
+
ask "Which application?", :choices => apps,
|
171
|
+
:display => proc(&:name)
|
143
172
|
}
|
144
173
|
def unbind_service(input)
|
145
|
-
|
146
|
-
|
147
|
-
app = client.app_by_name(appname)
|
148
|
-
name = input[:name, app.services]
|
174
|
+
app = input[:app, client.apps(2)]
|
175
|
+
instance = input[:instance, app.services]
|
149
176
|
|
150
|
-
with_progress(
|
151
|
-
|
177
|
+
with_progress(
|
178
|
+
"Unbinding #{c(instance.name, :name)} from #{c(app.name, :name)}") do
|
179
|
+
app.unbind(instance)
|
152
180
|
end
|
153
181
|
end
|
154
182
|
|
155
183
|
|
156
184
|
desc "Delete a service"
|
157
185
|
group :services, :manage
|
158
|
-
input(:
|
159
|
-
:
|
160
|
-
|
186
|
+
input(:instance, :argument => true,
|
187
|
+
:from_given => find_by_name("instance"),
|
188
|
+
:desc => "Service to bind") { |instances|
|
189
|
+
ask "Which service instance?", :choices => instances,
|
190
|
+
:display => proc(&:name)
|
161
191
|
}
|
162
192
|
input(:really, :type => :boolean, :forget => true) { |name, color|
|
163
193
|
force? || ask("Really delete #{c(name, color)}?", :default => false)
|
@@ -167,8 +197,8 @@ module VMC
|
|
167
197
|
if input[:all]
|
168
198
|
return unless input[:really, "ALL SERVICES", :bad]
|
169
199
|
|
170
|
-
|
171
|
-
|
200
|
+
client.service_instances.each do |i|
|
201
|
+
invoke :delete_service, :instance => i, :really => true
|
172
202
|
end
|
173
203
|
|
174
204
|
return
|
@@ -177,13 +207,21 @@ module VMC
|
|
177
207
|
instances = client.service_instances
|
178
208
|
fail "No services." if instances.empty?
|
179
209
|
|
180
|
-
|
181
|
-
|
210
|
+
instance = input[:instance, instances]
|
211
|
+
|
212
|
+
return unless input[:really, instance.name, :name]
|
182
213
|
|
183
|
-
|
214
|
+
with_progress("Deleting #{c(instance.name, :name)}") do |s|
|
215
|
+
bindings = instance.service_bindings
|
184
216
|
|
185
|
-
|
186
|
-
|
217
|
+
if bindings.empty?
|
218
|
+
instance.delete!
|
219
|
+
else
|
220
|
+
s.skip do
|
221
|
+
apps = bindings.collect(&:app).collect { |a| b(a.name) }
|
222
|
+
err "Service instance is bound to #{human_list(apps)}."
|
223
|
+
end
|
224
|
+
end
|
187
225
|
end
|
188
226
|
end
|
189
227
|
|
@@ -229,5 +267,16 @@ module VMC
|
|
229
267
|
puts " description: #{plan.description}"
|
230
268
|
end
|
231
269
|
end
|
270
|
+
|
271
|
+
def human_list(xs)
|
272
|
+
if xs.size == 1
|
273
|
+
xs.first
|
274
|
+
elsif xs.size == 2
|
275
|
+
"#{xs.first} and #{xs.last}"
|
276
|
+
else
|
277
|
+
last = xs.pop
|
278
|
+
xs.join(", ") + ", and #{last}"
|
279
|
+
end
|
280
|
+
end
|
232
281
|
end
|
233
282
|
end
|
data/vmc-ng/lib/vmc/cli/start.rb
CHANGED
@@ -146,11 +146,6 @@ module VMC
|
|
146
146
|
with_progress("Setting target to #{display}") do
|
147
147
|
set_target(target)
|
148
148
|
end
|
149
|
-
|
150
|
-
unless quiet?
|
151
|
-
puts ""
|
152
|
-
display_org_and_space
|
153
|
-
end
|
154
149
|
end
|
155
150
|
|
156
151
|
return unless v2? && client.logged_in?
|
@@ -428,7 +423,7 @@ module VMC
|
|
428
423
|
if !input[:interactive] && spaces.size == 1 && !input.given?(:space)
|
429
424
|
space = spaces.first
|
430
425
|
else
|
431
|
-
puts "" if changed_org
|
426
|
+
puts "" if input[:interactive] && changed_org
|
432
427
|
space = input[:space, spaces.sort_by(&:name)]
|
433
428
|
end
|
434
429
|
|
data/vmc-ng/lib/vmc/cli.rb
CHANGED
@@ -92,6 +92,7 @@ module VMC
|
|
92
92
|
rescue Mothership::Error
|
93
93
|
raise
|
94
94
|
rescue UserError => e
|
95
|
+
log_error(e)
|
95
96
|
err e.message
|
96
97
|
rescue CFoundry::Denied => e
|
97
98
|
if !$vmc_asked_auth && e.error_code == 200
|
@@ -290,13 +291,17 @@ module VMC
|
|
290
291
|
@@client.proxy = option(:proxy)
|
291
292
|
@@client.trace = option(:trace)
|
292
293
|
|
293
|
-
info
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
294
|
+
unless info.key? :version
|
295
|
+
info[:version] =
|
296
|
+
case @@client
|
297
|
+
when CFoundry::V2::Client
|
298
|
+
2
|
299
|
+
else
|
300
|
+
1
|
301
|
+
end
|
302
|
+
|
303
|
+
save_target_info(info)
|
304
|
+
end
|
300
305
|
|
301
306
|
if org = info[:organization]
|
302
307
|
@@client.current_organization = @@client.organization(org)
|
@@ -306,8 +311,6 @@ module VMC
|
|
306
311
|
@@client.current_space = @@client.space(space)
|
307
312
|
end
|
308
313
|
|
309
|
-
save_target_info(info)
|
310
|
-
|
311
314
|
@@client
|
312
315
|
end
|
313
316
|
|
data/vmc-ng/lib/vmc/version.rb
CHANGED
@@ -6,6 +6,16 @@ describe "Start#target" do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "switching target url" do
|
9
|
+
before(:all) do
|
10
|
+
@old_target = File.read(File.expand_path(VMC::TARGET_FILE))
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
File.open(File.expand_path(VMC::TARGET_FILE), "w") do |io|
|
15
|
+
io.print @old_target
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
9
19
|
before(:each) do
|
10
20
|
@old_client = client
|
11
21
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 62196431
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.4.0.beta.
|
11
|
+
- 22
|
12
|
+
version: 0.4.0.beta.22
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- VMware
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2012-07-
|
20
|
+
date: 2012-07-23 00:00:00 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: json_pure
|
@@ -249,12 +249,12 @@ dependencies:
|
|
249
249
|
requirements:
|
250
250
|
- - ~>
|
251
251
|
- !ruby/object:Gem::Version
|
252
|
-
hash:
|
252
|
+
hash: 1
|
253
253
|
segments:
|
254
254
|
- 0
|
255
255
|
- 3
|
256
|
-
-
|
257
|
-
version: 0.3.
|
256
|
+
- 9
|
257
|
+
version: 0.3.9
|
258
258
|
type: :runtime
|
259
259
|
version_requirements: *id014
|
260
260
|
- !ruby/object:Gem::Dependency
|
@@ -265,12 +265,12 @@ dependencies:
|
|
265
265
|
requirements:
|
266
266
|
- - ~>
|
267
267
|
- !ruby/object:Gem::Version
|
268
|
-
hash:
|
268
|
+
hash: 11
|
269
269
|
segments:
|
270
270
|
- 0
|
271
271
|
- 0
|
272
|
-
-
|
273
|
-
version: 0.0.
|
272
|
+
- 10
|
273
|
+
version: 0.0.10
|
274
274
|
type: :runtime
|
275
275
|
version_requirements: *id015
|
276
276
|
- !ruby/object:Gem::Dependency
|
@@ -281,12 +281,12 @@ dependencies:
|
|
281
281
|
requirements:
|
282
282
|
- - ~>
|
283
283
|
- !ruby/object:Gem::Version
|
284
|
-
hash:
|
284
|
+
hash: 15
|
285
285
|
segments:
|
286
286
|
- 0
|
287
|
-
-
|
288
|
-
-
|
289
|
-
version: 0.
|
287
|
+
- 4
|
288
|
+
- 0
|
289
|
+
version: 0.4.0
|
290
290
|
type: :runtime
|
291
291
|
version_requirements: *id016
|
292
292
|
- !ruby/object:Gem::Dependency
|