From dd91269491199f8596292e5193d46ba6c2e30f21 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 3 Aug 2016 11:34:03 -0700 Subject: [PATCH] guests: Prevent ssh disconnect from causing error on halt --- plugins/guests/bsd/cap/halt.rb | 2 +- plugins/guests/darwin/cap/halt.rb | 2 +- plugins/guests/esxi/cap/halt.rb | 2 +- plugins/guests/linux/cap/halt.rb | 2 +- plugins/guests/smartos/cap/halt.rb | 2 +- plugins/guests/solaris/cap/halt.rb | 2 +- plugins/guests/solaris11/cap/halt.rb | 2 +- plugins/guests/suse/cap/halt.rb | 2 +- plugins/guests/tinycore/cap/halt.rb | 2 +- test/unit/plugins/guests/bsd/cap/halt_test.rb | 12 ++++- .../plugins/guests/darwin/cap/halt_test.rb | 7 +++ .../unit/plugins/guests/esxi/cap/halt_test.rb | 44 +++++++++++++++++++ .../plugins/guests/linux/cap/halt_test.rb | 7 +++ .../plugins/guests/openbsd/cap/halt_test.rb | 2 +- .../plugins/guests/smartos/cap/halt_test.rb | 22 ++++++++-- .../plugins/guests/solaris/cap/halt_test.rb | 44 +++++++++++++++++++ .../plugins/guests/solaris11/cap/halt_test.rb | 44 +++++++++++++++++++ .../unit/plugins/guests/suse/cap/halt_test.rb | 7 +++ .../plugins/guests/tinycore/cap/halt_test.rb | 44 +++++++++++++++++++ 19 files changed, 235 insertions(+), 16 deletions(-) create mode 100644 test/unit/plugins/guests/esxi/cap/halt_test.rb create mode 100644 test/unit/plugins/guests/solaris/cap/halt_test.rb create mode 100644 test/unit/plugins/guests/solaris11/cap/halt_test.rb create mode 100644 test/unit/plugins/guests/tinycore/cap/halt_test.rb diff --git a/plugins/guests/bsd/cap/halt.rb b/plugins/guests/bsd/cap/halt.rb index f13379839..25fa3ef38 100644 --- a/plugins/guests/bsd/cap/halt.rb +++ b/plugins/guests/bsd/cap/halt.rb @@ -5,7 +5,7 @@ module VagrantPlugins def self.halt(machine) begin machine.communicate.sudo("/sbin/shutdown -p now", shell: "sh") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Do nothing, because it probably means the machine shut down # and SSH connection was lost. end diff --git a/plugins/guests/darwin/cap/halt.rb b/plugins/guests/darwin/cap/halt.rb index f48778ee2..7e381e21d 100644 --- a/plugins/guests/darwin/cap/halt.rb +++ b/plugins/guests/darwin/cap/halt.rb @@ -7,7 +7,7 @@ module VagrantPlugins # Darwin does not support the `-p` option like the rest of the # BSD-based guests, so it needs its own cap. machine.communicate.sudo("/sbin/shutdown -h now") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Do nothing because SSH connection closed and it probably # means the VM just shut down really fast. end diff --git a/plugins/guests/esxi/cap/halt.rb b/plugins/guests/esxi/cap/halt.rb index 7d1600389..d95fb7636 100644 --- a/plugins/guests/esxi/cap/halt.rb +++ b/plugins/guests/esxi/cap/halt.rb @@ -5,7 +5,7 @@ module VagrantPlugins def self.halt(machine) begin machine.communicate.execute("/bin/halt -d 0") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Ignore, this probably means connection closed because it # shut down. end diff --git a/plugins/guests/linux/cap/halt.rb b/plugins/guests/linux/cap/halt.rb index 6125a2082..60dc5dde4 100644 --- a/plugins/guests/linux/cap/halt.rb +++ b/plugins/guests/linux/cap/halt.rb @@ -5,7 +5,7 @@ module VagrantPlugins def self.halt(machine) begin machine.communicate.sudo("shutdown -h now") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Do nothing, because it probably means the machine shut down # and SSH connection was lost. end diff --git a/plugins/guests/smartos/cap/halt.rb b/plugins/guests/smartos/cap/halt.rb index c0178e388..7e10ee2cc 100644 --- a/plugins/guests/smartos/cap/halt.rb +++ b/plugins/guests/smartos/cap/halt.rb @@ -11,7 +11,7 @@ module VagrantPlugins begin machine.communicate.execute( "#{machine.config.smartos.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Ignore, this probably means connection closed because it # shut down. end diff --git a/plugins/guests/solaris/cap/halt.rb b/plugins/guests/solaris/cap/halt.rb index 3a60fd171..eea9a5c96 100644 --- a/plugins/guests/solaris/cap/halt.rb +++ b/plugins/guests/solaris/cap/halt.rb @@ -11,7 +11,7 @@ module VagrantPlugins begin machine.communicate.execute( "#{machine.config.solaris.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Ignore, this probably means connection closed because it # shut down. end diff --git a/plugins/guests/solaris11/cap/halt.rb b/plugins/guests/solaris11/cap/halt.rb index 4074a0da1..67e0b4219 100644 --- a/plugins/guests/solaris11/cap/halt.rb +++ b/plugins/guests/solaris11/cap/halt.rb @@ -15,7 +15,7 @@ module VagrantPlugins begin machine.communicate.execute( "#{machine.config.solaris11.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Ignore, this probably means connection closed because it # shut down. end diff --git a/plugins/guests/suse/cap/halt.rb b/plugins/guests/suse/cap/halt.rb index e6b20818b..7a1375e39 100644 --- a/plugins/guests/suse/cap/halt.rb +++ b/plugins/guests/suse/cap/halt.rb @@ -5,7 +5,7 @@ module VagrantPlugins def self.halt(machine) begin machine.communicate.sudo("/sbin/shutdown -h now") - rescue IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Do nothing, because it probably means the machine shut down # and SSH connection was lost. end diff --git a/plugins/guests/tinycore/cap/halt.rb b/plugins/guests/tinycore/cap/halt.rb index 97c045257..0789a4fc1 100644 --- a/plugins/guests/tinycore/cap/halt.rb +++ b/plugins/guests/tinycore/cap/halt.rb @@ -5,7 +5,7 @@ module VagrantPlugins def self.halt(machine) begin machine.communicate.sudo("poweroff") - rescue Net::SSH::Disconnect, IOError + rescue IOError, Vagrant::Errors::SSHDisconnected # Do nothing, because it probably means the machine shut down # and SSH connection was lost. end diff --git a/test/unit/plugins/guests/bsd/cap/halt_test.rb b/test/unit/plugins/guests/bsd/cap/halt_test.rb index 7ab3322b6..d645ed4a1 100644 --- a/test/unit/plugins/guests/bsd/cap/halt_test.rb +++ b/test/unit/plugins/guests/bsd/cap/halt_test.rb @@ -9,6 +9,7 @@ describe "VagrantPlugins::GuestBSD::Cap::Halt" do let(:machine) { double("machine") } let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + let(:shutdown_command) { "/sbin/shutdown -p now" } before do allow(machine).to receive(:communicate).and_return(comm) @@ -22,12 +23,19 @@ describe "VagrantPlugins::GuestBSD::Cap::Halt" do let(:cap) { caps.get(:halt) } it "runs the shutdown command" do - comm.expect_command("/sbin/shutdown -p now") + comm.expect_command(shutdown_command) cap.halt(machine) end it "ignores an IOError" do - comm.stub_command("/sbin/shutdown -p now", raise: IOError) + comm.stub_command(shutdown_command, raise: IOError) + expect { + cap.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) expect { cap.halt(machine) }.to_not raise_error diff --git a/test/unit/plugins/guests/darwin/cap/halt_test.rb b/test/unit/plugins/guests/darwin/cap/halt_test.rb index 0cce2836e..5827340dc 100644 --- a/test/unit/plugins/guests/darwin/cap/halt_test.rb +++ b/test/unit/plugins/guests/darwin/cap/halt_test.rb @@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestDarwin::Cap::Halt" do cap.halt(machine) }.to_not raise_error end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command("/sbin/shutdown -h now", raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end end end diff --git a/test/unit/plugins/guests/esxi/cap/halt_test.rb b/test/unit/plugins/guests/esxi/cap/halt_test.rb new file mode 100644 index 000000000..b0e488a02 --- /dev/null +++ b/test/unit/plugins/guests/esxi/cap/halt_test.rb @@ -0,0 +1,44 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestEsxi::Cap::Halt" do + let(:caps) do + VagrantPlugins::GuestEsxi::Plugin + .components + .guest_capabilities[:esxi] + end + + let(:shutdown_command){ "/bin/halt -d 0" } + let(:machine) { double("machine") } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(comm) + end + + after do + comm.verify_expectations! + end + + describe ".halt" do + let(:cap) { caps.get(:halt) } + + it "runs the shutdown command" do + comm.expect_command(shutdown_command) + cap.halt(machine) + end + + it "ignores an IOError" do + comm.stub_command(shutdown_command, raise: IOError) + expect { + cap.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end + end +end diff --git a/test/unit/plugins/guests/linux/cap/halt_test.rb b/test/unit/plugins/guests/linux/cap/halt_test.rb index 7b90e7bed..81f682aa1 100644 --- a/test/unit/plugins/guests/linux/cap/halt_test.rb +++ b/test/unit/plugins/guests/linux/cap/halt_test.rb @@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestLinux::Cap::Halt" do cap.halt(machine) }.to_not raise_error end + + it "does not raise a SSHDisconnected" do + comm.stub_command("shutdown -h now", raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end end end diff --git a/test/unit/plugins/guests/openbsd/cap/halt_test.rb b/test/unit/plugins/guests/openbsd/cap/halt_test.rb index 17ec5c913..8f94a3b9b 100644 --- a/test/unit/plugins/guests/openbsd/cap/halt_test.rb +++ b/test/unit/plugins/guests/openbsd/cap/halt_test.rb @@ -33,7 +33,7 @@ describe "VagrantPlugins::GuestOpenBSD::Cap::Halt" do }.to_not raise_error end - it "ignores an Vagrant::Errors::SSHDisconnected" do + it "ignores a Vagrant::Errors::SSHDisconnected" do comm.stub_command("/sbin/shutdown -p -h now", raise: Vagrant::Errors::SSHDisconnected) expect { cap.halt(machine) diff --git a/test/unit/plugins/guests/smartos/cap/halt_test.rb b/test/unit/plugins/guests/smartos/cap/halt_test.rb index 664b77ec8..137749489 100644 --- a/test/unit/plugins/guests/smartos/cap/halt_test.rb +++ b/test/unit/plugins/guests/smartos/cap/halt_test.rb @@ -1,10 +1,11 @@ require_relative "../../../../base" -describe "VagrantPlugins::VagrantPlugins::Cap::Halt" do +describe "VagrantPlugins::GuestSmartos::Cap::Halt" do let(:plugin) { VagrantPlugins::GuestSmartos::Plugin.components.guest_capabilities[:smartos].get(:halt) } let(:machine) { double("machine") } - let(:config) { double("config", smartos: VagrantPlugins::GuestSmartos::Config.new) } + let(:config) { double("config", smartos: double("smartos", suexec_cmd: 'pfexec')) } let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + let(:shutdown_command){ "pfexec /usr/sbin/shutdown -y -i5 -g0" } before do machine.stub(:communicate).and_return(communicator) @@ -17,9 +18,22 @@ describe "VagrantPlugins::VagrantPlugins::Cap::Halt" do describe ".halt" do it "sends a shutdown signal" do - communicator.expect_command(%Q(pfexec /usr/sbin/shutdown -y -i5 -g0)) + communicator.expect_command(shutdown_command) plugin.halt(machine) end + + it "ignores an IOError" do + communicator.stub_command(shutdown_command, raise: IOError) + expect { + plugin.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + communicator.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) + expect { + plugin.halt(machine) + }.to_not raise_error + end end end - diff --git a/test/unit/plugins/guests/solaris/cap/halt_test.rb b/test/unit/plugins/guests/solaris/cap/halt_test.rb new file mode 100644 index 000000000..e0f631120 --- /dev/null +++ b/test/unit/plugins/guests/solaris/cap/halt_test.rb @@ -0,0 +1,44 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestSolaris::Cap::Halt" do + let(:caps) do + VagrantPlugins::GuestSolaris::Plugin + .components + .guest_capabilities[:solaris] + end + + let(:shutdown_command){ "sudo /usr/sbin/shutdown -y -i5 -g0" } + let(:machine) { double("machine", config: double("config", solaris: double("solaris", suexec_cmd: 'sudo'))) } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(comm) + end + + after do + comm.verify_expectations! + end + + describe ".halt" do + let(:cap) { caps.get(:halt) } + + it "runs the shutdown command" do + comm.expect_command(shutdown_command) + cap.halt(machine) + end + + it "ignores an IOError" do + comm.stub_command(shutdown_command, raise: IOError) + expect { + cap.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end + end +end diff --git a/test/unit/plugins/guests/solaris11/cap/halt_test.rb b/test/unit/plugins/guests/solaris11/cap/halt_test.rb new file mode 100644 index 000000000..3c4d64eb0 --- /dev/null +++ b/test/unit/plugins/guests/solaris11/cap/halt_test.rb @@ -0,0 +1,44 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestSolaris11::Cap::Halt" do + let(:caps) do + VagrantPlugins::GuestSolaris11::Plugin + .components + .guest_capabilities[:solaris11] + end + + let(:shutdown_command){ "sudo /usr/sbin/shutdown -y -i5 -g0" } + let(:machine) { double("machine", config: double("config", solaris11: double("solaris11", suexec_cmd: 'sudo'))) } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(comm) + end + + after do + comm.verify_expectations! + end + + describe ".halt" do + let(:cap) { caps.get(:halt) } + + it "runs the shutdown command" do + comm.expect_command(shutdown_command) + cap.halt(machine) + end + + it "ignores an IOError" do + comm.stub_command(shutdown_command, raise: IOError) + expect { + cap.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end + end +end diff --git a/test/unit/plugins/guests/suse/cap/halt_test.rb b/test/unit/plugins/guests/suse/cap/halt_test.rb index acce6536d..7b998aad1 100644 --- a/test/unit/plugins/guests/suse/cap/halt_test.rb +++ b/test/unit/plugins/guests/suse/cap/halt_test.rb @@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestSUSE::Cap::Halt" do cap.halt(machine) }.to_not raise_error end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command("shutdown -h now", raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end end end diff --git a/test/unit/plugins/guests/tinycore/cap/halt_test.rb b/test/unit/plugins/guests/tinycore/cap/halt_test.rb new file mode 100644 index 000000000..99ebb1fea --- /dev/null +++ b/test/unit/plugins/guests/tinycore/cap/halt_test.rb @@ -0,0 +1,44 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestTinyCore::Cap::Halt" do + let(:caps) do + VagrantPlugins::GuestTinyCore::Plugin + .components + .guest_capabilities[:tinycore] + end + + let(:shutdown_command){ "poweroff" } + let(:machine) { double("machine") } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(comm) + end + + after do + comm.verify_expectations! + end + + describe ".halt" do + let(:cap) { caps.get(:halt) } + + it "runs the shutdown command" do + comm.expect_command(shutdown_command) + cap.halt(machine) + end + + it "ignores an IOError" do + comm.stub_command(shutdown_command, raise: IOError) + expect { + cap.halt(machine) + }.to_not raise_error + end + + it "ignores a Vagrant::Errors::SSHDisconnected" do + comm.stub_command(shutdown_command, raise: Vagrant::Errors::SSHDisconnected) + expect { + cap.halt(machine) + }.to_not raise_error + end + end +end