diff --git a/deploy/windows/installer/shopdb-install.ps1 b/deploy/windows/installer/shopdb-install.ps1 index c9d216b..5c46b35 100644 --- a/deploy/windows/installer/shopdb-install.ps1 +++ b/deploy/windows/installer/shopdb-install.ps1 @@ -149,6 +149,11 @@ try { if (-not (Test-Path $script:LogDir)) { New-Item -ItemType Directory -Path catch { $script:LogDir = $env:TEMP } $script:LogPath = Join-Path $script:LogDir ("shopdb-install-{0}.log" -f (Get-Date -Format 'yyyyMMdd-HHmmss')) $script:Created = New-Object System.Collections.ArrayList # for rollback +# Was this server already stamped by a previous run of THIS installer, as observed +# BEFORE stage 2 writes its own stamp? Stage 4 needs the answer to know whether the +# IIS objects it is about to reconcile are its own. $null means nothing has looked +# yet, which is the case when stage 4 is run on its own. +$script:PreexistingInstallStamp = $null function Write-Log { param([string] $Message, [string] $Level = 'INFO') @@ -763,6 +768,12 @@ function Invoke-Stage2 { if (-not (Test-Path $AppSource)) { Fail "application payload not found: $AppSource" } Assert-BundleIntegrity Assert-VenvMatchesWheelhouse + # Captured HERE, before the stamp below is written. Stage 4's guard against + # touching an installation this did not create tested the stamp directly, and + # stage 2 always runs first in a '-Stage all' install - so the stamp it had + # just written made every server look like one of ours and the guard never + # fired on the case it exists for. + $script:PreexistingInstallStamp = Test-Path (Join-Path $AppRoot '.installed-version') # --- Python, all users -------------------------------------------------- # A per-user install lands in %LOCALAPPDATA%, which the IIS app-pool identity @@ -1493,8 +1504,15 @@ has to come from the bundle either way. # -MountAlias would delete a live mount with no prompt and no error, and the # first sign would be the site 404ing. # - # 'Ours' means there is a version stamp, which only this installer writes. - $weBuiltThis = Test-Path (Join-Path $AppRoot '.installed-version') + # 'Ours' means there was a version stamp BEFORE this run started - only this + # installer writes one. Stage 2 records that observation; testing the file + # here instead would read the stamp stage 2 has already written. + $weBuiltThis = if ($null -ne $script:PreexistingInstallStamp) { + $script:PreexistingInstallStamp + } else { + # Stage 4 run on its own, so stage 2 has not written anything this run. + Test-Path (Join-Path $AppRoot '.installed-version') + } if (-not $WhatIfOnly) { $doomed = @() if ($MountAlias) {