diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index ee8974c7..8b4ac50b 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -14,7 +14,8 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic ### Bugfixes * [#472](https://github.com/Icinga/icinga-powershell-framework/pull/472) Fixes random errors while dynamically compiling Add-Type code by now writing a DLL inside `cache/dll` for later usage -* [#478](https://github.com/Icinga/icinga-powershell-framework/pull/478) Fixes connection option "Connecting from parent system" which is not asking for ca.crt location +* [#472](https://github.com/Icinga/icinga-powershell-framework/pull/472) Fixes random errors while dynamically compiling Add-Type code by now writing a DLL inside `cache/dll` for later usage +* [#479](https://github.com/Icinga/icinga-powershell-framework/pull/479) Fixes possible exceptions while trying to remove downloaded repository temp files which might still contain a file lock from virusscanners or other tasks ### Enhancements diff --git a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 index b67db767..dcb43018 100644 --- a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 +++ b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 @@ -119,7 +119,7 @@ function Get-IcingaPowerShellModuleArchive() if ((Invoke-IcingaWebRequest -UseBasicParsing -Uri $DownloadUrl -OutFile $DownloadDestination).HasErrors) { Write-IcingaConsoleError ([string]::Format('Failed to download "{0}" into "{1}". Starting cleanup process', $ModuleName, $DownloadDirectory)); Start-Sleep -Seconds 2; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; Write-IcingaConsoleNotice 'Starting to re-run the download wizard'; diff --git a/lib/core/framework/Remove-ItemSecure.psm1 b/lib/core/framework/Remove-ItemSecure.psm1 index 0f9ce0c9..9c636369 100644 --- a/lib/core/framework/Remove-ItemSecure.psm1 +++ b/lib/core/framework/Remove-ItemSecure.psm1 @@ -1,11 +1,11 @@ <# .SYNOPSIS - Wrapper for Remove-Item to secuerly remove items allowing better handling for errors + Wrapper for Remove-Item to securely remove items allowing better handling for errors .DESCRIPTION Removes files and folders from disk and catches possible exceptions with proper return values to handle errors better .FUNCTIONALITY - Wrapper for Remove-Item to secuerly remove items allowing better handling for errors + Wrapper for Remove-Item to securely remove items allowing better handling for errors .EXAMPLE PS>Remove-ItemSecure -Path C:\icinga; .EXAMPLE @@ -17,8 +17,12 @@ .PARAMETER Recurse Removes sub-folders and sub-files for a given location .PARAMETER Force - Tries to forefully removes a files and folders if they are either being used or a folder is + Tries to forcefully removes a files and folders if they are either being used or a folder is still containing items +.PARAMETER Retries + In case the object/folder is not removed without errors, the function will re-try the attempt + as often as specified with a sleep of 2 seconds between attempts to avoid possible file locks + for other operations .INPUTS System.String .OUTPUTS @@ -29,23 +33,38 @@ function Remove-ItemSecure() { - param( + param ( [string]$Path, [switch]$Recurse = $FALSE, - [switch]$Force = $FALSE - ) + [switch]$Force = $FALSE, + [int]$Retries = 1 + ); if ([string]::IsNullOrEmpty($Path) -Or (Test-Path $Path) -eq $FALSE) { Write-IcingaConsoleError 'The provided path "{0}" does not exist' -Objects $Path; return $FALSE; } - try { - Remove-Item -Path $Path -Recurse:$Recurse -Force:$Force -ErrorAction Stop; - return $TRUE; - } catch { - $ExMsg = $_.Exception; - Write-IcingaConsoleError 'Failed to remove items from path "{0}". Recurse is "{1}", Force is "{2}": "{3}"' -Objects $Path, $Recurse, $Force, $ExMsg; + if ($Retries -le 0) { + $Retries = 1; } + + $ExMsg = $null; + + while ($Retries -gt 0) { + try { + Remove-Item -Path $Path -Recurse:$Recurse -Force:$Force -ErrorAction Stop; + return $TRUE; + } catch { + $ExMsg = $_.Exception; + } + + Start-Sleep -Seconds 2; + Write-IcingaConsoleNotice -Message 'Waiting for lock on path "{0}" to be released before trying to remove it' -Objects $Path; + $Retries -= 1; + } + + Write-IcingaConsoleError 'Failed to remove items from path "{0}". Recurse is "{1}", Force is "{2}": "{3}"' -Objects $Path, $Recurse, $Force, $ExMsg; + return $FALSE; } diff --git a/lib/core/repository/Install-IcingaComponent.psm1 b/lib/core/repository/Install-IcingaComponent.psm1 index 8e897a63..af0445f7 100644 --- a/lib/core/repository/Install-IcingaComponent.psm1 +++ b/lib/core/repository/Install-IcingaComponent.psm1 @@ -83,7 +83,7 @@ function Install-IcingaComponent() if ((Invoke-IcingaWebRequest -UseBasicParsing -Uri $FileSource -OutFile $DownloadDestination).HasErrors) { Write-IcingaConsoleError ([string]::Format('Failed to download "{0}" from "{1}" into "{2}". Starting cleanup process', $Name.ToLower(), $FileSource, $DownloadDestination)); Start-Sleep -Seconds 2; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } @@ -128,7 +128,7 @@ function Install-IcingaComponent() if ($null -eq $ManifestFile) { Write-IcingaConsoleError ([string]::Format('Unable to read manifest for package "{0}". Aborting installation', $Name.ToLower())); Start-Sleep -Seconds 2; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } @@ -145,7 +145,7 @@ function Install-IcingaComponent() if ($ManifestFile.ModuleVersion -eq $InstallVersion -And $Force -eq $FALSE) { Write-IcingaConsoleWarning ([string]::Format('The package "{0}" with version "{1}" is already installed. Use "-Force" to re-install the component', $Name.ToLower(), $ManifestFile.ModuleVersion)); Start-Sleep -Seconds 2; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } @@ -285,13 +285,13 @@ function Install-IcingaComponent() if ($Success -eq 0) { Write-IcingaConsoleWarning ([string]::Format('The package "service" with version "{0}" is already installed. Use "-Force" to re-install the component', $InstalledService.ProductVersion)); - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } if ($Success -eq 1) { - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; Write-IcingaConsoleNotice 'Installation of component "service" was successful'; return; @@ -299,7 +299,7 @@ function Install-IcingaComponent() Write-IcingaConsoleError 'Failed to install component "service". Either the package did not include a service binary or the checksum of the binary did not match'; Start-Sleep -Seconds 2; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } else { Write-IcingaConsoleError 'There was no manifest file found inside the package'; @@ -352,7 +352,7 @@ function Install-IcingaComponent() if ($InstalledVersion.Full -eq $MSIData.ProductVersion -And $Force -eq $FALSE) { Write-IcingaConsoleWarning 'The package "agent" with version "{0}" is already installed. Use "-Force" to re-install the component' -Objects $InstalledVersion.Full; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; return; } @@ -391,6 +391,5 @@ function Install-IcingaComponent() Write-IcingaConsoleError ([string]::Format('Unsupported file extension "{0}" found for package "{1}". Aborting installation', ([IO.Path]::GetExtension($FileName)), $Name.ToLower())); } - Start-Sleep -Seconds 1; - Remove-Item -Path $DownloadDirectory -Recurse -Force; + Remove-ItemSecure -Path $DownloadDirectory -Recurse -Force -Retries 5 | Out-Null; }