Explorar el Código

Harden IIS deploy script auth, smoke test, and 32-bit ACE OLEDB handling

- scp/ssh now force a fallback to password auth so a missing/rejected
  key fails with a real prompt instead of an opaque "Permission denied
  (publickey)".
- Smoke test now checks each path against its expected status (/404 is
  expected to 404) instead of treating any non-throwing response as a
  pass, and surfaces the actual failure reason.
- The remote IIS server has the 64-bit Access Database Engine, unlike
  the local dev machine, so its app pool stays 64-bit and migrations
  run through the plain (64-bit) cscript.exe instead of SysWOW64.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
master
Daniel Covington hace 2 días
padre
commit
88e5ab264e
Se han modificado 2 ficheros con 51 adiciones y 12 borrados
  1. +5
    -1
      scripts/deploy-iis-remote-apply.ps1
  2. +46
    -11
      scripts/deploy-iis.ps1

+ 5
- 1
scripts/deploy-iis-remote-apply.ps1 Ver fichero

@@ -65,11 +65,15 @@ icacls $dataDir /grant ("IIS AppPool\" + $AppPool + ":(OI)(CI)(M)") /T | Out-Nul
Set-ItemProperty ('IIS:\Sites\' + $SiteName) -Name physicalPath -Value $publicDir
Set-ItemProperty ('IIS:\Sites\' + $SiteName) -Name applicationPool -Value $AppPool

# This server has the 64-bit Access Database Engine (ACE OLEDB) installed, unlike the local
# dev machine, which needs the 32-bit one - so the app pool stays 64-bit here.
Set-ItemProperty ('IIS:\AppPools\' + $AppPool) -Name enable32BitAppOnWin64 -Value $false

if($RunMigrations){
Write-Host 'Running pending migrations'
Push-Location $RemoteDir
try {
& C:\Windows\SysWOW64\cscript.exe //nologo scripts\runMigrations.vbs up
& cscript.exe //nologo scripts\runMigrations.vbs up
if($LASTEXITCODE -ne 0){ throw 'runMigrations.vbs up failed - see output above' }
} finally {
Pop-Location


+ 46
- 11
scripts/deploy-iis.ps1 Ver fichero

@@ -76,12 +76,20 @@ $remoteZip = 'C:\Windows\Temp\' + $zipName
$remoteApplyScript = Join-Path $PSScriptRoot 'deploy-iis-remote-apply.ps1'
$remoteApplyDest = 'C:\Windows\Temp\deploy-iis-remote-apply.ps1'

# Force a fall-through to password auth: if pubkey auth isn't set up (or an agent offers a
# key the server doesn't accept), plain ssh/scp can otherwise fail outright with
# "Permission denied (publickey)" instead of ever prompting for a password.
$AuthOpts = @(
'-o', 'PreferredAuthentications=publickey,keyboard-interactive,password',
'-o', 'NumberOfPasswordPrompts=3'
)

Write-Host "Copying release to $RemoteTarget"
& $ScpExe -P $RemotePort $localZip "${RemoteTarget}:$remoteZip"
if($LASTEXITCODE -ne 0){ throw 'scp of release zip failed' }
& $ScpExe -P $RemotePort @AuthOpts $localZip "${RemoteTarget}:$remoteZip"
if($LASTEXITCODE -ne 0){ throw 'scp of release zip failed - see scp output above for the actual reason' }

& $ScpExe -P $RemotePort $remoteApplyScript "${RemoteTarget}:$remoteApplyDest"
if($LASTEXITCODE -ne 0){ throw 'scp of remote-apply script failed' }
& $ScpExe -P $RemotePort @AuthOpts $remoteApplyScript "${RemoteTarget}:$remoteApplyDest"
if($LASTEXITCODE -ne 0){ throw 'scp of remote-apply script failed - see scp output above for the actual reason' }

# --- 3. Apply on the remote host ---
$remoteCommandParts = @(
@@ -96,8 +104,8 @@ $remoteCommandParts = @(
if($RunMigrations){ $remoteCommandParts += '-RunMigrations' }

Write-Host "Applying release on $RemoteTarget"
& $SshExe -p $RemotePort $RemoteTarget ($remoteCommandParts -join ' ')
if($LASTEXITCODE -ne 0){ throw 'remote apply failed' }
& $SshExe -p $RemotePort @AuthOpts $RemoteTarget ($remoteCommandParts -join ' ')
if($LASTEXITCODE -ne 0){ throw 'remote apply failed - see ssh output above for the actual reason' }

# --- 4. Local cleanup ---
Remove-Item $localZip -ErrorAction SilentlyContinue
@@ -105,11 +113,38 @@ Remove-Item -Recurse -Force $outDir -ErrorAction SilentlyContinue

# --- 5. Smoke test ---
Write-Host 'Smoke testing...'
$paths = @('/', '/request-order', '/404')
foreach($path in $paths){
$url = $BaseUrl.TrimEnd('/') + $path
$response = Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 30
Write-Host ("OK " + $path + ' -> ' + $response.StatusCode)
# /404 is the app's own not-found route - a 404 there is correct, not a failure.
$checks = @(
@{ Path = '/'; Expect = 200 },
@{ Path = '/request-order'; Expect = 200 },
@{ Path = '/404'; Expect = 404 }
)
$failed = $false
foreach($check in $checks){
$url = $BaseUrl.TrimEnd('/') + $check.Path
try {
$response = Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 30
$status = [int]$response.StatusCode
} catch {
if($_.Exception.Response){
$status = [int]$_.Exception.Response.StatusCode
} else {
Write-Host ("FAIL " + $check.Path + ' -> request failed: ' + $_.Exception.Message)
$failed = $true
continue
}
}

if($status -eq $check.Expect){
Write-Host ("OK " + $check.Path + ' -> ' + $status)
} else {
Write-Host ("FAIL " + $check.Path + ' -> ' + $status + ' (expected ' + $check.Expect + ')')
$failed = $true
}
}

if($failed){
throw 'Smoke test failed - see above'
}

Write-Host 'Deploy complete.'

Cargando…
Cancelar
Guardar

Powered by TurnKey Linux.