From 911406ed4a1c5f4bec0f866c2e58245c7018ab26 Mon Sep 17 00:00:00 2001 From: Shawn Neal Date: Tue, 24 Jun 2014 14:26:03 -0700 Subject: [PATCH] Addressed issues with Windows guest renaming on Win7/8 Removed dependency upon netdom which is not always available on all Windows versions. This implementation that uses PowerShell and WMI should work on all OS and PowerShell versions. Fixed another issue where host renames would always happen when the hostname was longer than 15 characters. The COMPUTERNAME environment variable only returns the first 15 characters so we no longer use that to check the current host name. --- .../guests/windows/cap/change_host_name.rb | 23 ++++++++++++------ .../windows/cap/change_host_name_test.rb | 24 +++++++++++-------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/plugins/guests/windows/cap/change_host_name.rb b/plugins/guests/windows/cap/change_host_name.rb index 9902c8565..fa48a3137 100644 --- a/plugins/guests/windows/cap/change_host_name.rb +++ b/plugins/guests/windows/cap/change_host_name.rb @@ -9,14 +9,23 @@ module VagrantPlugins def self.change_host_name_and_wait(machine, name, sleep_timeout) # If the configured name matches the current name, then bail - return if machine.communicate.test("if ($env:ComputerName -eq '#{name}') { exit 0 } exit 1") + # We cannot use %ComputerName% because it truncates at 15 chars + return if machine.communicate.test("if ([System.Net.Dns]::GetHostName() -eq '#{name}') { exit 0 } exit 1") + + # Rename and reboot host if rename succeeded + 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 - # Rename and then reboot in one step - exit_code = machine.communicate.execute( - "netdom renamecomputer \"$Env:COMPUTERNAME\" /NewName:#{name} /Force /Reboot:0", - error_check: false) - - raise Errors::RenameComputerFailed if exit_code != 0 + machine.communicate.execute( + script, + error_class: Errors::RenameComputerFailed, + error_key: :rename_computer_failed) # Don't continue until the machine has shutdown and rebooted sleep(sleep_timeout) diff --git a/test/unit/plugins/guests/windows/cap/change_host_name_test.rb b/test/unit/plugins/guests/windows/cap/change_host_name_test.rb index b90df3d3f..1f8b45170 100644 --- a/test/unit/plugins/guests/windows/cap/change_host_name_test.rb +++ b/test/unit/plugins/guests/windows/cap/change_host_name_test.rb @@ -8,7 +8,6 @@ describe "VagrantPlugins::GuestWindows::Cap::ChangeHostName" do end let(:machine) { double("machine") } let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } - let(:old_hostname) { 'oldhostname' } before do allow(machine).to receive(:communicate).and_return(communicator) @@ -19,19 +18,24 @@ describe "VagrantPlugins::GuestWindows::Cap::ChangeHostName" do end describe ".change_host_name" do + + let(:rename_script) { <<-EOH + $computer = Get-WmiObject -Class Win32_ComputerSystem + $retval = $computer.rename("newhostname").returnvalue + if ($retval -eq 0) { + shutdown /r /t 5 /f /d p:4:1 /c "Vagrant Rename Computer" + } + exit $retval + EOH + } + it "changes the hostname" do - communicator.stub_command('if (!($env:ComputerName -eq \'newhostname\')) { exit 0 } exit 1', exit_code: 0) - communicator.stub_command('netdom renamecomputer "$Env:COMPUTERNAME" /NewName:newhostname /Force /Reboot:0', + communicator.stub_command( + 'if (!([System.Net.Dns]::GetHostName() -eq \'newhostname\')) { exit 0 } exit 1', exit_code: 0) + communicator.stub_command(rename_script, exit_code: 0) described_class.change_host_name_and_wait(machine, 'newhostname', 0) end - it "raises RenameComputerFailed when exit code is non-zero" do - communicator.stub_command('if (!($env:ComputerName -eq \'newhostname\')) { exit 0 } exit 1', exit_code: 0) - communicator.stub_command('netdom renamecomputer "$Env:COMPUTERNAME" /NewName:newhostname /Force /Reboot:0', - exit_code: 123) - expect { described_class.change_host_name_and_wait(machine, 'newhostname', 0) }. - to raise_error(VagrantPlugins::GuestWindows::Errors::RenameComputerFailed) - end end end