diff --git a/plugins/providers/hyperv/action.rb b/plugins/providers/hyperv/action.rb index d6a4bdc82..b2bd98438 100644 --- a/plugins/providers/hyperv/action.rb +++ b/plugins/providers/hyperv/action.rb @@ -42,7 +42,7 @@ module VagrantPlugins b2.use ConfigValidate b2.use ProvisionerCleanup, :before - b2.use StopInstance + b2.use action_halt b2.use DeleteVM b2.use SyncedFolderCleanup end @@ -61,7 +61,11 @@ module VagrantPlugins b2.use Call, GracefulHalt, :off, :running do |env2, b3| if !env2[:result] - b3.use StopInstance + if env2[:force_halt] + b3.use HaltInstance + else + b3.use StopInstance + end end end end @@ -307,6 +311,7 @@ module VagrantPlugins autoload :CheckAccess, action_root.join("check_access") autoload :Configure, action_root.join("configure") autoload :DeleteVM, action_root.join("delete_vm") + autoload :HaltInstance, action_root.join("halt_instance") autoload :Import, action_root.join("import") autoload :Package, action_root.join("package") autoload :IsWindows, action_root.join("is_windows") diff --git a/plugins/providers/hyperv/action/halt_instance.rb b/plugins/providers/hyperv/action/halt_instance.rb new file mode 100644 index 000000000..bac04e276 --- /dev/null +++ b/plugins/providers/hyperv/action/halt_instance.rb @@ -0,0 +1,17 @@ +module VagrantPlugins + module HyperV + module Action + class HaltInstance + def initialize(app, env) + @app = app + end + + def call(env) + env[:ui].info("Turning off the machine...") + env[:machine].provider.driver.halt + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/hyperv/driver.rb b/plugins/providers/hyperv/driver.rb index 0a849b074..70bffbec3 100644 --- a/plugins/providers/hyperv/driver.rb +++ b/plugins/providers/hyperv/driver.rb @@ -136,6 +136,13 @@ module VagrantPlugins execute(:stop_vm, VmId: vm_id) end + # Halt the VM + # + # @return [nil] + def halt + execute(:stop_vm, VmId: vm_id, Force: true) + end + # Suspend the VM # # @return [nil] diff --git a/plugins/providers/hyperv/scripts/stop_vm.ps1 b/plugins/providers/hyperv/scripts/stop_vm.ps1 index 72f2835dd..998775295 100644 --- a/plugins/providers/hyperv/scripts/stop_vm.ps1 +++ b/plugins/providers/hyperv/scripts/stop_vm.ps1 @@ -5,7 +5,9 @@ Param( [Parameter(Mandatory=$true)] - [string]$VmId + [string]$VmId, + [Parameter(Mandatory=$false)] + [switch]$Force=$false ) $ErrorActionPreference = "Stop" @@ -13,7 +15,7 @@ $ErrorActionPreference = "Stop" try{ # Shuts down virtual machine regardless of any unsaved application data $VM = Hyper-V\Get-VM -Id $VmId - Hyper-V\Stop-VM $VM -Force + Hyper-V\Stop-VM $VM -Force -TurnOff:$Force } catch { Write-ErrorMessage "Failed to stop VM: ${PSItem}" exit 1 diff --git a/test/unit/plugins/providers/hyperv/action/halt_instance_test.rb b/test/unit/plugins/providers/hyperv/action/halt_instance_test.rb new file mode 100644 index 000000000..b6f79f339 --- /dev/null +++ b/test/unit/plugins/providers/hyperv/action/halt_instance_test.rb @@ -0,0 +1,29 @@ +require_relative "../../../../base" + +require Vagrant.source_root.join("plugins/providers/hyperv/action/halt_instance") + +describe VagrantPlugins::HyperV::Action::HaltInstance do + let(:app){ double("app") } + let(:env){ {ui: ui, machine: machine} } + let(:ui){ double("ui") } + let(:provider){ double("provider", driver: driver) } + let(:driver){ double("driver") } + let(:machine){ double("machine", provider: provider, data_dir: "/dev/null") } + let(:subject){ described_class.new(app, env) } + + before do + allow(app).to receive(:call) + allow(ui).to receive(:info) + allow(driver).to receive(:halt) + end + + it "should call the app on success" do + expect(app).to receive(:call) + subject.call(env) + end + + it "should call the driver to halt the vm" do + expect(driver).to receive(:halt) + subject.call(env) + end +end