vmc 0.4.0.beta.21 → 0.4.0.beta.22
Sign up to get free protection for your applications and to get access to all the features.
- 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
|