vmc 0.4.0.beta.30 → 0.4.0.beta.31

Sign up to get free protection for your applications and to get access to all the features.
@@ -70,6 +70,10 @@ module VMC
70
70
  end
71
71
 
72
72
  def precondition
73
+ unless File.exists? target_file
74
+ fail "Please select a target with 'vmc target'."
75
+ end
76
+
73
77
  unless client.logged_in?
74
78
  fail "Please log in with 'vmc login'."
75
79
  end
@@ -151,7 +151,11 @@ module VMC
151
151
 
152
152
  if exists = client.app_by_name(name)
153
153
  upload_app(exists, path)
154
- invoke :restart, :app => exists if input[:restart]
154
+
155
+ if input[:restart] && exists.started?
156
+ invoke :restart, :app => exists
157
+ end
158
+
155
159
  return
156
160
  end
157
161
 
@@ -737,6 +741,7 @@ module VMC
737
741
 
738
742
 
739
743
  desc "DEPRECATED. Use 'push' instead."
744
+ input :app, :argument => :optional
740
745
  def update(input)
741
746
  fail "The 'update' command is no longer needed; use 'push' instead."
742
747
  end
@@ -795,10 +800,6 @@ module VMC
795
800
  end
796
801
 
797
802
  def upload_app(app, path)
798
- if v2?
799
- fail "V2 API currently does not support uploading or starting apps."
800
- end
801
-
802
803
  with_progress("Uploading #{c(app.name, :name)}") do
803
804
  app.upload(path)
804
805
  end
@@ -10,11 +10,16 @@ module VMC
10
10
 
11
11
  def self.load_all
12
12
  # auto-load gems with 'vmc-plugin' in their name
13
- enabled =
14
- Set.new(
15
- Gem::Specification.find_all { |s|
13
+ matching =
14
+ if Gem::Specification.respond_to? :find_all
15
+ Gem::Specification.find_all do |s|
16
16
  s.name =~ /vmc-plugin/
17
- }.collect(&:name))
17
+ end
18
+ else
19
+ Gem.source_index.find_name(/vmc-plugin/)
20
+ end
21
+
22
+ enabled = Set.new(matching.collect(&:name))
18
23
 
19
24
  # allow explicit enabling/disabling of gems via config
20
25
  plugins = File.expand_path(VMC::PLUGINS_FILE)
@@ -1,3 +1,3 @@
1
1
  module VMC
2
- VERSION = "0.4.0.beta.30"
2
+ VERSION = "0.4.0.beta.31"
3
3
  end
@@ -3,16 +3,18 @@ require "./helpers"
3
3
  describe "App#push" do
4
4
  it "pushes interactively" do
5
5
  name = "app-#{random_str}"
6
- instances = rand(3) + 1
7
- framework = sample(client.frameworks)
8
- runtime = sample(client.runtimes)
6
+ instances = 1 # rand(3) + 1
7
+ framework = client.framework_by_name("sinatra")
8
+ runtime = client.runtime_by_name("ruby19")
9
9
  url = "#{name}.fakecloud.com"
10
- memory = sample([64, 128, 256, 512])
10
+ memory = 256 # sample([64, 128, 256, 512])
11
11
 
12
12
  client.app_by_name(name).should_not be
13
13
 
14
+ hello_sinatra = File.expand_path("../../assets/hello-sinatra", __FILE__)
15
+
14
16
  begin
15
- running(:push) do
17
+ running(:push, :path => hello_sinatra) do
16
18
  asks("Name")
17
19
  given(name)
18
20
  has_input(:name, name)
@@ -37,6 +39,8 @@ describe "App#push" do
37
39
  given("#{memory}M")
38
40
  has_input(:memory, "#{memory}M")
39
41
 
42
+ does("Creating #{name}")
43
+
40
44
  asks("Create services for application?")
41
45
  given("n")
42
46
  has_input(:create_instances, false)
@@ -44,16 +48,13 @@ describe "App#push" do
44
48
  asks("Bind other services to application?")
45
49
  given("n")
46
50
  has_input(:bind_instances, false)
51
+
52
+ does("Uploading #{name}")
53
+ does("Starting #{name}")
47
54
  end
48
- rescue VMC::UserError => e
49
- unless e.to_s == "V2 API currently does not support uploading or starting apps."
50
- raise
51
- end
52
- end
53
55
 
54
- app = client.app_by_name(name)
56
+ app = client.app_by_name(name)
55
57
 
56
- begin
57
58
  app.should be
58
59
  app.name.should == name
59
60
  app.instances.should == instances
@@ -62,7 +63,9 @@ describe "App#push" do
62
63
  #app.url.should == url # TODO v2
63
64
  app.memory.should == memory
64
65
  ensure
65
- app.delete!
66
+ if created = client.app_by_name(name)
67
+ created.delete!
68
+ end
66
69
  end
67
70
  end
68
71
  end
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gem "sinatra"
@@ -0,0 +1,5 @@
1
+ require "sinatra"
2
+
3
+ get "/" do
4
+ "Sup, world? Ruby #{RUBY_VERSION}, Gem #{Gem::VERSION}"
5
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ applications:
3
+ .:
4
+ name: hello-sinatra
5
+ instances: 2
6
+ framework: sinatra
7
+ memory: 128M
8
+ url: ${name}-suraci.${target-base}
9
+ runtime: ruby19
@@ -116,6 +116,26 @@ class EventLog
116
116
  @queue << GotInput.new(name, val)
117
117
  end
118
118
 
119
+ def raised(exception)
120
+ @queue << Raised.new(exception)
121
+ end
122
+
123
+ def did(message)
124
+ @queue << Did.new(message)
125
+ end
126
+
127
+ def skipped(message)
128
+ @queue << Skipped.new(message)
129
+ end
130
+
131
+ def failed_to(message)
132
+ @queue << FailedTo.new(message)
133
+ end
134
+
135
+ def gave_up(message)
136
+ @queue << GaveUp.new(message)
137
+ end
138
+
119
139
 
120
140
  class Printed
121
141
  attr_reader :line
@@ -154,4 +174,85 @@ class EventLog
154
174
  "<GotInput #@name '#@value'>"
155
175
  end
156
176
  end
177
+
178
+ class Raised
179
+ attr_reader :exception
180
+
181
+ def initialize(exception)
182
+ @exception = exception
183
+ end
184
+
185
+ def to_s
186
+ "<Raised #{@exception.class} '#@exception'>"
187
+ end
188
+ end
189
+
190
+ class Progress
191
+ attr_reader :message
192
+
193
+ def initialize(message)
194
+ @message = message
195
+ end
196
+
197
+ def ==(other)
198
+ other.is_a?(self.class) &&
199
+ @message == other.message
200
+ end
201
+ end
202
+
203
+ class Did < Progress
204
+ def to_s
205
+ "<Did '#@message'>"
206
+ end
207
+
208
+ def report
209
+ "do '#@message'"
210
+ end
211
+
212
+ def report_past
213
+ "did '#@message'"
214
+ end
215
+ end
216
+
217
+ class Skipped < Progress
218
+ def to_s
219
+ "<Skipped '#@message'>"
220
+ end
221
+
222
+ def report
223
+ "skip '#@message'"
224
+ end
225
+
226
+ def report_past
227
+ "skipped '#@message'"
228
+ end
229
+ end
230
+
231
+ class FailedTo < Progress
232
+ def to_s
233
+ "<FailedTo '#@message'>"
234
+ end
235
+
236
+ def report
237
+ "fail to '#@message'"
238
+ end
239
+
240
+ def report_past
241
+ "failed to '#@message'"
242
+ end
243
+ end
244
+
245
+ class GaveUp < Progress
246
+ def to_s
247
+ "<GaveUp '#@message'>"
248
+ end
249
+
250
+ def report
251
+ "give up on '#@message'"
252
+ end
253
+
254
+ def report_past
255
+ "gave up on '#@message'"
256
+ end
257
+ end
157
258
  end
@@ -116,7 +116,7 @@ stderr:
116
116
  EOF
117
117
  end
118
118
  rescue => e
119
- main.raise(e)
119
+ $vmc_event.raised(e)
120
120
  end
121
121
  end
122
122
 
@@ -264,6 +264,86 @@ module VMCMatchers
264
264
  end
265
265
 
266
266
 
267
+ class FailWith
268
+ def initialize(exception)
269
+ @expected = exception
270
+ end
271
+
272
+ def matches?(log)
273
+ @actual = log.wait_for_event(EventLog::Raised).exception
274
+ @actual.is_a?(@expected)
275
+ end
276
+
277
+ def failure_message
278
+ "expected #@expected to be raised, but got #{@actual.class}: '#@actual"
279
+ end
280
+
281
+ def negative_failure_message
282
+ "expected #@expected to NOT be raised, but it was"
283
+ end
284
+ end
285
+
286
+ def fail_with(exception)
287
+ FailWith.new(exception)
288
+ end
289
+
290
+
291
+ class ProgressExpectation
292
+ def matches?(log)
293
+ @actual = log.wait_for_event(EventLog::Progress)
294
+ @actual == @expected
295
+ end
296
+
297
+ def failure_message
298
+ "expected to #{@expected.report}, but #{@actual.report_past} instead"
299
+ end
300
+
301
+ def negative_failure_message
302
+ "expected not to #{@expected.report}"
303
+ end
304
+ end
305
+
306
+ class Successfully < ProgressExpectation
307
+ def initialize(message)
308
+ @expected = EventLog::Did.new(message)
309
+ end
310
+ end
311
+
312
+ class Skip < ProgressExpectation
313
+ def initialize(message)
314
+ @expected = EventLog::Skipped.new(message)
315
+ end
316
+ end
317
+
318
+ class FailTo < ProgressExpectation
319
+ def initialize(message)
320
+ @expected = EventLog::FailedTo.new(message)
321
+ end
322
+ end
323
+
324
+ class GiveUp < ProgressExpectation
325
+ def initialize(message)
326
+ @expected = EventLog::GaveUp.new(message)
327
+ end
328
+ end
329
+
330
+ def successfully(message)
331
+ Successfully.new(message)
332
+ end
333
+
334
+ def skip(message)
335
+ Skip.new(message)
336
+ end
337
+
338
+ def fail_to(message)
339
+ FailTo.new(message)
340
+ end
341
+
342
+ def give_up(message)
343
+ GiveUp.new(message)
344
+ end
345
+
346
+
267
347
  def asks(what)
268
348
  $vmc_event.should ask(what)
269
349
  end
@@ -276,6 +356,10 @@ module VMCMatchers
276
356
  $vmc_event.should have_input(name, value)
277
357
  end
278
358
 
359
+ def raises(exception)
360
+ $vmc_event.should fail_with(exception)
361
+ end
362
+
279
363
  def finish
280
364
  $vmc_event.should complete
281
365
  end
@@ -283,6 +367,22 @@ module VMCMatchers
283
367
  def outputs(what)
284
368
  $vmc_event.should output(what)
285
369
  end
370
+
371
+ def does(what)
372
+ $vmc_event.should successfully(what)
373
+ end
374
+
375
+ def skips(what)
376
+ $vmc_event.should skip(what)
377
+ end
378
+
379
+ def fails_to(what)
380
+ $vmc_event.should fail_to(what)
381
+ end
382
+
383
+ def gives_up(what)
384
+ $vmc_event.should give_up(what)
385
+ end
286
386
  end
287
387
 
288
388
  RSpec.configure do |c|
@@ -2,6 +2,36 @@
2
2
  $vmc_event = nil
3
3
 
4
4
  class VMC::CLI
5
+ class ProgressEventReporter
6
+ def initialize(message, skipper)
7
+ @message = message
8
+ @skipper = skipper
9
+ @skipped = false
10
+ end
11
+
12
+ def skip(&blk)
13
+ @skipped = true
14
+ $vmc_event.skipped(@message)
15
+ @skipper.skip(&blk)
16
+ end
17
+
18
+ def fail(&blk)
19
+ @skipped = true
20
+ $vmc_event.failed_to(@message)
21
+ @skipper.fail(&blk)
22
+ end
23
+
24
+ def give_up(&blk)
25
+ @skipped = true
26
+ $vmc_event.gave_up(@message)
27
+ @skipper.give_up(&blk)
28
+ end
29
+
30
+ def skipped?
31
+ @skipped
32
+ end
33
+ end
34
+
5
35
  def ask(*args)
6
36
  $vmc_event.asking(*args) if $vmc_event
7
37
  super
@@ -15,6 +45,21 @@ class VMC::CLI
15
45
  def force?
16
46
  false
17
47
  end
48
+
49
+ def with_progress(msg, &blk)
50
+ super(msg) do |s|
51
+ reporter = ProgressEventReporter.new(msg, s)
52
+
53
+ res = blk.call(reporter)
54
+
55
+ $vmc_event.did(msg) unless reporter.skipped?
56
+
57
+ res
58
+ end
59
+ rescue
60
+ $vmc_event.failed_to(msg)
61
+ raise
62
+ end
18
63
  end
19
64
 
20
65
  class Mothership::Inputs
@@ -9,12 +9,19 @@ describe "Start#target" do
9
9
 
10
10
  describe "switching target url" do
11
11
  before(:all) do
12
- @old_target = File.read(File.expand_path(VMC::TARGET_FILE))
12
+ tgt = File.expand_path(VMC::TARGET_FILE)
13
+ @old_target = File.read(tgt) if File.exists? tgt
13
14
  end
14
15
 
15
16
  after(:all) do
16
- File.open(File.expand_path(VMC::TARGET_FILE), "w") do |io|
17
- io.print @old_target
17
+ tgt = File.expand_path(VMC::TARGET_FILE)
18
+
19
+ if @old_target
20
+ File.open(tgt, "w") do |io|
21
+ io.print @old_target
22
+ end
23
+ else
24
+ File.delete(tgt)
18
25
  end
19
26
  end
20
27
 
data/vmc/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The VMware Cloud CLI. This is the command line interface to VMware's Application Platform
4
4
 
5
- _Copyright 2010-2011, VMware, Inc. Licensed under the
5
+ _Copyright 2010-2012, VMware, Inc. Licensed under the
6
6
  MIT license, please see the LICENSE file. All rights reserved._
7
7
 
8
8
  Usage: vmc [options] command [<args>] [command_options]
@@ -100,3 +100,7 @@ MIT license, please see the LICENSE file. All rights reserved._
100
100
  vmc login
101
101
  bundle package
102
102
  vmc push
103
+
104
+ ## File a Bug
105
+
106
+ To file a bug against Cloud Foundry Open Source and its components, sign up and use our bug tracking system: [http://cloudfoundry.atlassian.net](http://cloudfoundry.atlassian.net)
@@ -32,9 +32,20 @@ module VMC::Cli
32
32
 
33
33
  def start_local_console(port, appname)
34
34
  auth_info = console_credentials(appname)
35
- display "Connecting to '#{appname}' console: ", false
35
+ banner = "Connecting to '#{appname}' console: "
36
+ display banner, false
37
+ t = Thread.new do
38
+ count = 0
39
+ while count < 90 do
40
+ display '.', false
41
+ sleep 1
42
+ count += 1
43
+ end
44
+ end
36
45
  prompt = console_login(auth_info, port)
37
- display "OK".green
46
+ Thread.kill(t)
47
+ clear(80)
48
+ display "#{banner}#{'OK'.green}"
38
49
  display "\n"
39
50
  initialize_readline
40
51
  run_console prompt
@@ -47,7 +58,7 @@ module VMC::Cli
47
58
  @telnet_client = telnet_client(port)
48
59
  prompt = nil
49
60
  err_msg = "Login attempt timed out."
50
- 5.times do
61
+ 3.times do
51
62
  begin
52
63
  results = @telnet_client.login("Name"=>auth_info["username"],
53
64
  "Password"=>auth_info["password"])
@@ -67,7 +78,6 @@ module VMC::Cli
67
78
  sleep 5
68
79
  @telnet_client = telnet_client(port)
69
80
  end
70
- display ".", false
71
81
  end
72
82
  unless prompt
73
83
  close_console
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: 62196447
4
+ hash: 1290961179
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
9
  - 0
10
10
  - beta
11
- - 30
12
- version: 0.4.0.beta.30
11
+ - 31
12
+ version: 0.4.0.beta.31
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-08-06 00:00:00 Z
20
+ date: 2012-08-15 00:00:00 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: json_pure
@@ -388,6 +388,9 @@ files:
388
388
  - vmc-ng/lib/vmc.rb
389
389
  - vmc-ng/spec/app/apps_spec.rb
390
390
  - vmc-ng/spec/app/push_spec.rb
391
+ - vmc-ng/spec/assets/hello-sinatra/Gemfile
392
+ - vmc-ng/spec/assets/hello-sinatra/main.rb
393
+ - vmc-ng/spec/assets/hello-sinatra/manifest.yml
391
394
  - vmc-ng/spec/eventlog.rb
392
395
  - vmc-ng/spec/helpers.rb
393
396
  - vmc-ng/spec/patches.rb
@@ -426,7 +429,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
429
  requirements: []
427
430
 
428
431
  rubyforge_project:
429
- rubygems_version: 1.8.23
432
+ rubygems_version: 1.8.24
430
433
  signing_key:
431
434
  specification_version: 3
432
435
  summary: Client library and CLI that provides access to the VMware Cloud Application Platform.