Fix issue with infinite looping on `vagrant resume`
This commit is contained in:
parent
db24291b3d
commit
2f7de333ec
|
@ -0,0 +1,50 @@
|
||||||
|
module Vagrant
|
||||||
|
module Actions
|
||||||
|
module VM
|
||||||
|
class Boot < Base
|
||||||
|
def execute!
|
||||||
|
@runner.invoke_around_callback(:boot) do
|
||||||
|
# Startup the VM
|
||||||
|
boot
|
||||||
|
|
||||||
|
# Wait for it to complete booting, or error if we could
|
||||||
|
# never detect it booted up successfully
|
||||||
|
if !wait_for_boot
|
||||||
|
error_and_exit(<<-error)
|
||||||
|
Failed to connect to VM! Failed to boot?
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def collect_shared_folders
|
||||||
|
# The root shared folder for the project
|
||||||
|
["vagrant-root", Env.root_path, Vagrant.config.vm.project_directory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def boot
|
||||||
|
logger.info "Booting VM..."
|
||||||
|
@runner.vm.start(:headless, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_boot(sleeptime=5)
|
||||||
|
logger.info "Waiting for VM to boot..."
|
||||||
|
|
||||||
|
Vagrant.config[:ssh][:max_tries].to_i.times do |i|
|
||||||
|
logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..."
|
||||||
|
|
||||||
|
if Vagrant::SSH.up?
|
||||||
|
logger.info "VM booted and ready for use!"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep sleeptime
|
||||||
|
end
|
||||||
|
|
||||||
|
logger.info "Failed to connect to VM! Failed to boot?"
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,48 +2,15 @@ module Vagrant
|
||||||
module Actions
|
module Actions
|
||||||
module VM
|
module VM
|
||||||
class Start < Base
|
class Start < Base
|
||||||
def execute!
|
def prepare
|
||||||
@runner.invoke_around_callback(:boot) do
|
# Start is a "meta-action" so it really just queues up a bunch
|
||||||
# Startup the VM
|
# of other actions in its place:
|
||||||
boot
|
steps = [ForwardPorts, SharedFolders, Boot]
|
||||||
|
|
||||||
# Wait for it to complete booting, or error if we could
|
steps.each do |action_klass|
|
||||||
# never detect it booted up successfully
|
@runner.add_action(action_klass)
|
||||||
if !wait_for_boot
|
|
||||||
error_and_exit(<<-error)
|
|
||||||
Failed to connect to VM! Failed to boot?
|
|
||||||
error
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect_shared_folders
|
|
||||||
# The root shared folder for the project
|
|
||||||
["vagrant-root", Env.root_path, Vagrant.config.vm.project_directory]
|
|
||||||
end
|
|
||||||
|
|
||||||
def boot
|
|
||||||
logger.info "Booting VM..."
|
|
||||||
@runner.vm.start(:headless, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def wait_for_boot(sleeptime=5)
|
|
||||||
logger.info "Waiting for VM to boot..."
|
|
||||||
|
|
||||||
Vagrant.config[:ssh][:max_tries].to_i.times do |i|
|
|
||||||
logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..."
|
|
||||||
|
|
||||||
if Vagrant::SSH.up?
|
|
||||||
logger.info "VM booted and ready for use!"
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
sleep sleeptime
|
|
||||||
end
|
|
||||||
|
|
||||||
logger.info "Failed to connect to VM! Failed to boot?"
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ msg
|
||||||
|
|
||||||
# Up is a "meta-action" so it really just queues up a bunch
|
# Up is a "meta-action" so it really just queues up a bunch
|
||||||
# of other actions in its place:
|
# of other actions in its place:
|
||||||
steps = [Import, ForwardPorts, SharedFolders, Start]
|
steps = [Import, ForwardPorts, SharedFolders, Boot]
|
||||||
steps << Provision if Vagrant.config.chef.enabled
|
steps << Provision if Vagrant.config.chef.enabled
|
||||||
steps.insert(0, MoveHardDrive) if Vagrant.config.vm.hd_location
|
steps.insert(0, MoveHardDrive) if Vagrant.config.vm.hd_location
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,7 @@ module Vagrant
|
||||||
def start
|
def start
|
||||||
return if @vm.running?
|
return if @vm.running?
|
||||||
|
|
||||||
actions = [Actions::VM::ForwardPorts, Actions::VM::SharedFolders, Actions::VM::Start]
|
execute!(Actions::VM::Start)
|
||||||
actions.each do |action|
|
|
||||||
add_action(action)
|
|
||||||
end
|
|
||||||
|
|
||||||
execute!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||||
|
|
||||||
|
class BootActionTest < Test::Unit::TestCase
|
||||||
|
setup do
|
||||||
|
@mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Boot)
|
||||||
|
@mock_vm.stubs(:invoke_callback)
|
||||||
|
mock_config
|
||||||
|
end
|
||||||
|
|
||||||
|
context "execution" do
|
||||||
|
should "invoke the 'boot' around callback" do
|
||||||
|
boot_seq = sequence("boot_seq")
|
||||||
|
@mock_vm.expects(:invoke_around_callback).with(:boot).once.in_sequence(boot_seq).yields
|
||||||
|
@action.expects(:boot).in_sequence(boot_seq)
|
||||||
|
@action.expects(:wait_for_boot).returns(true).in_sequence(boot_seq)
|
||||||
|
@action.execute!
|
||||||
|
end
|
||||||
|
|
||||||
|
should "error and exit if the bootup failed" do
|
||||||
|
fail_boot_seq = sequence("fail_boot_seq")
|
||||||
|
@action.expects(:boot).once.in_sequence(fail_boot_seq)
|
||||||
|
@action.expects(:wait_for_boot).returns(false).in_sequence(fail_boot_seq)
|
||||||
|
@action.expects(:error_and_exit).once.in_sequence(fail_boot_seq)
|
||||||
|
@action.execute!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "booting" do
|
||||||
|
should "start the VM in headless mode" do
|
||||||
|
@vm.expects(:start).with(:headless, true).once
|
||||||
|
@action.boot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "waiting for boot" do
|
||||||
|
should "repeatedly ping the SSH port and return false with no response" do
|
||||||
|
seq = sequence('pings')
|
||||||
|
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i - 1).returns(false).in_sequence(seq)
|
||||||
|
Vagrant::SSH.expects(:up?).once.returns(true).in_sequence(seq)
|
||||||
|
assert @action.wait_for_boot(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "ping the max number of times then just return" do
|
||||||
|
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i).returns(false)
|
||||||
|
assert !@action.wait_for_boot(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "callbacks" do
|
||||||
|
should "setup the root directory shared folder" do
|
||||||
|
expected = ["vagrant-root", Vagrant::Env.root_path, Vagrant.config.vm.project_directory]
|
||||||
|
assert_equal expected, @action.collect_shared_folders
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,53 +3,26 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||||
class StartActionTest < Test::Unit::TestCase
|
class StartActionTest < Test::Unit::TestCase
|
||||||
setup do
|
setup do
|
||||||
@mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Start)
|
@mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Start)
|
||||||
@mock_vm.stubs(:invoke_callback)
|
|
||||||
mock_config
|
mock_config
|
||||||
end
|
end
|
||||||
|
|
||||||
context "execution" do
|
context "sub-actions" do
|
||||||
should "invoke the 'boot' around callback" do
|
setup do
|
||||||
boot_seq = sequence("boot_seq")
|
File.stubs(:file?).returns(true)
|
||||||
@mock_vm.expects(:invoke_around_callback).with(:boot).once.in_sequence(boot_seq).yields
|
File.stubs(:exist?).returns(true)
|
||||||
@action.expects(:boot).in_sequence(boot_seq)
|
@default_order = [Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
|
||||||
@action.expects(:wait_for_boot).returns(true).in_sequence(boot_seq)
|
|
||||||
@action.execute!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
should "error and exit if the bootup failed" do
|
def setup_action_expectations
|
||||||
fail_boot_seq = sequence("fail_boot_seq")
|
default_seq = sequence("default_seq")
|
||||||
@action.expects(:boot).once.in_sequence(fail_boot_seq)
|
@default_order.each do |action|
|
||||||
@action.expects(:wait_for_boot).returns(false).in_sequence(fail_boot_seq)
|
@mock_vm.expects(:add_action).with(action).once.in_sequence(default_seq)
|
||||||
@action.expects(:error_and_exit).once.in_sequence(fail_boot_seq)
|
end
|
||||||
@action.execute!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "booting" do
|
|
||||||
should "start the VM in headless mode" do
|
|
||||||
@vm.expects(:start).with(:headless, true).once
|
|
||||||
@action.boot
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "waiting for boot" do
|
|
||||||
should "repeatedly ping the SSH port and return false with no response" do
|
|
||||||
seq = sequence('pings')
|
|
||||||
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i - 1).returns(false).in_sequence(seq)
|
|
||||||
Vagrant::SSH.expects(:up?).once.returns(true).in_sequence(seq)
|
|
||||||
assert @action.wait_for_boot(0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
should "ping the max number of times then just return" do
|
should "do the proper actions by default" do
|
||||||
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i).returns(false)
|
setup_action_expectations
|
||||||
assert !@action.wait_for_boot(0)
|
@action.prepare
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "callbacks" do
|
|
||||||
should "setup the root directory shared folder" do
|
|
||||||
expected = ["vagrant-root", Vagrant::Env.root_path, Vagrant.config.vm.project_directory]
|
|
||||||
assert_equal expected, @action.collect_shared_folders
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ class UpActionTest < Test::Unit::TestCase
|
||||||
setup do
|
setup do
|
||||||
File.stubs(:file?).returns(true)
|
File.stubs(:file?).returns(true)
|
||||||
File.stubs(:exist?).returns(true)
|
File.stubs(:exist?).returns(true)
|
||||||
@default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Start]
|
@default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_action_expectations
|
def setup_action_expectations
|
||||||
|
|
|
@ -80,15 +80,8 @@ class VMTest < Test::Unit::TestCase
|
||||||
@vm.start
|
@vm.start
|
||||||
end
|
end
|
||||||
|
|
||||||
should "add and execute the proper actions" do
|
should "execute the start action" do
|
||||||
actions = [Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Start]
|
@vm.expects(:execute!).once.with(Vagrant::Actions::VM::Start)
|
||||||
|
|
||||||
action_seq = sequence("action_seq")
|
|
||||||
actions.each do |action|
|
|
||||||
@vm.expects(:add_action).with(action).in_sequence(action_seq)
|
|
||||||
end
|
|
||||||
|
|
||||||
@vm.expects(:execute!).once.in_sequence(action_seq)
|
|
||||||
@vm.start
|
@vm.start
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue