Files
nexarch/archive/cmd/restoretest-cli/main.go
T
sysops c761cf9b93 feat(archive): BAK-06 Restore-Testverfahren
internal/restoretest wiederholt BAK-03s eigene Pruefdiskt als
Produktcode: echter Restore der neuesten Sicherung, echter Kurzstart
einer isolierten Postgres-Instanz, echte SELECT-1-Abfrage; Objekt-Seite
echter restic-Restore + Inhaltspruefung. JSONL-Historie (append-only),
sichtbare Warnung ueber denselben OPS-05-Pull-Weg wie BAK-08, eigenes
/metrics-Modul (archive-restoretest). Zwei reale Defekte gefunden und
behoben: Unix-Socket-Pfadlaenge unter tief verschachtelten Testpfaden,
restic-stderr-Vermischung beim JSON-Parsen unter dem Dienstnutzer.
Real auf 131 verdrahtet und ausgeloest (beide Testarten erfolgreich,
End-zu-Ende ueber OPS-03 bestaetigt).
2026-08-30 00:31:34 +02:00

72 lines
2.1 KiB
Go

// restoretest-cli ist der Aufrufpunkt fuer BAK-06 (systemd-Timer,
// regelmaessiger Zeitplan) - fuehrt einen vollstaendigen Restore-Test
// (Datenbank UND Objekt-Storage) gegen die jeweils neueste Sicherung in
// eine isolierte Testumgebung durch und protokolliert das Ergebnis.
package main
import (
"context"
"log"
"os"
"gitea.perlbach24.de/scripte/nexarch/archive/internal/backup"
"gitea.perlbach24.de/scripte/nexarch/archive/internal/objectbackup"
"gitea.perlbach24.de/scripte/nexarch/archive/internal/restoretest"
)
func main() {
testRoot := os.Getenv("NEXARCH_RESTORETEST_DIR")
logPath := os.Getenv("NEXARCH_RESTORETEST_LOG")
if testRoot == "" || logPath == "" {
log.Fatal("NEXARCH_RESTORETEST_DIR und NEXARCH_RESTORETEST_LOG muessen gesetzt sein")
}
if err := os.MkdirAll(testRoot, 0o750); err != nil {
log.Fatalf("testverzeichnis anlegen: %v", err)
}
ctx := context.Background()
failed := false
dbCfg := backup.Config{
Host: os.Getenv("NEXARCH_BACKUP_PG_HOST"),
Port: os.Getenv("NEXARCH_BACKUP_PG_PORT"),
User: os.Getenv("NEXARCH_BACKUP_PG_USER"),
Password: os.Getenv("NEXARCH_BACKUP_PG_PASSWORD"),
BackupDir: os.Getenv("NEXARCH_BACKUP_DIR"),
}
pgCfg := restoretest.PgConfig{TestPort: envOr("NEXARCH_RESTORETEST_PG_PORT", "55433")}
dbResult := restoretest.RunDatabaseTest(ctx, dbCfg, pgCfg, testRoot)
logResult(logPath, dbResult)
if !dbResult.Success {
failed = true
}
objCfg := objectbackup.Config{
RepoDir: os.Getenv("NEXARCH_OBJECTBACKUP_REPO_DIR"),
Password: os.Getenv("NEXARCH_OBJECTBACKUP_PASSWORD"),
}
objResult := restoretest.RunObjectTest(ctx, objCfg, testRoot)
logResult(logPath, objResult)
if !objResult.Success {
failed = true
}
if failed {
os.Exit(1)
}
}
func logResult(logPath string, r restoretest.Result) {
log.Printf("restoretest %s: quelle=%s erfolg=%t detail=%s", r.Kind, r.Source, r.Success, r.Detail)
if err := restoretest.AppendHistory(logPath, r); err != nil {
log.Fatalf("protokoll schreiben: %v", err)
}
}
func envOr(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}