fix: Rollback auf ZIP-Snapshot (offline-faehig, kanonische Referenz)

This commit is contained in:
Rhino
2026-06-20 21:38:30 +02:00
parent f29345c1d1
commit 9db5217eec
+68 -68
View File
@@ -1,97 +1,97 @@
# StatusQuo_Updates/scripts/rollback.ps1 # StatusQuo_Updates/scripts/rollback.ps1
# Stellt den Stand vor dem letzten Update wieder her. # Kanonisches Rollback-Skript (Referenz). Die ausgelieferte rollback.bat enthaelt
# Erwartet im aufrufenden Scope (wie update.ps1): # diese Logik EINGEBETTET und laeuft damit vollstaendig OFFLINE (kein Netz noetig).
# $root - Installationspfad # Erwartet im aufrufenden Scope: $root, $stopBat, $startBat
# $stopBat - (optional) Stop-Skript-Dateiname oder ''
# $startBat - (optional) Start-Skript-Dateiname
$ErrorActionPreference = 'Stop'
$ErrorActionPreference = 'Stop'
# Erwartet im Scope: $root, $stopBat, $startBat
$_stopName = if ($null -ne $stopBat) { $stopBat } else { 'stop.bat' } $_stopName = if ($null -ne $stopBat) { $stopBat } else { 'stop.bat' }
$_startName = if ($null -ne $startBat) { $startBat } else { 'dgl.bat' } $_startName = if ($null -ne $startBat) { $startBat } else { 'dgl.bat' }
# Verfügbare Backups suchen $bk = Join-Path $root '.backup'
$_backupBase = Join-Path $root '.backup' if (-not (Test-Path -LiteralPath $bk)) {
if (-not (Test-Path -LiteralPath $_backupBase)) { Write-Host "Kein Backup-Verzeichnis gefunden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
Write-Host "FEHLER: Kein Backup-Verzeichnis gefunden!" -ForegroundColor Red
Write-Host " Gesucht: $_backupBase"
Write-Host " Backups werden automatisch beim nächsten Update angelegt."
return return
} }
$snaps = Get-ChildItem -LiteralPath $bk -Filter 'snapshot-*.zip' -ErrorAction SilentlyContinue | Sort-Object Name -Descending
$_backups = Get-ChildItem -LiteralPath $_backupBase -Directory | if (-not $snaps) {
Where-Object { $_.Name -match '^\d{8}-\d{6}$' } | Sort-Object Name -Descending Write-Host "Keine Sicherungen vorhanden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
if ($_backups.Count -eq 0) {
Write-Host "FEHLER: Keine Backups vorhanden." -ForegroundColor Red
Write-Host " Backups werden automatisch beim nächsten Update angelegt."
return return
} }
Write-Host "" Write-Host ""
Write-Host "Verfügbare Backups:" -ForegroundColor Cyan Write-Host "Verfügbare Sicherungen (neueste zuerst):" -ForegroundColor Cyan
$_i = 0 $i = 0
foreach ($bk in $_backups) { foreach ($s in $snaps) {
$suffix = if ($_i -eq 0) { " ← neuestes" } else { "" } $size = '{0:N1} MB' -f ($s.Length / 1MB)
Write-Host (" [{0}] {1}{2}" -f $_i, $bk.Name, $suffix) $tag = if ($i -eq 0) { " <- neueste" } else { "" }
$_i++ Write-Host (" [{0}] {1} ({2}){3}" -f $i, $s.Name, $size, $tag)
$i++
} }
Write-Host "" Write-Host ""
$_choice = Read-Host "Backup-Nummer wählen (Enter = neuestes [0])" $c = Read-Host "Nummer der Sicherung wählen (Enter = neueste [0])"
if ($_choice -eq '') { $_choice = '0' } if ($c -eq '') { $c = '0' }
if ($_choice -notmatch '^\d+$' -or [int]$_choice -ge $_backups.Count) { if ($c -notmatch '^\d+$' -or [int]$c -ge $snaps.Count) {
Write-Host "Ungültige Auswahl. Abgebrochen." -ForegroundColor Yellow Write-Host "Ungültige Auswahl. Abgebrochen." -ForegroundColor Yellow
return 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
}
$_selected = $_backups[[int]$_choice]
Write-Host "" Write-Host ""
Write-Host "Stelle wieder her: $($_selected.Name)" -ForegroundColor Yellow $yn = Read-Host "Stand '$($chosen.Name)' wiederherstellen? Der aktuelle Stand wird ersetzt! [j/N]"
$yn = Read-Host "Rollback durchführen? Aktuelle Dateien werden überschrieben! [j/N]"
if ($yn -notin 'j','J','y','Y') { Write-Host "Abgebrochen."; return } if ($yn -notin 'j','J','y','Y') { Write-Host "Abgebrochen."; return }
# Server stoppen # Server stoppen
Write-Host "Stoppe Server ..." Write-Host "Stoppe Server ..."
if ($_stopName -ne '') { if ($_stopName -ne '') {
$_stopPath = Join-Path $root $_stopName $sp = Join-Path $root $_stopName
if (Test-Path -LiteralPath $_stopPath) { if (Test-Path -LiteralPath $sp) { & cmd /c "`"$sp`""; Start-Sleep -Seconds 2 }
& cmd /c "`"$_stopPath`"" else { Write-Host " (Stop-Skript '$_stopName' nicht gefunden — übersprungen)" -ForegroundColor DarkYellow }
Start-Sleep -Seconds 2 } else { Write-Host " (Kein Stop-Skript konfiguriert — übersprungen)" -ForegroundColor DarkYellow }
} else {
Write-Host " (Stop-Skript '$_stopName' nicht gefunden — ü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 { $_.Name -ne '.backup' } | 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 { $_.Name -ne '.backup' } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-ChildItem -LiteralPath $aside -Force | ForEach-Object {
Move-Item -LiteralPath $_.FullName -Destination (Join-Path $root $_.Name) -Force
} }
} else { Write-Host "Vorheriger Zustand wiederhergestellt — kein Datenverlust." -ForegroundColor Yellow
Write-Host " (Kein Stop-Skript konfiguriert — übersprungen)" -ForegroundColor DarkYellow return
} }
# Nutzerdaten wiederherstellen # Beiseite-Ordner aufräumen: nur die letzten 2 behalten
$_dataBackup = Join-Path $_selected.FullName 'data' Get-ChildItem -LiteralPath $bk -Directory -Filter '_vor-rollback-*' -ErrorAction SilentlyContinue |
if (Test-Path -LiteralPath $_dataBackup) { Sort-Object Name -Descending | Select-Object -Skip 2 |
$dataTarget = Join-Path $root 'data' Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
if (Test-Path -LiteralPath $dataTarget) {
# Aktuellen data/-Ordner vor Überschreiben sichern
$safeName = "data_vor_rollback_$(Get-Date -Format 'yyyyMMdd-HHmmss')"
Rename-Item -LiteralPath $dataTarget -NewName $safeName -ErrorAction SilentlyContinue
}
Copy-Item -Path $_dataBackup -Destination $dataTarget -Recurse -Force
$dataCount = (Get-ChildItem -LiteralPath $dataTarget -Recurse -File -ErrorAction SilentlyContinue).Count
Write-Host "Nutzerdaten wiederhergestellt ($dataCount Dateien)." -ForegroundColor Green
} else {
Write-Host " (Kein Nutzerdaten-Backup in diesem Stand)" -ForegroundColor DarkYellow
}
# Code-Dateien wiederherstellen # Server starten
$_codeFiles = Get-ChildItem -LiteralPath $_selected.FullName -File -ErrorAction SilentlyContinue $stp = Join-Path $root $_startName
foreach ($f in $_codeFiles) { if (Test-Path -LiteralPath $stp) {
Copy-Item -Path $f.FullName -Destination (Join-Path $root $f.Name) -Force Start-Process -FilePath 'cmd.exe' -ArgumentList "/c `"$stp`"" -WindowStyle Hidden
}
Write-Host "Code-Dateien wiederhergestellt ($($_codeFiles.Count) Dateien)." -ForegroundColor Green
# Server neu starten
$_startPath = Join-Path $root $_startName
if (Test-Path -LiteralPath $_startPath) {
Start-Process -FilePath 'cmd.exe' -ArgumentList "/c `"$_startPath`"" -WindowStyle Hidden
Write-Host "Server gestartet." -ForegroundColor Green Write-Host "Server gestartet." -ForegroundColor Green
} else { } else {
Write-Host "Start-Skript '$_startName' nicht gefunden — bitte Server manuell starten." -ForegroundColor Yellow Write-Host "Start-Skript '$_startName' nicht gefunden — bitte Server manuell starten." -ForegroundColor Yellow
@@ -99,4 +99,4 @@ if (Test-Path -LiteralPath $_startPath) {
Write-Host "" Write-Host ""
Write-Host "=== Rollback abgeschlossen ===" -ForegroundColor Green Write-Host "=== Rollback abgeschlossen ===" -ForegroundColor Green
Write-Host " Wiederhergestellt: $($_selected.Name)" -ForegroundColor Cyan Write-Host " Wiederhergestellt: $($chosen.Name)" -ForegroundColor Cyan