Signal trapping for SIGINT waits for busy signal to go low
This commit is contained in:
parent
816b29eb18
commit
3d27d47d34
|
@ -4,8 +4,10 @@ module Vagrant
|
||||||
def execute!
|
def execute!
|
||||||
@vm.invoke_callback(:before_import)
|
@vm.invoke_callback(:before_import)
|
||||||
|
|
||||||
logger.info "Importing base VM (#{Vagrant.config[:vm][:base]})..."
|
Busy.busy do
|
||||||
@vm.vm = VirtualBox::VM.import(File.expand_path(Vagrant.config[:vm][:base]))
|
logger.info "Importing base VM (#{Vagrant.config[:vm][:base]})..."
|
||||||
|
@vm.vm = VirtualBox::VM.import(File.expand_path(Vagrant.config[:vm][:base]))
|
||||||
|
end
|
||||||
|
|
||||||
@vm.invoke_callback(:after_import)
|
@vm.invoke_callback(:after_import)
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,8 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
class Busy
|
class Busy
|
||||||
|
extend Vagrant::Util
|
||||||
|
|
||||||
@@busy = false
|
@@busy = false
|
||||||
@@mutex = Mutex.new
|
@@mutex = Mutex.new
|
||||||
|
|
||||||
|
@ -23,15 +25,34 @@ module Vagrant
|
||||||
def busy(&block)
|
def busy(&block)
|
||||||
@@mutex.synchronize do
|
@@mutex.synchronize do
|
||||||
begin
|
begin
|
||||||
|
Signal.trap("INT") { wait_for_not_busy }
|
||||||
Busy.busy = true
|
Busy.busy = true
|
||||||
yield
|
runner = Thread.new(block) { block.call }
|
||||||
|
runner.join
|
||||||
ensure
|
ensure
|
||||||
# In the case an exception is thrown, make sure we restore
|
# In the case an exception is thrown, make sure we restore
|
||||||
# busy back to some sane state.
|
# busy back to some sane state.
|
||||||
Busy.busy = false
|
Busy.busy = false
|
||||||
|
|
||||||
|
# And restore the INT trap to the default
|
||||||
|
Signal.trap("INT", "DEFAULT")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wait_for_not_busy(sleeptime=5)
|
||||||
|
Thread.new do
|
||||||
|
# Wait while the app is busy
|
||||||
|
loop do
|
||||||
|
break unless busy?
|
||||||
|
logger.info "Waiting for vagrant to clean itself up..."
|
||||||
|
sleep sleeptime
|
||||||
|
end
|
||||||
|
|
||||||
|
# Exit out of the entire script
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,11 @@ class ImportActionTest < Test::Unit::TestCase
|
||||||
VirtualBox::VM.stubs(:import)
|
VirtualBox::VM.stubs(:import)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "run in a busy block" do
|
||||||
|
Vagrant::Busy.expects(:busy).once
|
||||||
|
@import.execute!
|
||||||
|
end
|
||||||
|
|
||||||
should "invoke before/after callbacks around the import" do
|
should "invoke before/after callbacks around the import" do
|
||||||
callback_seq = sequence("callback_seq")
|
callback_seq = sequence("callback_seq")
|
||||||
@mock_vm.expects(:invoke_callback).with(:before_import).once.in_sequence(callback_seq)
|
@mock_vm.expects(:invoke_callback).with(:before_import).once.in_sequence(callback_seq)
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||||
|
|
||||||
class BusyTest < Test::Unit::TestCase
|
class BusyTest < Test::Unit::TestCase
|
||||||
|
context "waiting for not busy" do
|
||||||
|
# TODO: Need to test this method
|
||||||
|
end
|
||||||
|
|
||||||
context "during an action in a busy block" do
|
context "during an action in a busy block" do
|
||||||
should "report as busy" do
|
should "report as busy" do
|
||||||
Vagrant.busy do
|
Vagrant.busy do
|
||||||
|
@ -33,5 +37,21 @@ class BusyTest < Test::Unit::TestCase
|
||||||
# While the above thread is executing vagrant should be busy
|
# While the above thread is executing vagrant should be busy
|
||||||
assert Vagrant.busy?
|
assert Vagrant.busy?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "run the action in a new thread" do
|
||||||
|
runner_thread = nil
|
||||||
|
Vagrant.busy do
|
||||||
|
runner_thread = Thread.current
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_not_equal Thread.current, runner_thread
|
||||||
|
end
|
||||||
|
|
||||||
|
should "trap INT" do
|
||||||
|
trap_seq = sequence("trap_seq")
|
||||||
|
Signal.expects(:trap).with("INT", anything).once.in_sequence(trap_seq)
|
||||||
|
Signal.expects(:trap).with("INT", "DEFAULT").once.in_sequence(trap_seq)
|
||||||
|
Vagrant.busy do; end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue