From f792b5870441108734261b7e19f03e2d53d9fa4b Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 14 Apr 2020 11:50:30 -0700 Subject: [PATCH] Add functionality to clean up stale disks for hyper-v guests --- plugins/providers/hyperv/cap/cleanup_disks.rb | 23 +++++++++++-------- .../providers/hyperv/cap/configure_disks.rb | 6 +++++ .../hyperv/scripts/remove_disk_drive.ps1 | 4 ++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/providers/hyperv/cap/cleanup_disks.rb b/plugins/providers/hyperv/cap/cleanup_disks.rb index fc3322d2b..41e4e4546 100644 --- a/plugins/providers/hyperv/cap/cleanup_disks.rb +++ b/plugins/providers/hyperv/cap/cleanup_disks.rb @@ -25,22 +25,25 @@ module VagrantPlugins # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] defined_disks # @param [Hash] disk_meta - A hash of all the previously defined disks from the last configure_disk action def self.handle_cleanup_disk(machine, defined_disks, disk_meta) - # TODO: Iterate over each disk_meta disk, check if it's still defined in the - # guests config, and if it's no longer there, remove it from the guest - disk_meta.each do |d| - # find d in defined_disk - # if found, continue on - # else, remove the disk + all_disks = machine.provider.driver.list_hdds + disk_meta.each do |d| # look at Path instead of Name or UUID disk_name = File.basename(d["path"], '.*') dsk = defined_disks.select { |dk| dk.name == disk_name } - primary_disk_uuid = "" - ## todo: finish this - if !dsk.empty? || d["uuid"] == primary_disk_uuid + + + if !dsk.empty? || d["primary"] == true next else - #remove disk from guest, and remove from system + LOGGER.warn("Found disk not in Vagrantfile config: '#{d["name"]}'. Removing disk from guest #{machine.name}") + disk_info = machine.provider.driver.get_disk(d["path"]) + + machine.ui.warn("Disk '#{d["name"]}' no longer exists in Vagrant config. Removing and closing medium from guest...", prefix: true) + + disk_actual = all_disks.select { |a| a["Path"] == d["path"] }.first + + machine.provider.driver.remove_disk(disk_actual["ControllerType"], disk_actual["ControllerNumber"], disk_actual["DiskLocation"]) end end end diff --git a/plugins/providers/hyperv/cap/configure_disks.rb b/plugins/providers/hyperv/cap/configure_disks.rb index ec83ef6db..27fb69c26 100644 --- a/plugins/providers/hyperv/cap/configure_disks.rb +++ b/plugins/providers/hyperv/cap/configure_disks.rb @@ -93,6 +93,9 @@ module VagrantPlugins # # TODO: Is it possible for a disk to not be connected by this point # for hyper-v? Since we get the disk from the vm info itself + # + # note: hyper-v has a key `"Attached"` that can be used to see if + # the disk is currently attached to a guest #disk_info = machine.provider.driver.get_port_and_device(current_disk["DiskIdentifier"]) #if disk_info.empty? @@ -106,6 +109,9 @@ module VagrantPlugins #end disk_metadata = {uuid: current_disk["DiskIdentifier"], name: disk.name, path: current_disk["Path"]} + if disk.primary + disk_metadata[:primary] = true + end end disk_metadata diff --git a/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 b/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 index ec330dd4d..0d24d7ed5 100644 --- a/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +++ b/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 @@ -8,13 +8,13 @@ param( [Parameter(Mandatory=$true)] [string]$ControllerNumber, [Parameter(Mandatory=$true)] - [string]$ControllerLocation, + [string]$ControllerLocation ) try { $VM = Hyper-V\Get-VM -Id $VmId - Hyper-v\Remove-VMHardDiskDrive -VMName $VM -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation + Hyper-v\Remove-VMHardDiskDrive -VMName $VM.Name -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation } catch { Write-ErrorMessage "Failed to remove disk ${DiskFilePath} to VM ${VM}: ${PSItem}" exit 1