Files
StatusQuo_Updates/scripts/rollback.ps1
T

114 lines
4.9 KiB
PowerShell

# StatusQuo_Updates/scripts/rollback.ps1
# Kanonisches Rollback-Skript (Referenz). rollback.bat enthaelt diese Logik
# EINGEBETTET und laeuft vollstaendig OFFLINE. Beachtet .backupignore.
# Erwartet im Scope: $root, $stopBat, $startBat
$ErrorActionPreference = 'Stop'
# Erwartet im Scope: $root, $stopBat, $startBat
$_stopName = if ($null -ne $stopBat) { $stopBat } else { 'stop.bat' }
$_startName = if ($null -ne $startBat) { $startBat } else { 'dgl.bat' }
# Ausschlussliste (identisch zu update.ps1): .backup nie anfassen, plus große
# Content-Ordner aus .backupignore — diese bleiben beim Rollback unverändert.
$_excl = @('.backup')
$_ignoreFile = Join-Path $root '.backupignore'
if (Test-Path -LiteralPath $_ignoreFile) {
$_extra = @(Get-Content -LiteralPath $_ignoreFile | ForEach-Object { $_.Trim() } |
Where-Object { $_ -ne '' -and -not $_.StartsWith('#') })
$_excl = $_excl + $_extra
}
$_excl = @($_excl) # strikt als Array (verhindert Skalar-Entpackung)
$bk = Join-Path $root '.backup'
if (-not (Test-Path -LiteralPath $bk)) {
Write-Host "Kein Backup-Verzeichnis gefunden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
return
}
$snaps = Get-ChildItem -LiteralPath $bk -Filter 'snapshot-*.zip' -ErrorAction SilentlyContinue | Sort-Object Name -Descending
if (-not $snaps) {
Write-Host "Keine Sicherungen vorhanden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
return
}
Write-Host ""
Write-Host "Verfügbare Sicherungen (neueste zuerst):" -ForegroundColor Cyan
$i = 0
foreach ($s in $snaps) {
$size = '{0:N1} MB' -f ($s.Length / 1MB)
$tag = if ($i -eq 0) { " <- neueste" } else { "" }
Write-Host (" [{0}] {1} ({2}){3}" -f $i, $s.Name, $size, $tag)
$i++
}
Write-Host ""
$c = Read-Host "Nummer der Sicherung wählen (Enter = neueste [0])"
if ($c -eq '') { $c = '0' }
if ($c -notmatch '^\d+$' -or [int]$c -ge $snaps.Count) {
Write-Host "Ungültige Auswahl. Abgebrochen." -ForegroundColor Yellow
return
}
$chosen = $snaps[[int]$c]
$zip = $chosen.FullName
# Integrität der Sicherung prüfen, BEVOR irgendetwas ersetzt wird
Add-Type -AssemblyName System.IO.Compression.FileSystem
try {
$z = [System.IO.Compression.ZipFile]::OpenRead($zip)
$null = $z.Entries.Count
$z.Dispose()
} catch {
Write-Host "FEHLER: Sicherung ist beschädigt — Rollback abgebrochen: $zip" -ForegroundColor Red
return
}
Write-Host ""
$yn = Read-Host "Stand '$($chosen.Name)' wiederherstellen? Der aktuelle Stand wird ersetzt! [j/N]"
if ($yn -notin 'j','J','y','Y') { Write-Host "Abgebrochen."; return }
# Server stoppen
Write-Host "Stoppe Server ..."
if ($_stopName -ne '') {
$sp = Join-Path $root $_stopName
if (Test-Path -LiteralPath $sp) { & cmd /c "`"$sp`""; Start-Sleep -Seconds 2 }
else { Write-Host " (Stop-Skript '$_stopName' nicht gefunden — übersprungen)" -ForegroundColor DarkYellow }
} else { Write-Host " (Kein Stop-Skript konfiguriert — übersprungen)" -ForegroundColor DarkYellow }
# Aktuellen Stand beiseite verschieben (Sicherheitsnetz, kein Datenverlust)
$aside = Join-Path $bk ("_vor-rollback-" + (Get-Date -Format 'yyyyMMdd-HHmmss'))
New-Item -ItemType Directory -Path $aside -Force | Out-Null
Get-ChildItem -LiteralPath $root -Force | Where-Object { $_excl -notcontains $_.Name } | ForEach-Object {
Move-Item -LiteralPath $_.FullName -Destination (Join-Path $aside $_.Name) -Force
}
# Sicherung wiederherstellen
try {
Expand-Archive -LiteralPath $zip -DestinationPath $root -Force
Write-Host "Stand wiederhergestellt: $($chosen.Name)" -ForegroundColor Green
} catch {
Write-Host "FEHLER beim Wiederherstellen — mache Änderung rückgängig ..." -ForegroundColor Red
Get-ChildItem -LiteralPath $root -Force | Where-Object { $_excl -notcontains $_.Name } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-ChildItem -LiteralPath $aside -Force | ForEach-Object {
Move-Item -LiteralPath $_.FullName -Destination (Join-Path $root $_.Name) -Force
}
Write-Host "Vorheriger Zustand wiederhergestellt — kein Datenverlust." -ForegroundColor Yellow
return
}
# Beiseite-Ordner aufräumen: nur die letzten 2 behalten
Get-ChildItem -LiteralPath $bk -Directory -Filter '_vor-rollback-*' -ErrorAction SilentlyContinue |
Sort-Object Name -Descending | Select-Object -Skip 2 |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
# Server starten
$stp = Join-Path $root $_startName
if (Test-Path -LiteralPath $stp) {
Start-Process -FilePath 'cmd.exe' -ArgumentList "/c `"$stp`"" -WindowStyle Hidden
Write-Host "Server gestartet." -ForegroundColor Green
} else {
Write-Host "Start-Skript '$_startName' nicht gefunden — bitte Server manuell starten." -ForegroundColor Yellow
}
Write-Host ""
Write-Host "=== Rollback abgeschlossen ===" -ForegroundColor Green
Write-Host " Wiederhergestellt: $($chosen.Name)" -ForegroundColor Cyan