mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Support force halt behaviour (#1270)
Vagrant subcommand halt accepts an argument -f that should result in VMs being halted immediately instead of attempting a graceful shutdown. Add support for this option and include tests to cover the rest of the halt behaviour. Fixes: #1265
This commit is contained in:
@@ -17,6 +17,11 @@ module VagrantPlugins
|
|||||||
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
||||||
raise Errors::NoDomainError if domain.nil?
|
raise Errors::NoDomainError if domain.nil?
|
||||||
|
|
||||||
|
if env[:force_halt]
|
||||||
|
domain.poweroff
|
||||||
|
return @app.call(env)
|
||||||
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Timeout.timeout(timeout) do
|
Timeout.timeout(timeout) do
|
||||||
begin
|
begin
|
||||||
@@ -39,6 +44,9 @@ module VagrantPlugins
|
|||||||
rescue Timeout::Error
|
rescue Timeout::Error
|
||||||
@logger.info('VM is still running. Calling force poweroff.')
|
@logger.info('VM is still running. Calling force poweroff.')
|
||||||
domain.poweroff
|
domain.poweroff
|
||||||
|
rescue
|
||||||
|
@logger.error('Failed to shutdown cleanly. Calling force poweroff.')
|
||||||
|
domain.poweroff
|
||||||
end
|
end
|
||||||
|
|
||||||
@app.call(env)
|
@app.call(env)
|
||||||
|
|||||||
90
spec/unit/action/halt_domain_spec.rb
Normal file
90
spec/unit/action/halt_domain_spec.rb
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
require 'support/sharedcontext'
|
||||||
|
require 'support/libvirt_context'
|
||||||
|
require 'vagrant-libvirt/action/destroy_domain'
|
||||||
|
|
||||||
|
describe VagrantPlugins::ProviderLibvirt::Action::HaltDomain do
|
||||||
|
subject { described_class.new(app, env) }
|
||||||
|
|
||||||
|
include_context 'unit'
|
||||||
|
include_context 'libvirt'
|
||||||
|
|
||||||
|
let(:libvirt_domain) { double('libvirt_domain') }
|
||||||
|
let(:servers) { double('servers') }
|
||||||
|
|
||||||
|
describe '#call' do
|
||||||
|
before do
|
||||||
|
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
|
||||||
|
.to receive(:connection).and_return(connection)
|
||||||
|
allow(connection).to receive(:servers).and_return(servers)
|
||||||
|
allow(servers).to receive(:get).and_return(domain)
|
||||||
|
# always see this at the start of #call
|
||||||
|
expect(ui).to receive(:info).with('Halting domain...')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with graceful timeout' do
|
||||||
|
it "should shutdown" do
|
||||||
|
expect(guest).to receive(:capability).with(:halt).and_return(true)
|
||||||
|
expect(domain).to receive(:wait_for).with(60).and_return(false)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when halt fails' do
|
||||||
|
before do
|
||||||
|
expect(logger).to receive(:info).with('Trying Libvirt graceful shutdown.')
|
||||||
|
expect(guest).to receive(:capability).with(:halt).and_raise(IOError)
|
||||||
|
expect(domain).to receive(:state).and_return('running')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should call shutdown" do
|
||||||
|
expect(domain).to receive(:shutdown)
|
||||||
|
expect(domain).to receive(:wait_for).with(60).and_return(false)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when shutdown fails' do
|
||||||
|
it "should call power off" do
|
||||||
|
expect(logger).to receive(:error).with('Failed to shutdown cleanly. Calling force poweroff.')
|
||||||
|
expect(domain).to receive(:shutdown).and_raise(IOError)
|
||||||
|
expect(domain).to receive(:poweroff)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when shutdown exceeds the timeout' do
|
||||||
|
it "should call poweroff" do
|
||||||
|
expect(logger).to receive(:info).with('VM is still running. Calling force poweroff.')
|
||||||
|
expect(domain).to receive(:shutdown).and_raise(Timeout::Error)
|
||||||
|
expect(domain).to receive(:poweroff)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when halt exceeds the timeout' do
|
||||||
|
before do
|
||||||
|
expect(logger).to_not receive(:info).with('Trying Libvirt graceful shutdown.')
|
||||||
|
expect(guest).to receive(:capability).with(:halt).and_raise(Timeout::Error)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should call poweroff" do
|
||||||
|
expect(logger).to receive(:info).with('VM is still running. Calling force poweroff.')
|
||||||
|
expect(domain).to receive(:poweroff)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with force halt enabled' do
|
||||||
|
before do
|
||||||
|
allow(env).to receive(:[]).and_call_original
|
||||||
|
expect(env).to receive(:[]).with(:force_halt).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should just call poweroff" do
|
||||||
|
expect(domain).to receive(:poweroff)
|
||||||
|
expect(subject.call(env)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user