Private/Invoke-OSDAppBuiltInCacheTransaction.ps1
|
function Invoke-OSDAppBuiltInCacheTransaction { [CmdletBinding()] param( [Parameter(Mandatory)][string]$Root, [Parameter(Mandatory)][scriptblock]$Build, [Parameter(Mandatory)][scriptblock]$Validate ) $transactionRoot = "$Root.osdapps-new-$([guid]::NewGuid().ToString('N'))" $backupRoot = "$Root.osdapps-old-$([guid]::NewGuid().ToString('N'))" $hadPrevious = Test-Path -LiteralPath $Root -PathType Container $promoted = $false try { New-Item -ItemType Directory -Path $transactionRoot -Force | Out-Null & $Build $transactionRoot & $Validate $transactionRoot | Out-Null if ($hadPrevious) { Move-Item -LiteralPath $Root -Destination $backupRoot -ErrorAction Stop } try { Move-Item -LiteralPath $transactionRoot -Destination $Root -ErrorAction Stop $promoted = $true } catch { if ($hadPrevious -and (Test-Path -LiteralPath $backupRoot -PathType Container) -and -not (Test-Path -LiteralPath $Root)) { Move-Item -LiteralPath $backupRoot -Destination $Root -ErrorAction Stop } throw } if (Test-Path -LiteralPath $backupRoot -PathType Container) { Remove-Item -LiteralPath $backupRoot -Recurse -Force -ErrorAction Stop } # The newly promoted generation has already passed the caller's full # validation gate. Residue from older interrupted transactions can now # be removed without risking the only usable generation. $parent = Split-Path -Path $Root -Parent $leaf = Split-Path -Path $Root -Leaf Get-ChildItem -LiteralPath $parent -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -like "$leaf.osdapps-new-*" -or $_.Name -like "$leaf.osdapps-old-*" } | ForEach-Object { Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction SilentlyContinue } [pscustomobject]@{ Root = $Root HadPrevious = $hadPrevious Promoted = $promoted Transactional = $true } } finally { if (Test-Path -LiteralPath $transactionRoot) { Remove-Item -LiteralPath $transactionRoot -Recurse -Force -ErrorAction SilentlyContinue } if ((Test-Path -LiteralPath $backupRoot -PathType Container) -and -not (Test-Path -LiteralPath $Root)) { Move-Item -LiteralPath $backupRoot -Destination $Root -ErrorAction SilentlyContinue } if ($promoted -and (Test-Path -LiteralPath $backupRoot -PathType Container)) { Remove-Item -LiteralPath $backupRoot -Recurse -Force -ErrorAction SilentlyContinue } } } |