vagrant-skytap 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/eng-10269.diff.1 ADDED
@@ -0,0 +1,455 @@
1
+ # HG changeset patch
2
+ # Parent 586410d23ff4907e87ce5ee2c7eee574f0749ab0
3
+ ENG-10269 add parallelization support for `vagrant up`. This appears to work for the no-parallel case.
4
+
5
+ diff -r 586410d23ff4 lib/vagrant-skytap/action.rb
6
+ --- a/lib/vagrant-skytap/action.rb Thu Nov 19 21:24:21 2015 -0800
7
+ +++ b/lib/vagrant-skytap/action.rb Thu Nov 19 21:24:32 2015 -0800
8
+ @@ -187,6 +187,30 @@
9
+ # This action is called to bring the box up from nothing.
10
+ def self.action_up
11
+ Vagrant::Action::Builder.new.tap do |b|
12
+ + b.use action_create
13
+ +
14
+ + b.use Call, IsStopped do |env, b1|
15
+ + if env[:result]
16
+ + # this has some kind of hook that executes
17
+ + # when #action returns
18
+ + b1.use action_prepare_boot
19
+ + end
20
+ + end
21
+ +
22
+ + b.use Call, IsRunning do |env, b1|
23
+ + if env[:result]
24
+ + b1.use MessageAlreadyRunning
25
+ + next
26
+ + end
27
+ + b1.use RunVm
28
+ + b1.use WaitForCommunicator
29
+ + end
30
+ + end
31
+ + end
32
+ +
33
+ + # Pulled out of action_up to allow
34
+ + def self.action_create
35
+ + Vagrant::Action::Builder.new.tap do |b|
36
+ b.use HandleBox
37
+ b.use ConfigValidate
38
+ b.use InitializeAPIClient
39
+ @@ -204,26 +228,23 @@
40
+ b1.use StoreExtraData
41
+ b1.use SetUpVm
42
+ end
43
+ - b.use Call, IsRunning do |env, b1|
44
+ + b.use Call, IsStopped do |env, b1|
45
+ if env[:result]
46
+ - b1.use MessageAlreadyRunning
47
+ - next
48
+ - end
49
+ -
50
+ - b1.use Call, IsStopped do |env2, b2|
51
+ - if env2[:result]
52
+ - b2.use UpdateHardware
53
+ - b2.use SetHostname
54
+ - b2.use action_prepare_boot
55
+ - end
56
+ -
57
+ - b2.use RunVm
58
+ - b2.use WaitForCommunicator
59
+ + b1.use UpdateHardware
60
+ + b1.use SetHostname
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ + def self.action_run_environment
67
+ + Vagrant::Action::Builder.new.tap do |b|
68
+ + b.use InitializeAPIClient
69
+ + b.use FetchEnvironment
70
+ + b.use RunEnvironment
71
+ + end
72
+ + end
73
+ +
74
+ def self.action_reload
75
+ Vagrant::Action::Builder.new.tap do |b|
76
+ b.use ConfigValidate
77
+ diff -r 586410d23ff4 lib/vagrant-skytap/action/initialize_api_client.rb
78
+ --- a/lib/vagrant-skytap/action/initialize_api_client.rb Thu Nov 19 21:24:21 2015 -0800
79
+ +++ b/lib/vagrant-skytap/action/initialize_api_client.rb Thu Nov 19 21:24:32 2015 -0800
80
+ @@ -15,7 +15,14 @@
81
+ def call(env)
82
+ @logger.info("Connecting to Skytap...")
83
+
84
+ - client = API::Client.new(env[:machine].provider_config)
85
+ + # This can be called outside the context of a machine
86
+ + config = env[:machine].try(:provider_config) || {
87
+ + base_url: env[:base_url],
88
+ + username: env[:username],
89
+ + api_token: env[:api_token],
90
+ + }
91
+ +
92
+ + client = API::Client.new(config)
93
+ if client.get('/configurations').code == '200'
94
+ env[:api_client] = client
95
+ end
96
+ diff -r 586410d23ff4 lib/vagrant-skytap/action/run_environment.rb
97
+ --- a/lib/vagrant-skytap/action/run_environment.rb Thu Nov 19 21:24:21 2015 -0800
98
+ +++ b/lib/vagrant-skytap/action/run_environment.rb Thu Nov 19 21:24:32 2015 -0800
99
+ @@ -16,8 +16,10 @@
100
+ end
101
+
102
+ def call(env)
103
+ - env[:ui].info(I18n.t("vagrant_skytap.launching_instance"))
104
+ - environment.run!
105
+ + env[:ui].info(I18n.t("vagrant_skytap.running_environment"))
106
+ + vm_ids = env[:machines].try(:collect, &:id)
107
+ + @logger.info("Running VMs: #{vm_ids}")
108
+ + env[:environment].run!(vm_ids)
109
+
110
+ @app.call(env)
111
+ end
112
+ diff -r 586410d23ff4 lib/vagrant-skytap/api/environment.rb
113
+ --- a/lib/vagrant-skytap/api/environment.rb Thu Nov 19 21:24:21 2015 -0800
114
+ +++ b/lib/vagrant-skytap/api/environment.rb Thu Nov 19 21:24:32 2015 -0800
115
+ @@ -28,7 +28,9 @@
116
+ end
117
+
118
+ def properties(env)
119
+ - EnvironmentProperties.read(env[:machine].env.local_data_path)
120
+ + # This can be called outside the context of a particular machine
121
+ + path = env[:local_data_path] || env[:machine].env.local_data_path
122
+ + EnvironmentProperties.read(path)
123
+ end
124
+
125
+ def check_vm_before_adding(env, vm)
126
+ @@ -78,6 +80,10 @@
127
+ super
128
+ end
129
+
130
+ + def run!(vm_ids = nil)
131
+ + set_runstate :running, vm_ids: vm_ids
132
+ + end
133
+ +
134
+ def delete
135
+ retry_while_resource_busy do
136
+ api_client.delete(url)
137
+ diff -r 586410d23ff4 lib/vagrant-skytap/api/runstate_operations.rb
138
+ --- a/lib/vagrant-skytap/api/runstate_operations.rb Thu Nov 19 21:24:21 2015 -0800
139
+ +++ b/lib/vagrant-skytap/api/runstate_operations.rb Thu Nov 19 21:24:32 2015 -0800
140
+ @@ -20,12 +20,17 @@
141
+ end
142
+
143
+ def poweroff!
144
+ - set_runstate :halted, :stopped
145
+ + set_runstate :halted, completed_runstate: :stopped
146
+ end
147
+
148
+ - def set_runstate(new_runstate, completed_runstate = nil)
149
+ - completed_runstate ||= new_runstate
150
+ - update_with_retry(runstate: new_runstate)
151
+ + def set_runstate(new_runstate, opts = {})
152
+ + completed_runstate = opts.delete(:completed_runstate) || new_runstate
153
+ +
154
+ + params = {runstate: new_runstate}.tap do |ret|
155
+ + ret[:multiselect] = opts[:vm_ids] if opts[:vm_ids]
156
+ + end
157
+ + update_with_retry(params)
158
+ +
159
+ wait_for_runstate(completed_runstate) unless runstate == completed_runstate
160
+ end
161
+
162
+ diff -r 586410d23ff4 lib/vagrant-skytap/command/start_mixins.rb
163
+ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164
+ +++ b/lib/vagrant-skytap/command/start_mixins.rb Thu Nov 19 21:24:32 2015 -0800
165
+ @@ -0,0 +1,47 @@
166
+ +module VagrantPlugins
167
+ + module Skytap
168
+ + module Command
169
+ + module StartMixins
170
+ +
171
+ + # Would be nice to just extend this, then alias #build_start_options
172
+ + # and add default options flag.
173
+ + #include VagrantPlugins::CommandUp::StartMixins
174
+ +
175
+ + # This adds the standard `start` command line flags to the given
176
+ + # OptionParser, storing the result in the `options` dictionary.
177
+ + #
178
+ + # @param [OptionParser] parser
179
+ + # @param [Hash] options
180
+ + def build_start_options(parser, options)
181
+ + # Setup the defaults
182
+ + options[:provision_types] = nil
183
+ +
184
+ + # Add the options
185
+ + parser.on("--[no-]provision", "Enable or disable provisioning") do |p|
186
+ + options[:provision_enabled] = p
187
+ + options[:provision_ignore_sentinel] = true
188
+ + end
189
+ +
190
+ + parser.on("--provision-with x,y,z", Array,
191
+ + "Enable only certain provisioners, by type.") do |list|
192
+ + options[:provision_types] = list.map { |type| type.to_sym }
193
+ + options[:provision_enabled] = true
194
+ + options[:provision_ignore_sentinel] = true
195
+ + end
196
+ + end
197
+ +
198
+ + # This validates the provisioner flags and raises an exception
199
+ + # if there are invalid ones.
200
+ + def validate_provisioner_flags!(options)
201
+ + (options[:provision_types] || []).each do |type|
202
+ + klass = Vagrant.plugin("2").manager.provisioners[type]
203
+ + if !klass
204
+ + raise Vagrant::Errors::ProvisionerFlagInvalid,
205
+ + name: type.to_s
206
+ + end
207
+ + end
208
+ + end
209
+ + end
210
+ + end
211
+ + end
212
+ +end
213
+ diff -r 586410d23ff4 lib/vagrant-skytap/command/up.rb
214
+ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
215
+ +++ b/lib/vagrant-skytap/command/up.rb Thu Nov 19 21:24:32 2015 -0800
216
+ @@ -0,0 +1,139 @@
217
+ +require 'optparse'
218
+ +
219
+ +require "vagrant"
220
+ +require 'byebug'
221
+ +
222
+ +require_relative 'start_mixins'
223
+ +
224
+ +# This is a copy of Vagrant's built-in "up" command which handles
225
+ +# parallel runstate changes by invoking the run_environment action
226
+ +# once for all machines: runstate operations lock the environment,
227
+ +# and are therefore not thread-safe.
228
+ +
229
+ +module VagrantPlugins
230
+ + module Skytap
231
+ + module Command
232
+ + #class Up < VagrantPlugins::CommandUp::Command
233
+ + class Up < Vagrant.plugin("2", :command)
234
+ + include StartMixins
235
+ +
236
+ + def self.synopsis
237
+ + "starts and provisions the vagrant environment (with parallel runstate support)"
238
+ + end
239
+ +
240
+ + def execute
241
+ + options = {}
242
+ + options[:destroy_on_error] = true
243
+ + options[:parallel] = true
244
+ + options[:provision_ignore_sentinel] = false
245
+ +
246
+ + opts = OptionParser.new do |o|
247
+ + o.banner = "Usage: vagrant up [options] [name]"
248
+ + o.separator ""
249
+ + o.separator "Options:"
250
+ + o.separator ""
251
+ +
252
+ + build_start_options(o, options)
253
+ +
254
+ + o.on("--[no-]destroy-on-error",
255
+ + "Destroy machine if any fatal error happens (default to true)") do |destroy|
256
+ + options[:destroy_on_error] = destroy
257
+ + end
258
+ +
259
+ + o.on("--[no-]parallel",
260
+ + "Enable or disable parallelism if provider supports it") do |parallel|
261
+ + options[:parallel] = parallel
262
+ + end
263
+ +
264
+ + o.on("--provider PROVIDER", String,
265
+ + "Back the machine with a specific provider") do |provider|
266
+ + options[:provider] = provider
267
+ + end
268
+ + end
269
+ +
270
+ + # Parse the options
271
+ + argv = parse_options(opts)
272
+ + return if !argv
273
+ +
274
+ + # Validate the provisioners
275
+ + validate_provisioner_flags!(options)
276
+ +
277
+ + # Go over each VM and bring it up
278
+ + @logger.debug("'Up' each target VM...")
279
+ +
280
+ +
281
+ + # Begin modified section
282
+ +
283
+ + machines = []
284
+ + names = argv
285
+ + if names.empty?
286
+ + autostart = false
287
+ + @env.vagrantfile.machine_names_and_options.each do |n, o|
288
+ + autostart = true if o.key?(:autostart)
289
+ + o[:autostart] = true if !o.key?(:autostart)
290
+ + names << n.to_s if o[:autostart]
291
+ + end
292
+ +
293
+ + # If we have an autostart key but no names, it means that
294
+ + # all machines are autostart: false and we don't start anything.
295
+ + names = nil if autostart && names.empty?
296
+ + end
297
+ +
298
+ + with_target_vms(names, provider: options[:provider]) do |machine|
299
+ + @env.ui.info(I18n.t(
300
+ + "vagrant.commands.up.upping",
301
+ + name: machine.name,
302
+ + provider: machine.provider_name))
303
+ +
304
+ + machines << machine
305
+ +
306
+ + if options[:parallel]
307
+ + machine.action(:create, options)
308
+ + else
309
+ + machine.action(:up, options)
310
+ + end
311
+ + end
312
+ +
313
+ + if options[:parallel]
314
+ + @env.action_runner.run(VagrantPlugins::Skytap::Action.action_run_environment,
315
+ + local_data_path: @env.local_data_path,
316
+ + machines: machines,
317
+ + machine: machines.first,
318
+ + base_url: nil,
319
+ + username: nil,
320
+ + api_token: nil,
321
+ + ui: @env.ui
322
+ + )
323
+ + end
324
+ +
325
+ + # End modified section
326
+ +
327
+ +
328
+ + if machines.empty?
329
+ + @env.ui.info(I18n.t("vagrant.up_no_machines"))
330
+ + return 0
331
+ + else
332
+ +
333
+ + end
334
+ +
335
+ + # Output the post-up messages that we have, if any
336
+ + machines.each do |m|
337
+ + next if !m.config.vm.post_up_message
338
+ + next if m.config.vm.post_up_message == ""
339
+ +
340
+ + # Add a newline to separate things.
341
+ + @env.ui.info("", prefix: false)
342
+ +
343
+ + m.ui.success(I18n.t(
344
+ + "vagrant.post_up_message",
345
+ + name: m.name.to_s,
346
+ + message: m.config.vm.post_up_message))
347
+ + end
348
+ +
349
+ + # Success, exit status 0
350
+ + 0
351
+ + end
352
+ + end
353
+ + end
354
+ + end
355
+ +end
356
+ diff -r 586410d23ff4 lib/vagrant-skytap/plugin.rb
357
+ --- a/lib/vagrant-skytap/plugin.rb Thu Nov 19 21:24:21 2015 -0800
358
+ +++ b/lib/vagrant-skytap/plugin.rb Thu Nov 19 21:24:32 2015 -0800
359
+ @@ -24,7 +24,7 @@
360
+ Config
361
+ end
362
+
363
+ - provider(:skytap, parallel: false) do
364
+ + provider(:skytap, parallel: true) do
365
+ # Setup logging and i18n
366
+ setup_logging
367
+ setup_i18n
368
+ @@ -34,6 +34,11 @@
369
+ Provider
370
+ end
371
+
372
+ + command("up", primary: true) do
373
+ + require_relative "command/up"
374
+ + Command::Up
375
+ + end
376
+ +
377
+ # This initializes the internationalization strings.
378
+ def self.setup_i18n
379
+ I18n.load_path << File.expand_path("locales/en.yml", Skytap.source_root)
380
+ diff -r 586410d23ff4 locales/en.yml
381
+ --- a/locales/en.yml Thu Nov 19 21:24:21 2015 -0800
382
+ +++ b/locales/en.yml Thu Nov 19 21:24:32 2015 -0800
383
+ @@ -3,8 +3,8 @@
384
+ already_status: |-
385
+ The machine is already %{status}.
386
+
387
+ - launching_instance: |-
388
+ - Launching an instance with the following settings...
389
+ + running_environment: |-
390
+ + Starting VMs ...
391
+ launching_vm: |-
392
+ Launching a VM with the following settings...
393
+ not_created: |-
394
+ diff -r 586410d23ff4 spec/acceptance/provider/up_spec.rb
395
+ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
396
+ +++ b/spec/acceptance/provider/up_spec.rb Thu Nov 19 21:24:32 2015 -0800
397
+ @@ -0,0 +1,33 @@
398
+ +# This tests that an instance can be halted correctly
399
+ +shared_examples 'provider/up' do |provider, options|
400
+ + if !options[:box]
401
+ + raise ArgumentError,
402
+ + "box option must be specified for provider: #{provider}"
403
+ + end
404
+ +
405
+ + include_context 'acceptance'
406
+ +
407
+ + before do
408
+ + environment.skeleton('generic')
409
+ + #assert_execute('vagrant', 'box', 'add', 'basic', options[:box])
410
+ + end
411
+ +
412
+ + after do
413
+ + assert_execute('vagrant', 'destroy', '--force')
414
+ + end
415
+ +
416
+ + it 'should bring up the machine and halt it' do
417
+ + status("Test: machine can be brought up")
418
+ + up_result = execute("vagrant", "up")
419
+ + expect(up_result).to exit_with(0)
420
+ +
421
+ + status("Test: machine is running after up")
422
+ + echo_result = execute("vagrant", "ssh", "-c", "echo foo")
423
+ + expect(echo_result).to exit_with(0)
424
+ + expect(echo_result.stdout).to match(/foo\n$/)
425
+ +
426
+ + status("Test: machine can be halted")
427
+ + halt_result = execute("vagrant", "halt")
428
+ + expect(halt_result).to exit_with(0)
429
+ + end
430
+ +end
431
+ diff -r 586410d23ff4 spec/acceptance/skeletons/generic/Vagrantfile
432
+ --- a/spec/acceptance/skeletons/generic/Vagrantfile Thu Nov 19 21:24:21 2015 -0800
433
+ +++ b/spec/acceptance/skeletons/generic/Vagrantfile Thu Nov 19 21:24:32 2015 -0800
434
+ @@ -1,15 +1,14 @@
435
+ Vagrant.configure("2") do |config|
436
+ - config.vm.box = "skytap-dummy"
437
+ + config.vm.box = "skytap/empty"
438
+
439
+ config.vm.provider :skytap do |skytap, override|
440
+ - skytap.username = "user"
441
+ - skytap.api_token = "9999999999999999999999"
442
+ - skytap.base_url = "https://example.com/"
443
+ + skytap.vm_url = "/vms/7285844"
444
+ + skytap.vpn_url = "/vpns/vpn-711360"
445
+ +# skytap.vpn_url = "/vpns/vpn-3195669"
446
+ end
447
+
448
+ config.vm.define "vm1" do |ubuntu|
449
+ - ubuntu.vm.provider :skytap do |box|
450
+ - box.vm_url = "https://example.com/vms/1"
451
+ - end
452
+ + ubuntu.ssh.username = "skytap"
453
+ + ubuntu.ssh.password = "ChangeMe!"
454
+ end
455
+ end
@@ -0,0 +1,20 @@
1
+ module VagrantPlugins
2
+ module Skytap
3
+ module Action
4
+ # Our modified "up" command captures the VM states in the initial_states hash
5
+ # before running them, potentially in parallel.
6
+ class InitialState
7
+ def initialize(app, env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new("vagrant_skytap::action::initial_state")
10
+ end
11
+
12
+ def call(env)
13
+ # if initial_states is absent, result is nil
14
+ env[:result] = env[:initial_states].try(:[], env[:machine].id)
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module VagrantPlugins
2
+ module Skytap
3
+ module Action
4
+ # This can be used with "Call" built-in to check if the action
5
+ # is being performed as part of a parallel operation.
6
+ class IsParallelized
7
+ def initialize(app, env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new("vagrant_skytap::action::is_parallelized")
10
+ end
11
+
12
+ def call(env)
13
+ env[:result] = env[:parallel]
14
+ @logger.info("Parallelization is #{env[:result] ? 'on' : 'off'}")
15
+
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module Skytap
3
+ module Action
4
+ class MessageResuming
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t("vagrant_skytap.resuming"))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -3,7 +3,9 @@ require "log4r"
3
3
  module VagrantPlugins
4
4
  module Skytap
5
5
  module Action
6
- # Runs the Skytap environment.
6
+ # Runs multiple VMs in parallel. This middleware will be invoked for
7
+ # each machine, so we set the :first_machine flag to prevent redundant
8
+ # REST calls.
7
9
  class RunEnvironment
8
10
  include Vagrant::Util::Retryable
9
11
 
@@ -16,8 +18,12 @@ module VagrantPlugins
16
18
  end
17
19
 
18
20
  def call(env)
19
- env[:ui].info(I18n.t("vagrant_skytap.launching_instance"))
20
- environment.run!
21
+ if env[:first_machine]
22
+ env[:ui].info(I18n.t("vagrant_skytap.running_environment"))
23
+ vm_ids = env[:machines].try(:collect, &:id)
24
+ @logger.info("Running VMs: #{vm_ids}")
25
+ env[:environment].run!(vm_ids)
26
+ end
21
27
 
22
28
  @app.call(env)
23
29
  end
@@ -40,7 +40,7 @@ module VagrantPlugins
40
40
  end
41
41
  end
42
42
  rescue Timeout::Error
43
- raise Errors::VMBootTimeout
43
+ raise Vagrant::Errors::VMBootTimeout
44
44
  end
45
45
  end
46
46
  end
@@ -168,6 +168,11 @@ module VagrantPlugins
168
168
  end
169
169
  end
170
170
 
171
+ # Note: Provision and SyncedFolders perform actions before and after
172
+ # calling the next middleware in the sequence. Both require that
173
+ # the machine be booted before those calls return. This requirement
174
+ # can be satisfied by putting the WaitForCommunicator middleware
175
+ # later in the sequence.
171
176
  def self.action_prepare_boot
172
177
  Vagrant::Action::Builder.new.tap do |b|
173
178
  b.use PrepareNFSSettings
@@ -180,12 +185,28 @@ module VagrantPlugins
180
185
 
181
186
  def self.action_resume
182
187
  Vagrant::Action::Builder.new.tap do |b|
183
- b.use action_up
188
+ Vagrant::Action::Builder.new.tap do |b|
189
+ b.use InitializeAPIClient
190
+ b.use FetchEnvironment
191
+ b.use Call, IsSuspended do |env, b1|
192
+ if env[:result]
193
+ b1.use MessageResuming
194
+ b1.use RunVm
195
+ b1.use WaitForCommunicator
196
+ end
197
+ end
198
+ end
184
199
  end
185
200
  end
186
201
 
187
- # This action is called to bring the box up from nothing.
188
- def self.action_up
202
+ # The Skytap provider has a modified "vagrant up" command which
203
+ # takes advantage of parallel runstate operations on Skytap
204
+ # environments. The create and update_hardware actions are
205
+ # separated from the run_vm action, so we can pass in the ids
206
+ # and initial states for all machines to be run, potentially
207
+ # with a single REST call.
208
+
209
+ def self.action_create
189
210
  Vagrant::Action::Builder.new.tap do |b|
190
211
  b.use HandleBox
191
212
  b.use ConfigValidate
@@ -204,23 +225,53 @@ module VagrantPlugins
204
225
  b1.use StoreExtraData
205
226
  b1.use SetUpVm
206
227
  end
207
- b.use Call, IsRunning do |env, b1|
228
+ end
229
+ end
230
+
231
+ def self.action_update_hardware
232
+ Vagrant::Action::Builder.new.tap do |b|
233
+ b.use InitializeAPIClient
234
+ b.use FetchEnvironment
235
+ b.use Call, IsStopped do |env, b1|
208
236
  if env[:result]
237
+ b1.use UpdateHardware
238
+ b1.use SetHostname
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ def self.action_run_vm
245
+ Vagrant::Action::Builder.new.tap do |b|
246
+ b.use InitializeAPIClient
247
+ b.use FetchEnvironment
248
+
249
+ # The "up" command stores the pre-run states to
250
+ # avoid a race condition when running multiple
251
+ # VMs in parallel -- we need to know which VMs
252
+ # are actually being powered on and need to
253
+ # have folders synced and provisioning run.
254
+ b.use Call, InitialState do |env, b1|
255
+ case env[:result]
256
+ when :running
209
257
  b1.use MessageAlreadyRunning
210
258
  next
259
+ when :suspended
260
+ b1.use MessageResuming
261
+ else
262
+ b1.use action_prepare_boot
211
263
  end
212
-
213
- b1.use Call, IsStopped do |env2, b2|
264
+ b1.use Call, IsParallelized do |env2, b2|
214
265
  if env2[:result]
215
- b2.use UpdateHardware
216
- b2.use SetHostname
217
- b2.use action_prepare_boot
266
+ # Note: RunEnvironment is a no-op after
267
+ # the first invocation.
268
+ b2.use RunEnvironment
269
+ else
270
+ b2.use RunVm
218
271
  end
219
-
220
- b2.use RunVm
221
- b2.use WaitForCommunicator
222
272
  end
223
273
  end
274
+ b.use WaitForCommunicator
224
275
  end
225
276
  end
226
277
 
@@ -229,13 +280,17 @@ module VagrantPlugins
229
280
  b.use ConfigValidate
230
281
  b.use InitializeAPIClient
231
282
  b.use FetchEnvironment
232
- b.use Call, ExistenceCheck do |env, b2|
283
+ b.use Call, ExistenceCheck do |env, b1|
233
284
  case env[:result]
234
285
  when :missing_environment, :missing_vm, :no_vms
235
- b2.use MessageNotCreated
286
+ b1.use MessageNotCreated
236
287
  else
237
- b2.use action_halt
238
- b2.use action_up
288
+ b1.use action_halt
289
+ b1.use action_update_hardware
290
+ # We don't need to store the initial states
291
+ # before calling run_vm, because the default
292
+ # behavior is to treat the VMs as powered off.
293
+ b1.use action_run_vm
239
294
  end
240
295
  end
241
296
  end
@@ -251,6 +306,8 @@ module VagrantPlugins
251
306
  autoload :ExistenceCheck, action_root.join("existence_check")
252
307
  autoload :FetchEnvironment, action_root.join("fetch_environment")
253
308
  autoload :InitializeAPIClient, action_root.join("initialize_api_client")
309
+ autoload :InitialState, action_root.join("initial_state")
310
+ autoload :IsParallelized, action_root.join("is_parallelized")
254
311
  autoload :IsRunning, action_root.join("is_running")
255
312
  autoload :IsStopped, action_root.join("is_stopped")
256
313
  autoload :IsSuspended, action_root.join("is_suspended")
@@ -258,6 +315,7 @@ module VagrantPlugins
258
315
  autoload :MessageAlreadyRunning, action_root.join("message_already_running")
259
316
  autoload :MessageNotCreated, action_root.join("message_not_created")
260
317
  autoload :MessageEnvironmentUrl, action_root.join("message_environment_url")
318
+ autoload :MessageResuming, action_root.join("message_resuming")
261
319
  autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
262
320
  autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings")
263
321
  autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids")