Merge pull request #7675 from chrisroberts/en/linux-cap-halt

guests: Prevent ssh disconnect from causing error on halt
This commit is contained in:
Chris Roberts 2016-08-12 16:47:22 -07:00 committed by GitHub
commit b87e02205c
19 changed files with 235 additions and 16 deletions

View File

@ -5,7 +5,7 @@ module VagrantPlugins
def self.halt(machine) def self.halt(machine)
begin begin
machine.communicate.sudo("/sbin/shutdown -p now", shell: "sh") 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 # Do nothing, because it probably means the machine shut down
# and SSH connection was lost. # and SSH connection was lost.
end end

View File

@ -7,7 +7,7 @@ module VagrantPlugins
# Darwin does not support the `-p` option like the rest of the # Darwin does not support the `-p` option like the rest of the
# BSD-based guests, so it needs its own cap. # BSD-based guests, so it needs its own cap.
machine.communicate.sudo("/sbin/shutdown -h now") machine.communicate.sudo("/sbin/shutdown -h now")
rescue IOError rescue IOError, Vagrant::Errors::SSHDisconnected
# Do nothing because SSH connection closed and it probably # Do nothing because SSH connection closed and it probably
# means the VM just shut down really fast. # means the VM just shut down really fast.
end end

View File

@ -5,7 +5,7 @@ module VagrantPlugins
def self.halt(machine) def self.halt(machine)
begin begin
machine.communicate.execute("/bin/halt -d 0") machine.communicate.execute("/bin/halt -d 0")
rescue IOError rescue IOError, Vagrant::Errors::SSHDisconnected
# Ignore, this probably means connection closed because it # Ignore, this probably means connection closed because it
# shut down. # shut down.
end end

View File

@ -5,7 +5,7 @@ module VagrantPlugins
def self.halt(machine) def self.halt(machine)
begin begin
machine.communicate.sudo("shutdown -h now") machine.communicate.sudo("shutdown -h now")
rescue IOError rescue IOError, Vagrant::Errors::SSHDisconnected
# Do nothing, because it probably means the machine shut down # Do nothing, because it probably means the machine shut down
# and SSH connection was lost. # and SSH connection was lost.
end end

View File

@ -11,7 +11,7 @@ module VagrantPlugins
begin begin
machine.communicate.execute( machine.communicate.execute(
"#{machine.config.smartos.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") "#{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 # Ignore, this probably means connection closed because it
# shut down. # shut down.
end end

View File

@ -11,7 +11,7 @@ module VagrantPlugins
begin begin
machine.communicate.execute( machine.communicate.execute(
"#{machine.config.solaris.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") "#{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 # Ignore, this probably means connection closed because it
# shut down. # shut down.
end end

View File

@ -15,7 +15,7 @@ module VagrantPlugins
begin begin
machine.communicate.execute( machine.communicate.execute(
"#{machine.config.solaris11.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") "#{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 # Ignore, this probably means connection closed because it
# shut down. # shut down.
end end

View File

@ -5,7 +5,7 @@ module VagrantPlugins
def self.halt(machine) def self.halt(machine)
begin begin
machine.communicate.sudo("/sbin/shutdown -h now") machine.communicate.sudo("/sbin/shutdown -h now")
rescue IOError rescue IOError, Vagrant::Errors::SSHDisconnected
# Do nothing, because it probably means the machine shut down # Do nothing, because it probably means the machine shut down
# and SSH connection was lost. # and SSH connection was lost.
end end

View File

@ -5,7 +5,7 @@ module VagrantPlugins
def self.halt(machine) def self.halt(machine)
begin begin
machine.communicate.sudo("poweroff") machine.communicate.sudo("poweroff")
rescue Net::SSH::Disconnect, IOError rescue IOError, Vagrant::Errors::SSHDisconnected
# Do nothing, because it probably means the machine shut down # Do nothing, because it probably means the machine shut down
# and SSH connection was lost. # and SSH connection was lost.
end end

View File

@ -9,6 +9,7 @@ describe "VagrantPlugins::GuestBSD::Cap::Halt" do
let(:machine) { double("machine") } let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
let(:shutdown_command) { "/sbin/shutdown -p now" }
before do before do
allow(machine).to receive(:communicate).and_return(comm) allow(machine).to receive(:communicate).and_return(comm)
@ -22,12 +23,19 @@ describe "VagrantPlugins::GuestBSD::Cap::Halt" do
let(:cap) { caps.get(:halt) } let(:cap) { caps.get(:halt) }
it "runs the shutdown command" do it "runs the shutdown command" do
comm.expect_command("/sbin/shutdown -p now") comm.expect_command(shutdown_command)
cap.halt(machine) cap.halt(machine)
end end
it "ignores an IOError" do 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 { expect {
cap.halt(machine) cap.halt(machine)
}.to_not raise_error }.to_not raise_error

View File

@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestDarwin::Cap::Halt" do
cap.halt(machine) cap.halt(machine)
}.to_not raise_error }.to_not raise_error
end 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
end end

View File

@ -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

View File

@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestLinux::Cap::Halt" do
cap.halt(machine) cap.halt(machine)
}.to_not raise_error }.to_not raise_error
end 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
end end

View File

@ -33,7 +33,7 @@ describe "VagrantPlugins::GuestOpenBSD::Cap::Halt" do
}.to_not raise_error }.to_not raise_error
end 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) comm.stub_command("/sbin/shutdown -p -h now", raise: Vagrant::Errors::SSHDisconnected)
expect { expect {
cap.halt(machine) cap.halt(machine)

View File

@ -1,10 +1,11 @@
require_relative "../../../../base" 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(:plugin) { VagrantPlugins::GuestSmartos::Plugin.components.guest_capabilities[:smartos].get(:halt) }
let(:machine) { double("machine") } 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(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
let(:shutdown_command){ "pfexec /usr/sbin/shutdown -y -i5 -g0" }
before do before do
machine.stub(:communicate).and_return(communicator) machine.stub(:communicate).and_return(communicator)
@ -17,9 +18,22 @@ describe "VagrantPlugins::VagrantPlugins::Cap::Halt" do
describe ".halt" do describe ".halt" do
it "sends a shutdown signal" 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) plugin.halt(machine)
end end
end
it "ignores an IOError" do
communicator.stub_command(shutdown_command, raise: IOError)
expect {
plugin.halt(machine)
}.to_not raise_error
end 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

View File

@ -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

View File

@ -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

View File

@ -32,5 +32,12 @@ describe "VagrantPlugins::GuestSUSE::Cap::Halt" do
cap.halt(machine) cap.halt(machine)
}.to_not raise_error }.to_not raise_error
end 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
end end

View File

@ -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