From c6b9d9ce90ee3117e80039ded77f852e7f8bff08 Mon Sep 17 00:00:00 2001 From: DanHam Date: Thu, 5 Jul 2018 21:16:51 +0100 Subject: [PATCH] Add checks/error reporting to compaction process * Report compaction results * Failure to find any disks under the supplied path is treated as a 'soft' error and a warning message will be printed in place of the compaction result. Any other failure will cause the build to fail. --- builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_mock.go | 6 +++-- builder/hyperv/common/driver_ps_4.go | 2 +- builder/hyperv/common/step_export_vm.go | 8 +++++- common/powershell/hyperv/hyperv.go | 33 +++++++++++++++++++++---- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index ef4e9c48d..de3ba2651 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -96,7 +96,7 @@ type Driver interface { PreserveLegacyExportBehaviour(string, string) error - CompactDisks(string) error + CompactDisks(string) (string, error) RestartVirtualMachine(string) error diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 28efa397d..8e5a52cbd 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -193,6 +193,7 @@ type DriverMock struct { CompactDisks_Called bool CompactDisks_Path string + CompactDisks_Result string CompactDisks_Err error RestartVirtualMachine_Called bool @@ -493,10 +494,11 @@ func (d *DriverMock) PreserveLegacyExportBehaviour(srcPath string, dstPath strin return d.PreserveLegacyExportBehaviour_Err } -func (d *DriverMock) CompactDisks(path string) error { +func (d *DriverMock) CompactDisks(path string) (result string, err error) { d.CompactDisks_Called = true d.CompactDisks_Path = path - return d.CompactDisks_Err + d.CompactDisks_Result = "Mock compact result msg: mockdisk.vhdx. Disk size reduced by 20%" + return d.CompactDisks_Result, d.CompactDisks_Err } func (d *DriverMock) RestartVirtualMachine(vmName string) error { diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index b013b2598..acf399210 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -223,7 +223,7 @@ func (d *HypervPS4Driver) PreserveLegacyExportBehaviour(srcPath string, dstPath return hyperv.PreserveLegacyExportBehaviour(srcPath, dstPath) } -func (d *HypervPS4Driver) CompactDisks(path string) error { +func (d *HypervPS4Driver) CompactDisks(path string) (result string, err error) { return hyperv.CompactDisks(path) } diff --git a/builder/hyperv/common/step_export_vm.go b/builder/hyperv/common/step_export_vm.go index 0eb42a7c0..dfed94bf7 100644 --- a/builder/hyperv/common/step_export_vm.go +++ b/builder/hyperv/common/step_export_vm.go @@ -34,13 +34,19 @@ func (s *StepExportVm) Run(_ context.Context, state multistep.StateBag) multiste ui.Say("Skipping disk compaction...") } else { ui.Say("Compacting disks...") - err := driver.CompactDisks(tmpPath) + // CompactDisks searches for all VHD/VHDX files under the supplied + // path and runs the compacting process on each of them. If no disks + // are found under the supplied path this is treated as a 'soft' error + // and a warning message is printed. All other errors halt the build. + result, err := driver.CompactDisks(tmpPath) if err != nil { err := fmt.Errorf("Error compacting disks: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } + // Report disk compaction results/warn if no disks were found + ui.Message(result) } if s.SkipExport { diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index d51eef74c..055d12706 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -721,17 +721,40 @@ if ( $((Get-Item $srcPath).GetFileSystemInfos().Count) -eq 0 ) { return err } -func CompactDisks(path string) error { +func CompactDisks(path string) (result string, err error) { var script = ` param([string]$srcPath) -Get-ChildItem "$srcPath" -Filter *.vhd* | %{ - Optimize-VHD -Path $_.FullName -Mode Full + +$disks = Get-ChildItem -Path $srcPath -Recurse -Filter *.vhd* -ErrorAction SilentlyContinue | % { $_.FullName } +# Failure to find any disks is treated as a 'soft' error. Simply print out +# a warning and exit +if ($disks.Length -eq 0) { + Write-Output "WARNING: No disks found under $srcPath" + exit +} + +foreach ($disk in $disks) { + Write-Output "Compacting disk: $(Split-Path $disk -leaf)" + + $sizeBefore = $disk.Length + Optimize-VHD -Path $disk -Mode Full + $sizeAfter = $disk.Length + + # Calculate the percentage change in disk size + if ($sizeAfter -gt 0) { # Protect against division by zero + $percentChange = ( ( $sizeAfter / $sizeBefore ) * 100 ) - 100 + switch($percentChange) { + {$_ -lt 0} {Write-Output "Disk size reduced by: $(([math]::Abs($_)).ToString("#.#"))%"} + {$_ -eq 0} {Write-Output "Disk size is unchanged"} + {$_ -gt 0} {Write-Output "WARNING: Disk size increased by: $($_.ToString("#.#"))%"} + } + } } ` var ps powershell.PowerShellCmd - err := ps.Run(script, path) - return err + result, err = ps.Output(script, path) + return } func CreateVirtualSwitch(switchName string, switchType string) (bool, error) {