`vagrant halt` now attempts to gracefully shut down the machine (via System#halt)
This commit is contained in:
parent
0736f8582d
commit
d5866a1b54
|
@ -6,8 +6,12 @@ module Vagrant
|
|||
raise ActionException.new(:vm_not_running) unless @runner.vm.running?
|
||||
|
||||
@runner.invoke_around_callback(:halt) do
|
||||
logger.info "Forcing shutdown of VM..."
|
||||
@runner.vm.stop
|
||||
@runner.system.halt
|
||||
|
||||
if @runner.vm.state(true) != :powered_off
|
||||
logger.info "Forcing shutdown of VM..."
|
||||
@runner.vm.stop
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,15 @@ module Vagrant
|
|||
@vm = vm
|
||||
end
|
||||
|
||||
# Halt the machine. This method should gracefully shut down the
|
||||
# operating system. This method will cause `vagrant halt` and associated
|
||||
# commands to _block_, meaning that if the machine doesn't halt
|
||||
# in a reasonable amount of time, this method should just return.
|
||||
#
|
||||
# If when this method returns, the machine's state isn't "powered_off,"
|
||||
# Vagrant will proceed to forcefully shut the machine down.
|
||||
def halt; end
|
||||
|
||||
# Mounts a shared folder. This method is called by the shared
|
||||
# folder action with an open SSH session (passed in as `ssh`).
|
||||
# This method should create, mount, and properly set permissions
|
||||
|
|
|
@ -11,6 +11,24 @@ module Vagrant
|
|||
#-------------------------------------------------------------------
|
||||
# Overridden methods
|
||||
#-------------------------------------------------------------------
|
||||
def halt
|
||||
logger.info "Attempting graceful shutdown of linux..."
|
||||
vm.env.ssh.execute do |ssh|
|
||||
ssh.exec!("sudo halt")
|
||||
end
|
||||
|
||||
# Wait until the VM's state is actually powered off. If this doesn't
|
||||
# occur within a reasonable amount of time (15 seconds by default),
|
||||
# then simply return and allow Vagrant to kill the machine.
|
||||
count = 0
|
||||
while vm.vm.state(true) != :powered_off
|
||||
count += 1
|
||||
|
||||
return if count >= 15
|
||||
sleep 1
|
||||
end
|
||||
end
|
||||
|
||||
def mount_shared_folder(ssh, name, guestpath)
|
||||
ssh.exec!("sudo mkdir -p #{guestpath}")
|
||||
mount_folder(ssh, name, guestpath)
|
||||
|
|
|
@ -87,9 +87,16 @@ class Test::Unit::TestCase
|
|||
mock_vm.stubs(:actions).returns([action])
|
||||
mock_vm.stubs(:env).returns(mock_environment)
|
||||
|
||||
vm.stubs(:env).returns(mock_vm.env)
|
||||
|
||||
[mock_vm, vm, action]
|
||||
end
|
||||
|
||||
# Returns a linux system
|
||||
def linux_system(vm)
|
||||
Vagrant::Systems::Linux.new(vm)
|
||||
end
|
||||
|
||||
def stub_default_action_dependecies(mock)
|
||||
mock.stubs(:precedes).returns([])
|
||||
mock.stubs(:follows).returns([])
|
||||
|
|
|
@ -3,21 +3,35 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
|||
class HaltActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Halt)
|
||||
@runner.stubs(:system).returns(linux_system(@vm))
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@vm.stubs(:running?).returns(true)
|
||||
|
||||
@runner.system.stubs(:halt)
|
||||
@vm.stubs(:stop)
|
||||
@vm.stubs(:state).returns(:powered_off)
|
||||
end
|
||||
|
||||
should "invoke the 'halt' around callback" do
|
||||
halt_seq = sequence("halt_seq")
|
||||
@runner.expects(:invoke_around_callback).with(:halt).once.in_sequence(halt_seq).yields
|
||||
@vm.expects(:stop).in_sequence(halt_seq)
|
||||
@runner.expects(:invoke_around_callback).with(:halt).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "force the VM to stop" do
|
||||
should "halt with the system and NOT force VM to stop if powered off" do
|
||||
@vm.expects(:state).with(true).returns(:powered_off)
|
||||
|
||||
@runner.system.expects(:halt).once
|
||||
@vm.expects(:stop).never
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "halt with the system and force VM to stop if NOT powered off" do
|
||||
@vm.expects(:state).with(true).returns(:running)
|
||||
|
||||
@runner.system.expects(:halt).once
|
||||
@vm.expects(:stop).once
|
||||
@action.execute!
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
|||
class SharedFoldersActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::SharedFolders)
|
||||
@runner.stubs(:system).returns(Vagrant::Systems::Linux.new(@vm))
|
||||
@runner.stubs(:system).returns(linux_system(@vm))
|
||||
end
|
||||
|
||||
def stub_shared_folders
|
||||
|
|
|
@ -9,6 +9,26 @@ class LinuxSystemTest < Test::Unit::TestCase
|
|||
@instance = @klass.new(@vm)
|
||||
end
|
||||
|
||||
context "halting" do
|
||||
setup do
|
||||
@ssh_session = mock("ssh_session")
|
||||
@ssh = mock("ssh")
|
||||
@ssh.stubs(:execute).yields(@ssh_session)
|
||||
@vm.env.stubs(:ssh).returns(@ssh)
|
||||
|
||||
@real_vm = mock("real_vm")
|
||||
@real_vm.stubs(:state).returns(:powered_off)
|
||||
@vm.stubs(:vm).returns(@real_vm)
|
||||
end
|
||||
|
||||
should "execute halt via SSH" do
|
||||
@ssh_session.expects(:exec!).with("sudo halt").once
|
||||
@instance.halt
|
||||
end
|
||||
|
||||
# TODO: Sleep/timeout testing
|
||||
end
|
||||
|
||||
context "mounting shared folders" do
|
||||
setup do
|
||||
@ssh = mock("ssh")
|
||||
|
|
Loading…
Reference in New Issue