vmc 0.5.0.beta.6 → 0.5.0.beta.7
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/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
|