From 1e84cc4d6aa5eff2f27fc2e13663aa9734336a4f Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 2 Sep 2015 16:36:23 -0500 Subject: [PATCH] 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. --- plugins/communicators/winrm/communicator.rb | 7 +++- .../communicators/winrm/communicator_test.rb | 38 +++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/plugins/communicators/winrm/communicator.rb b/plugins/communicators/winrm/communicator.rb index fdb3fe615..b14b28efa 100644 --- a/plugins/communicators/winrm/communicator.rb +++ b/plugins/communicators/winrm/communicator.rb @@ -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 diff --git a/test/unit/plugins/communicators/winrm/communicator_test.rb b/test/unit/plugins/communicators/winrm/communicator_test.rb index ceea0985d..e98f646b3 100644 --- a/test/unit/plugins/communicators/winrm/communicator_test.rb +++ b/test/unit/plugins/communicators/winrm/communicator_test.rb @@ -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 })