communicators/winrm: respect boot_timeout when fetching winrm_info

We gained a ton of improvemnts to WinRM error handling in
https://github.com/mitchellh/vagrant/pull/4943, but we also got one bug.

The new code raises an exception when `winrm_info` does not return right
away. This was preventing us from catching the retry/timout logic that's
meant to wait until boot_timeout for the WinRM communicator to be ready.

This restores the proper behavior by rescuing the WinRMNotReady
exception and continuing to retry until the surrounding timeout fires.
This commit is contained in:
Paul Hinze 2015-09-02 16:36:23 -05:00
parent 3b7117b689
commit 1e84cc4d6a
2 changed files with 41 additions and 4 deletions

View File

@ -30,7 +30,12 @@ module VagrantPlugins
# Wait for winrm_info to be ready
winrm_info = nil
while true
winrm_info = Helper.winrm_info(@machine)
winrm_info = nil
begin
winrm_info = Helper.winrm_info(@machine)
rescue Errors::WinRMNotReady
@logger.debug("WinRM not ready yet; retrying until boot_timeout is reached.")
end
break if winrm_info
sleep 0.5
end

View File

@ -5,10 +5,11 @@ require Vagrant.source_root.join("plugins/communicators/winrm/communicator")
describe VagrantPlugins::CommunicatorWinRM::Communicator do
include_context "unit"
let(:winrm) { double("winrm", timeout: 1) }
let(:winrm) { double("winrm", timeout: 1, host: nil, port: 5986, guest_port: 5986) }
let(:config) { double("config", winrm: winrm) }
let(:machine) { double("machine", config: config) }
let(:provider) { double("provider") }
let(:ui) { double("ui") }
let(:machine) { double("machine", config: config, provider: provider, ui: ui) }
let(:shell) { double("shell") }
subject do
@ -22,6 +23,37 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do
allow(shell).to receive(:password).and_return('password')
end
describe ".wait_for_ready" do
context "with no winrm_info capability and no static config (default scenario)" do
before do
# No default providers support this capability
allow(provider).to receive(:capability?).with(:winrm_info).and_return(false)
# Get us through the detail prints
allow(ui).to receive(:detail)
allow(shell).to receive(:host)
allow(shell).to receive(:port)
allow(shell).to receive(:username)
allow(shell).to receive(:config) { double("config", transport: nil)}
end
context "when ssh_info requires a multiple tries before it is ready" do
before do
allow(machine).to receive(:ssh_info).and_return(nil, {
host: '10.1.2.3',
port: '22',
})
# Makes ready? return true
allow(shell).to receive(:powershell).with("hostname").and_return({ exitcode: 0 })
end
it "retries ssh_info until ready" do
expect(subject.wait_for_ready(2)).to eq(true)
end
end
end
end
describe ".ready?" do
it "returns true if hostname command executes without error" do
expect(shell).to receive(:powershell).with("hostname").and_return({ exitcode: 0 })