SSH.up? timeout slowly ramps up based on configuration values, giving later attempts more time.
This commit is contained in:
parent
b03af8ccc2
commit
2c1483ae80
|
@ -9,7 +9,9 @@ Vagrant::Config.run do |config|
|
||||||
config.ssh.host = "localhost"
|
config.ssh.host = "localhost"
|
||||||
config.ssh.forwarded_port_key = "ssh"
|
config.ssh.forwarded_port_key = "ssh"
|
||||||
config.ssh.max_tries = 10
|
config.ssh.max_tries = 10
|
||||||
config.ssh.timeout = 30
|
config.ssh.timeout = 5
|
||||||
|
config.ssh.retry_timeout_delta = 5
|
||||||
|
config.ssh.max_timeout_delta = 30
|
||||||
|
|
||||||
config.vm.box_ovf = "box.ovf"
|
config.vm.box_ovf = "box.ovf"
|
||||||
config.vm.base_mac = "0800279C2E42"
|
config.vm.base_mac = "0800279C2E42"
|
||||||
|
|
|
@ -29,13 +29,18 @@ error
|
||||||
def wait_for_boot
|
def wait_for_boot
|
||||||
logger.info "Waiting for VM to boot..."
|
logger.info "Waiting for VM to boot..."
|
||||||
|
|
||||||
|
current_timeout = Vagrant.config.ssh.timeout
|
||||||
|
max_timeout = current_timeout + Vagrant.config.ssh.max_timeout_delta
|
||||||
|
|
||||||
Vagrant.config[:ssh][:max_tries].to_i.times do |i|
|
Vagrant.config[:ssh][:max_tries].to_i.times do |i|
|
||||||
logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..."
|
logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..."
|
||||||
|
|
||||||
if Vagrant::SSH.up?
|
if Vagrant::SSH.up?(current_timeout)
|
||||||
logger.info "VM booted and ready for use!"
|
logger.info "VM booted and ready for use!"
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
current_timeout += Vagrant.config.ssh.retry_timeout_delta unless current_timeout >= max_timeout
|
||||||
end
|
end
|
||||||
|
|
||||||
logger.info "Failed to connect to VM! Failed to boot?"
|
logger.info "Failed to connect to VM! Failed to boot?"
|
||||||
|
|
|
@ -64,6 +64,8 @@ module Vagrant
|
||||||
attr_accessor :forwarded_port_key
|
attr_accessor :forwarded_port_key
|
||||||
attr_accessor :max_tries
|
attr_accessor :max_tries
|
||||||
attr_accessor :timeout
|
attr_accessor :timeout
|
||||||
|
attr_accessor :retry_timeout_delta
|
||||||
|
attr_accessor :max_timeout_delta
|
||||||
end
|
end
|
||||||
|
|
||||||
class VMConfig < Base
|
class VMConfig < Base
|
||||||
|
|
|
@ -25,11 +25,13 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def up?
|
def up?(timeout=nil)
|
||||||
|
timeout ||= Vagrant.config.ssh.timeout
|
||||||
|
|
||||||
check_thread = Thread.new do
|
check_thread = Thread.new do
|
||||||
begin
|
begin
|
||||||
Thread.current[:result] = false
|
Thread.current[:result] = false
|
||||||
Net::SSH.start(Vagrant.config.ssh.host, Vagrant.config.ssh.username, :port => port, :password => Vagrant.config.ssh.password, :timeout => Vagrant.config.ssh.timeout) do |ssh|
|
Net::SSH.start(Vagrant.config.ssh.host, Vagrant.config.ssh.username, :port => port, :password => Vagrant.config.ssh.password, :timeout => timeout) do |ssh|
|
||||||
Thread.current[:result] = true
|
Thread.current[:result] = true
|
||||||
end
|
end
|
||||||
rescue Errno::ECONNREFUSED, Net::SSH::Disconnect
|
rescue Errno::ECONNREFUSED, Net::SSH::Disconnect
|
||||||
|
@ -37,7 +39,7 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
check_thread.join(Vagrant.config.ssh.timeout)
|
check_thread.join(timeout)
|
||||||
return check_thread[:result]
|
return check_thread[:result]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ class Test::Unit::TestCase
|
||||||
config.ssh.forwarded_port_key = "ssh"
|
config.ssh.forwarded_port_key = "ssh"
|
||||||
config.ssh.max_tries = 10
|
config.ssh.max_tries = 10
|
||||||
config.ssh.timeout = 10
|
config.ssh.timeout = 10
|
||||||
|
config.ssh.retry_timeout_delta = 5
|
||||||
|
config.ssh.max_timeout_delta = 30
|
||||||
|
|
||||||
config.vm.box = "foo"
|
config.vm.box = "foo"
|
||||||
config.vm.box_ovf = "box.ovf"
|
config.vm.box_ovf = "box.ovf"
|
||||||
|
|
|
@ -51,5 +51,27 @@ class BootActionTest < Test::Unit::TestCase
|
||||||
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i).returns(false)
|
Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i).returns(false)
|
||||||
assert !@action.wait_for_boot
|
assert !@action.wait_for_boot
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "slowly increase timeout given to up? up to maximum specified" do
|
||||||
|
@timeout = 30
|
||||||
|
@retry_delta = 5
|
||||||
|
@max_delta = 30
|
||||||
|
|
||||||
|
mock_config do |config|
|
||||||
|
config.ssh.timeout = @timeout
|
||||||
|
config.ssh.retry_timeout_delta = @retry_delta
|
||||||
|
config.ssh.max_timeout_delta = @max_delta
|
||||||
|
end
|
||||||
|
|
||||||
|
up_sequence = sequence("up_seq")
|
||||||
|
current_timeout = @timeout
|
||||||
|
max_timeout = @timeout + @max_delta
|
||||||
|
Vagrant.config.ssh.max_tries.times do |i|
|
||||||
|
Vagrant::SSH.expects(:up?).with(current_timeout).returns(false).in_sequence(up_sequence)
|
||||||
|
current_timeout += @retry_delta unless current_timeout >= max_timeout
|
||||||
|
end
|
||||||
|
|
||||||
|
assert !@action.wait_for_boot
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,26 +56,59 @@ class SshTest < Test::Unit::TestCase
|
||||||
context "checking if host is up" do
|
context "checking if host is up" do
|
||||||
setup do
|
setup do
|
||||||
mock_config
|
mock_config
|
||||||
end
|
|
||||||
|
|
||||||
should "return true if SSH connection works" do
|
@timeout = 7
|
||||||
Net::SSH.expects(:start).yields("success")
|
|
||||||
assert Vagrant::SSH.up?
|
|
||||||
end
|
|
||||||
|
|
||||||
should "return false if SSH connection times out" do
|
|
||||||
Net::SSH.expects(:start)
|
|
||||||
assert !Vagrant::SSH.up?
|
|
||||||
end
|
|
||||||
|
|
||||||
should "allow the thread the configured timeout time" do
|
|
||||||
@thread = mock("thread")
|
@thread = mock("thread")
|
||||||
@thread.stubs(:[])
|
@thread.stubs(:[])
|
||||||
|
@thread.stubs(:[]=)
|
||||||
|
@thread.stubs(:join)
|
||||||
|
Thread.stubs(:current).returns(@thread)
|
||||||
|
Thread.stubs(:new).returns(@thread).yields
|
||||||
|
|
||||||
|
Net::SSH.stubs(:start)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "return the value of result in thread" do
|
||||||
|
result = mock("result")
|
||||||
|
@thread.expects(:[]).with(:result).returns(result)
|
||||||
|
assert_equal result, Vagrant::SSH.up?
|
||||||
|
end
|
||||||
|
|
||||||
|
should "start SSH with proper configuration" do
|
||||||
|
Net::SSH.expects(:start).with(Vagrant.config.ssh.host, Vagrant.config.ssh.username, :port => Vagrant::SSH.port, :password => Vagrant.config.ssh.password, :timeout => Vagrant.config.ssh.timeout).once
|
||||||
|
Vagrant::SSH.up?
|
||||||
|
end
|
||||||
|
|
||||||
|
should "start SSH with proper timeout value if given" do
|
||||||
|
Net::SSH.expects(:start).with(Vagrant.config.ssh.host, Vagrant.config.ssh.username, :port => Vagrant::SSH.port, :password => Vagrant.config.ssh.password, :timeout => @timeout).once
|
||||||
|
Vagrant::SSH.up?(@timeout)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "set result to true if SSH connection works" do
|
||||||
|
@thread.expects(:[]=).with(:result, true)
|
||||||
|
Net::SSH.expects(:start).yields("success")
|
||||||
|
Vagrant::SSH.up?
|
||||||
|
end
|
||||||
|
|
||||||
|
should "set result to false if SSH connection times out" do
|
||||||
|
@thread.expects(:[]=).with(:result, false)
|
||||||
|
Net::SSH.expects(:start)
|
||||||
|
Vagrant::SSH.up?
|
||||||
|
end
|
||||||
|
|
||||||
|
should "allow the thread the configured timeout time by default" do
|
||||||
Thread.expects(:new).returns(@thread)
|
Thread.expects(:new).returns(@thread)
|
||||||
@thread.expects(:join).with(Vagrant.config.ssh.timeout).once
|
@thread.expects(:join).with(Vagrant.config.ssh.timeout).once
|
||||||
Vagrant::SSH.up?
|
Vagrant::SSH.up?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "allow the thread the given timeout time if given" do
|
||||||
|
Thread.expects(:new).returns(@thread)
|
||||||
|
@thread.expects(:join).with(@timeout).once
|
||||||
|
Vagrant::SSH.up?(@timeout)
|
||||||
|
end
|
||||||
|
|
||||||
should "return false if the connection is refused" do
|
should "return false if the connection is refused" do
|
||||||
Net::SSH.expects(:start).raises(Errno::ECONNREFUSED)
|
Net::SSH.expects(:start).raises(Errno::ECONNREFUSED)
|
||||||
assert_nothing_raised {
|
assert_nothing_raised {
|
||||||
|
|
Loading…
Reference in New Issue