vmc 0.5.0.beta.6 → 0.5.0.beta.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vmc/cli.rb +11 -0
- data/lib/vmc/cli/app/base.rb +2 -2
- data/lib/vmc/cli/app/instances.rb +4 -2
- data/lib/vmc/cli/app/push.rb +2 -1
- data/lib/vmc/cli/app/push/create.rb +5 -1
- data/lib/vmc/cli/app/push/interactions.rb +3 -1
- data/lib/vmc/cli/app/stats.rb +1 -1
- data/lib/vmc/cli/start/info.rb +2 -2
- data/lib/vmc/plugin.rb +3 -2
- data/lib/vmc/version.rb +1 -1
- data/spec/support/feature_helpers.rb +1 -0
- data/spec/vmc/cli/app/base_spec.rb +17 -0
- data/spec/vmc/cli/app/delete_spec.rb +16 -15
- data/spec/vmc/cli/app/instances_spec.rb +70 -0
- data/spec/vmc/cli/app/push/create_spec.rb +66 -20
- data/spec/vmc/cli/app/push_spec.rb +17 -17
- data/spec/vmc/cli/app/rename_spec.rb +4 -4
- data/spec/vmc/cli/app/stats_spec.rb +66 -0
- data/spec/vmc/cli/organization/orgs_spec.rb +5 -4
- data/spec/vmc/cli/organization/rename_spec.rb +3 -3
- data/spec/vmc/cli/route/delete_route_spec.rb +3 -3
- data/spec/vmc/cli/service/rename_spec.rb +4 -4
- data/spec/vmc/cli/space/rename_spec.rb +4 -4
- data/spec/vmc/cli/space/spaces_spec.rb +5 -5
- data/spec/vmc/cli/start/info_spec.rb +127 -1
- data/spec/vmc/cli/start/register_spec.rb +1 -1
- data/spec/vmc/cli/user/passwd_spec.rb +6 -2
- data/spec/vmc/cli_spec.rb +42 -4
- data/spec/vmc/detect_spec.rb +2 -2
- metadata +60 -69
data/lib/vmc/cli.rb
CHANGED
@@ -158,6 +158,17 @@ module VMC
|
|
158
158
|
f.puts msg
|
159
159
|
f.puts ""
|
160
160
|
|
161
|
+
if e.respond_to?(:request_trace)
|
162
|
+
f.puts "<<<"
|
163
|
+
f.puts e.request_trace
|
164
|
+
end
|
165
|
+
|
166
|
+
if e.respond_to?(:response_trace)
|
167
|
+
f.puts e.response_trace
|
168
|
+
f.puts ">>>"
|
169
|
+
f.puts ""
|
170
|
+
end
|
171
|
+
|
161
172
|
vmc_dir = File.expand_path("../../../..", __FILE__) + "/"
|
162
173
|
e.backtrace.each do |loc|
|
163
174
|
if loc =~ /\/gems\//
|
data/lib/vmc/cli/app/base.rb
CHANGED
@@ -52,10 +52,10 @@ module VMC
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def human_size(num, precision = 1)
|
55
|
-
sizes =
|
55
|
+
sizes = %w(G M K)
|
56
56
|
sizes.each.with_index do |suf, i|
|
57
57
|
pow = sizes.size - i
|
58
|
-
unit = 1024 ** pow
|
58
|
+
unit = 1024.0 ** pow
|
59
59
|
if num >= unit
|
60
60
|
return format("%.#{precision}f%s", num / unit, suf)
|
61
61
|
end
|
@@ -19,7 +19,7 @@ module VMC::App
|
|
19
19
|
|
20
20
|
line unless quiet?
|
21
21
|
|
22
|
-
spaced(instances) do |i|
|
22
|
+
spaced(instances.sort { |a, b| a.id.to_i <=> b.id.to_i }) do |i|
|
23
23
|
if quiet?
|
24
24
|
line i.id
|
25
25
|
else
|
@@ -29,9 +29,11 @@ module VMC::App
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
private
|
33
|
+
|
32
34
|
def display_instance(i)
|
33
35
|
start_line "instance #{c("\##{i.id}", :instance)}: "
|
34
|
-
puts "#{b(c(i.state.downcase, state_color(i.state)))}
|
36
|
+
puts "#{b(c(i.state.downcase, state_color(i.state)))}"
|
35
37
|
|
36
38
|
indented do
|
37
39
|
if s = i.since
|
data/lib/vmc/cli/app/push.rb
CHANGED
@@ -17,7 +17,7 @@ module VMC::App
|
|
17
17
|
input :instances, :desc => "Number of instances to run", :type => :integer
|
18
18
|
input :framework, :desc => "Framework to use", :from_given => by_name(:framework)
|
19
19
|
input :runtime, :desc => "Runtime to use", :from_given => by_name(:runtime)
|
20
|
-
input :command, :desc => "Startup command
|
20
|
+
input :command, :desc => "Startup command"
|
21
21
|
input :plan, :desc => "Application plan", :default => "D100"
|
22
22
|
input :start, :desc => "Start app after pushing?", :default => true
|
23
23
|
input :restart, :desc => "Restart app after updating?", :default => true
|
@@ -26,6 +26,7 @@ module VMC::App
|
|
26
26
|
input :bind_services, :desc => "Interactively bind services?",
|
27
27
|
:type => :boolean, :default => proc { force? ? false : interact }
|
28
28
|
interactions PushInteractions
|
29
|
+
|
29
30
|
def push
|
30
31
|
name = input[:name]
|
31
32
|
path = File.expand_path(input[:path])
|
@@ -12,7 +12,7 @@ module VMC::App
|
|
12
12
|
inputs[:space] = client.current_space if client.current_space
|
13
13
|
inputs[:production] = !!(input[:plan] =~ /^p/i) if v2?
|
14
14
|
inputs[:framework] = framework = determine_framework
|
15
|
-
inputs[:command] = input[:command] if framework
|
15
|
+
inputs[:command] = input[:command] if can_have_custom_start_command?(framework)
|
16
16
|
inputs[:runtime] = determine_runtime(framework)
|
17
17
|
|
18
18
|
human_mb = human_mb(detector.suggested_memory(framework) || 64)
|
@@ -114,6 +114,10 @@ module VMC::App
|
|
114
114
|
|
115
115
|
private
|
116
116
|
|
117
|
+
def can_have_custom_start_command?(framework)
|
118
|
+
%w(standalone buildpack).include?(framework.name)
|
119
|
+
end
|
120
|
+
|
117
121
|
def all_instances
|
118
122
|
@all_instances ||= client.service_instances
|
119
123
|
end
|
data/lib/vmc/cli/app/stats.rb
CHANGED
@@ -37,7 +37,7 @@ module VMC::App
|
|
37
37
|
if usage
|
38
38
|
[ idx,
|
39
39
|
"#{percentage(usage[:cpu])} of #{b(stats[:cores])} cores",
|
40
|
-
"#{usage(usage[:mem]
|
40
|
+
"#{usage(usage[:mem], stats[:mem_quota])}",
|
41
41
|
"#{usage(usage[:disk], stats[:disk_quota])}"
|
42
42
|
]
|
43
43
|
else
|
data/lib/vmc/cli/start/info.rb
CHANGED
data/lib/vmc/plugin.rb
CHANGED
@@ -21,8 +21,9 @@ module VMC
|
|
21
21
|
|
22
22
|
enabled = Set.new(matching.collect(&:name))
|
23
23
|
|
24
|
-
Gem.loaded_specs["vmc"]
|
25
|
-
|
24
|
+
vmc_gems = Gem.loaded_specs["vmc"]
|
25
|
+
((vmc_gems && vmc_gems.dependencies) || Gem.loaded_specs.values).each do |dep|
|
26
|
+
if dep.name =~ /vmc-plugin/
|
26
27
|
require "#{dep.name}/plugin"
|
27
28
|
enabled.delete dep.name
|
28
29
|
end
|
data/lib/vmc/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "vmc/cli/app/base"
|
3
|
+
|
4
|
+
describe VMC::App::Base do
|
5
|
+
describe '#human_size' do
|
6
|
+
let(:base) { VMC::App::Base.new }
|
7
|
+
|
8
|
+
it { base.human_size(1_023).should == "1023.0B" }
|
9
|
+
it { base.human_size(1_024).should == "1.0K" }
|
10
|
+
it { base.human_size(1_024 * 1_024).should == "1.0M" }
|
11
|
+
it { base.human_size(1_024 * 1_024 * 1.5).should == "1.5M" }
|
12
|
+
it { base.human_size(1_024 * 1_024 * 1_024).should == "1.0G" }
|
13
|
+
it { base.human_size(1_024 * 1_024 * 1_024 * 1.5).should == "1.5G" }
|
14
|
+
it { base.human_size(1_024 * 1_024 * 1_024 * 1.234, 3).should == "1.234G" }
|
15
|
+
it { base.human_size(31395840).should == "29.9M" } # tests against floating point errors
|
16
|
+
end
|
17
|
+
end
|
@@ -5,7 +5,7 @@ describe VMC::App::Delete do
|
|
5
5
|
let(:global) { { :color => false, :quiet => true } }
|
6
6
|
let(:inputs) { {} }
|
7
7
|
let(:given) { {} }
|
8
|
-
let(:client) {
|
8
|
+
let(:client) { fake_client }
|
9
9
|
let(:app) {}
|
10
10
|
let(:new_name) { "some-new-name" }
|
11
11
|
|
@@ -49,28 +49,25 @@ describe VMC::App::Delete do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
context 'when there are apps' do
|
52
|
-
let(:client) {
|
52
|
+
let(:client) { fake_client(:apps => apps) }
|
53
53
|
let(:apps) { [basic_app, app_with_orphans, app_without_orphans] }
|
54
|
-
let(:service_1) {
|
55
|
-
let(:service_2) {
|
56
|
-
let(:basic_app) {
|
54
|
+
let(:service_1) { fake :service_instance }
|
55
|
+
let(:service_2) { fake :service_instance }
|
56
|
+
let(:basic_app) { fake(:app, :name => "basic_app") }
|
57
57
|
let(:app_with_orphans) {
|
58
|
-
|
58
|
+
fake :app,
|
59
59
|
:name => "app_with_orphans",
|
60
60
|
:service_bindings => [
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
:service_instance => service_2)
|
65
|
-
])
|
61
|
+
fake(:service_binding, :service_instance => service_1),
|
62
|
+
fake(:service_binding, :service_instance => service_2)
|
63
|
+
]
|
66
64
|
}
|
67
65
|
let(:app_without_orphans) {
|
68
|
-
|
66
|
+
fake :app,
|
69
67
|
:name => "app_without_orphans",
|
70
68
|
:service_bindings => [
|
71
|
-
|
72
|
-
|
73
|
-
])
|
69
|
+
fake(:service_binding, :service_instance => service_1)
|
70
|
+
]
|
74
71
|
}
|
75
72
|
|
76
73
|
context 'and no app is given' do
|
@@ -125,6 +122,8 @@ describe VMC::App::Delete do
|
|
125
122
|
stub_ask("Really delete #{deleted_app.name}?", anything) { true }
|
126
123
|
stub(deleted_app).delete!
|
127
124
|
|
125
|
+
stub(service_2).invalidate!
|
126
|
+
|
128
127
|
mock_ask("Delete orphaned service #{service_2.name}?", anything) { true }
|
129
128
|
|
130
129
|
any_instance_of(VMC::App::Delete) do |del|
|
@@ -141,6 +140,8 @@ describe VMC::App::Delete do
|
|
141
140
|
stub_ask("Really delete #{deleted_app.name}?", anything) { false }
|
142
141
|
dont_allow(deleted_app).delete!
|
143
142
|
|
143
|
+
stub(service_2).invalidate!
|
144
|
+
|
144
145
|
dont_allow_ask("Delete orphaned service #{service_2.name}?")
|
145
146
|
|
146
147
|
any_instance_of(VMC::App::Delete) do |del|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe VMC::App::Stats do
|
5
|
+
let(:global) { { :color => false } }
|
6
|
+
let(:inputs) { {:app => apps[0]} }
|
7
|
+
let(:given) { {} }
|
8
|
+
let(:output) { StringIO.new }
|
9
|
+
let(:client) { fake_client(:apps => apps) }
|
10
|
+
let(:apps) { [fake(:app, :name => "basic_app")] }
|
11
|
+
let(:time) { Time.local(2012,11,1,2,30)}
|
12
|
+
|
13
|
+
before do
|
14
|
+
any_instance_of(VMC::CLI) do |cli|
|
15
|
+
stub(cli).client { client }
|
16
|
+
stub(cli).precondition { nil }
|
17
|
+
end
|
18
|
+
stub(client).base.stub!.instances(anything) do
|
19
|
+
{
|
20
|
+
"12" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
|
21
|
+
"1" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
|
22
|
+
"2" => {:state => "STARTED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
subject do
|
28
|
+
with_output_to output do
|
29
|
+
Mothership.new.invoke(:instances, inputs, given, global)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'metadata' do
|
34
|
+
let(:command) { Mothership.commands[:instances] }
|
35
|
+
|
36
|
+
describe 'command' do
|
37
|
+
subject { command }
|
38
|
+
its(:description) { should eq "List an app's instances" }
|
39
|
+
it { expect(Mothership::Help.group(:apps, :info)).to include(subject) }
|
40
|
+
end
|
41
|
+
|
42
|
+
include_examples 'inputs must have descriptions'
|
43
|
+
|
44
|
+
describe 'arguments' do
|
45
|
+
subject { command.arguments }
|
46
|
+
it 'has no arguments' do
|
47
|
+
should eq([{:type=>:splat, :value=>nil, :name=>:apps}])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'prints out the instances in the correct order' do
|
53
|
+
subject
|
54
|
+
|
55
|
+
output.rewind
|
56
|
+
expect(output.string).to match /.*instance \#1.*instance \#2.*instance \#12.*/m
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'prints out one of the instances correctly' do
|
60
|
+
subject
|
61
|
+
|
62
|
+
output.rewind
|
63
|
+
expect(output.string).to include <<-OUT.strip_heredoc
|
64
|
+
instance #2: started
|
65
|
+
started: #{time.strftime("%F %r")}
|
66
|
+
debugger: port bar at foo
|
67
|
+
console: port qux at baz
|
68
|
+
OUT
|
69
|
+
end
|
70
|
+
end
|
@@ -5,19 +5,20 @@ describe VMC::App::Create do
|
|
5
5
|
let(:given) { {} }
|
6
6
|
let(:global) { { :color => false, :quiet => true } }
|
7
7
|
|
8
|
-
let(:frameworks) {
|
9
|
-
let(:framework) {
|
10
|
-
let(:
|
8
|
+
let(:frameworks) { fake_list(:framework, 3) }
|
9
|
+
let(:framework) { buildpack }
|
10
|
+
let(:buildpack) { fake(:framework, :name => "buildpack") }
|
11
|
+
let(:standalone) { fake(:framework, :name => "standalone") }
|
11
12
|
|
12
|
-
let(:runtimes) {
|
13
|
+
let(:runtimes) { fake_list(:runtime, 3) }
|
13
14
|
let(:runtime) { runtimes.first }
|
14
15
|
|
15
|
-
let(:service_instances) {
|
16
|
+
let(:service_instances) { fake_list(:service_instance, 5) }
|
16
17
|
|
17
18
|
let(:client) do
|
18
|
-
|
19
|
-
:
|
20
|
-
:
|
19
|
+
fake_client(
|
20
|
+
:frameworks => frameworks,
|
21
|
+
:runtimes => runtimes,
|
21
22
|
:service_instances => service_instances)
|
22
23
|
end
|
23
24
|
|
@@ -44,7 +45,8 @@ describe VMC::App::Create do
|
|
44
45
|
:plan => "p100",
|
45
46
|
:framework => framework,
|
46
47
|
:runtime => runtime,
|
47
|
-
:memory => "1G"
|
48
|
+
:memory => "1G",
|
49
|
+
:command => "ruby main.rb"
|
48
50
|
}
|
49
51
|
end
|
50
52
|
|
@@ -54,7 +56,7 @@ describe VMC::App::Create do
|
|
54
56
|
its([:space]) { should eq client.current_space }
|
55
57
|
its([:production]) { should eq true }
|
56
58
|
its([:framework]) { should eq framework }
|
57
|
-
its([:command]) { should eq
|
59
|
+
its([:command]) { should eq "ruby main.rb" }
|
58
60
|
its([:runtime]) { should eq runtime }
|
59
61
|
its([:memory]) { should eq 1024 }
|
60
62
|
end
|
@@ -81,10 +83,54 @@ describe VMC::App::Create do
|
|
81
83
|
subject
|
82
84
|
end
|
83
85
|
|
84
|
-
|
85
|
-
inputs
|
86
|
-
|
87
|
-
|
86
|
+
context 'when the command is not given' do
|
87
|
+
before { inputs.delete(:command) }
|
88
|
+
|
89
|
+
shared_examples 'an app that can have a custom start command' do
|
90
|
+
it 'should ask if there is a custom start command' do
|
91
|
+
mock_ask("Use custom startup command?", :default => false) { false }
|
92
|
+
subject
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when the user answers "yes" to the custom start command' do
|
96
|
+
before { stub_ask("Use custom startup command?", :default => false) { true } }
|
97
|
+
|
98
|
+
it 'should ask for the startup command' do
|
99
|
+
mock_ask("Startup command") { "foo bar.com" }
|
100
|
+
subject[:command].should eq "foo bar.com"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when the user answers "no" to the custom start command' do
|
105
|
+
before { stub_ask("Use custom startup command?", :default => false) { false } }
|
106
|
+
|
107
|
+
it 'should not ask for the startup command' do
|
108
|
+
dont_allow_ask("Startup command")
|
109
|
+
subject
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when the framework is "buildpack"' do
|
115
|
+
let(:framework) { buildpack }
|
116
|
+
|
117
|
+
include_examples 'an app that can have a custom start command'
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when the framework is "standalone"' do
|
121
|
+
let(:framework) { standalone }
|
122
|
+
|
123
|
+
include_examples 'an app that can have a custom start command'
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'when the framework is neither "buildpack" nor "standalone"' do
|
127
|
+
let(:framework) { fake(:framework, :name => "java") }
|
128
|
+
|
129
|
+
it 'does not ask if there is a custom start command' do
|
130
|
+
dont_allow_ask("Startup command")
|
131
|
+
subject
|
132
|
+
end
|
133
|
+
end
|
88
134
|
end
|
89
135
|
|
90
136
|
it 'should ask for the runtime' do
|
@@ -225,7 +271,7 @@ describe VMC::App::Create do
|
|
225
271
|
describe '#create_app' do
|
226
272
|
before { dont_allow_ask }
|
227
273
|
|
228
|
-
let(:app) {
|
274
|
+
let(:app) { fake(:app, :guid => nil) }
|
229
275
|
|
230
276
|
let(:attributes) do
|
231
277
|
{ :name => "some-app",
|
@@ -255,7 +301,7 @@ describe VMC::App::Create do
|
|
255
301
|
end
|
256
302
|
|
257
303
|
describe '#map_url' do
|
258
|
-
let(:app) {
|
304
|
+
let(:app) { fake(:app) }
|
259
305
|
let(:url_choices) { %W(#{app.name}.foo-cloud.com) }
|
260
306
|
|
261
307
|
before do
|
@@ -291,7 +337,7 @@ describe VMC::App::Create do
|
|
291
337
|
mock_ask('URL', anything) { url_choices.first }
|
292
338
|
|
293
339
|
mock(create).invoke(:map, :app => app, :url => url_choices.first) do
|
294
|
-
raise CFoundry::RouteHostTaken.new(
|
340
|
+
raise CFoundry::RouteHostTaken.new(nil, nil, "foo", 1234)
|
295
341
|
end
|
296
342
|
end
|
297
343
|
|
@@ -319,7 +365,7 @@ describe VMC::App::Create do
|
|
319
365
|
end
|
320
366
|
|
321
367
|
describe '#create_services' do
|
322
|
-
let(:app) {
|
368
|
+
let(:app) { fake(:app) }
|
323
369
|
subject { create.create_services(app) }
|
324
370
|
|
325
371
|
context 'when forcing' do
|
@@ -365,7 +411,7 @@ describe VMC::App::Create do
|
|
365
411
|
end
|
366
412
|
|
367
413
|
describe '#bind_services' do
|
368
|
-
let(:app) {
|
414
|
+
let(:app) { fake(:app) }
|
369
415
|
|
370
416
|
subject { create.bind_services(app) }
|
371
417
|
|
@@ -437,7 +483,7 @@ describe VMC::App::Create do
|
|
437
483
|
end
|
438
484
|
|
439
485
|
describe '#start_app' do
|
440
|
-
let(:app) {
|
486
|
+
let(:app) { fake(:app) }
|
441
487
|
subject { create.start_app(app) }
|
442
488
|
|
443
489
|
context 'when the start flag is provided' do
|