diff --git a/plugins/guests/windows/cap/change_host_name.rb b/plugins/guests/windows/cap/change_host_name.rb index 8526247f3..656a8805b 100644 --- a/plugins/guests/windows/cap/change_host_name.rb +++ b/plugins/guests/windows/cap/change_host_name.rb @@ -4,8 +4,6 @@ module VagrantPlugins module GuestWindows module Cap module ChangeHostName - MAX_REBOOT_DURATION = 120 - def self.change_host_name(machine, name) change_host_name_and_wait(machine, name, machine.config.vm.graceful_halt_timeout) end @@ -20,9 +18,6 @@ module VagrantPlugins script = <<-EOH $computer = Get-WmiObject -Class Win32_ComputerSystem $retval = $computer.rename("#{name}").returnvalue - if ($retval -eq 0) { - shutdown /r /t 5 /f /d p:4:1 /c "Vagrant Rename Computer" - } exit $retval EOH @@ -31,24 +26,7 @@ module VagrantPlugins error_class: Errors::RenameComputerFailed, error_key: :rename_computer_failed) - - wait_remaining = MAX_REBOOT_DURATION - begin - # Don't continue until the machine has shutdown and rebooted - if machine.guest.capability?(:wait_for_reboot) - machine.guest.capability(:wait_for_reboot) - else - @logger.debug("No wait_for_reboot capability, sleeping for #{sleep_timeout} instead...") - # use graceful_halt_timeout only if guest cannot wait for reboot - sleep(sleep_timeout) - end - rescue Vagrant::Errors::MachineGuestNotReady => e - raise if wait_remaining < 0 - @logger.warn("Machine not ready, cannot wait for reboot yet. Trying again") - sleep(5) - wait_remaining -= 5 - retry - end + machine.guest.capability(:reboot) end end end diff --git a/plugins/guests/windows/cap/reboot.rb b/plugins/guests/windows/cap/reboot.rb index 2534a1e2b..f8354096b 100644 --- a/plugins/guests/windows/cap/reboot.rb +++ b/plugins/guests/windows/cap/reboot.rb @@ -1,21 +1,50 @@ +require "log4r" + module VagrantPlugins module GuestWindows module Cap class Reboot - def self.wait_for_reboot(machine) - # Technically it should be possible to make it work with SSH - # too, but we don't yet. - return if machine.config.vm.communicator != :winrm + MAX_REBOOT_RETRY_DURATION = 120 + + def self.reboot(machine) + @logger = Log4r::Logger.new("vagrant::windows::reboot") + reboot_script = "shutdown /r /t 5 /f /d p:4:1 /c \"Vagrant Reboot Computer\"" + + comm = machine.communicate script = File.expand_path("../../scripts/reboot_detect.ps1", __FILE__) script = File.read(script) - while machine.communicate.execute(script, error_check: false) != 0 + if comm.test(script, error_check: false, shell: :powershell) + @logger.debug("Issuing reboot command for guest") + comm.execute(reboot_script, shell: :powershell) + else + @logger.debug("A reboot is already in progress") + end + + @logger.debug("Waiting for machine to finish rebooting") + + wait_remaining = MAX_REBOOT_RETRY_DURATION + begin + wait_for_reboot(machine) + rescue Vagrant::Errors::MachineGuestNotReady, WinRM::WinRMHTTPTransportError => e + raise if wait_remaining < 0 + @logger.warn("Machine not ready, cannot start reboot yet. Trying again") + sleep(5) + wait_remaining -= 5 + retry + end + end + + def self.wait_for_reboot(machine) + script = File.expand_path("../../scripts/reboot_detect.ps1", __FILE__) + script = File.read(script) + while machine.communicate.execute(script, error_check: false, shell: :powershell) != 0 sleep 10 end # This re-establishes our symbolic links if they were # created between now and a reboot - machine.communicate.execute("net use", error_check: false) + machine.communicate.execute("net use", error_check: false, shell: :powershell) end end end diff --git a/plugins/guests/windows/plugin.rb b/plugins/guests/windows/plugin.rb index 76124f6b4..a4308d4a2 100644 --- a/plugins/guests/windows/plugin.rb +++ b/plugins/guests/windows/plugin.rb @@ -64,6 +64,11 @@ module VagrantPlugins Cap::Reboot end + guest_capability(:windows, :reboot) do + require_relative "cap/reboot" + Cap::Reboot + end + guest_capability(:windows, :choose_addressable_ip_addr) do require_relative "cap/choose_addressable_ip_addr" Cap::ChooseAddressableIPAddr diff --git a/test/unit/plugins/guests/windows/cap/reboot_test.rb b/test/unit/plugins/guests/windows/cap/reboot_test.rb index afa50d381..723f3c7d6 100644 --- a/test/unit/plugins/guests/windows/cap/reboot_test.rb +++ b/test/unit/plugins/guests/windows/cap/reboot_test.rb @@ -17,6 +17,12 @@ describe "VagrantPlugins::GuestWindows::Cap::Reboot" do allow(config).to receive(:vm).and_return(vm) end + describe ".reboot" do + before do + allow(vm).to receive(:communicator).and_return(:winrm) + end + end + describe "winrm communicator" do before do allow(vm).to receive(:communicator).and_return(:winrm) @@ -24,15 +30,15 @@ describe "VagrantPlugins::GuestWindows::Cap::Reboot" do describe ".wait_for_reboot" do it "runs reboot detect script" do - expect(communicator).to receive(:execute).with(/# Function/, { error_check: false }).and_return(0) + expect(communicator).to receive(:execute).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0) allow(communicator).to receive(:execute) described_class.wait_for_reboot(machine) end - + it "fixes symlinks to network shares" do allow(communicator).to receive(:execute).and_return(0) - expect(communicator).to receive(:execute).with('net use', { error_check: false }) + expect(communicator).to receive(:execute).with('net use', { error_check: false, shell: :powershell }) described_class.wait_for_reboot(machine) end @@ -45,8 +51,9 @@ describe "VagrantPlugins::GuestWindows::Cap::Reboot" do end describe ".wait_for_reboot" do - it "does not execute Windows reboot detect script" do - expect(communicator).to_not receive(:execute) + it "does execute Windows reboot detect script" do + expect(communicator).to receive(:execute).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0) + expect(communicator).to receive(:execute).with('net use', { error_check: false, shell: :powershell }) described_class.wait_for_reboot(machine) end end