From c4ba67b55c9c0cd550b48567dffaa7ff862b9d1e Mon Sep 17 00:00:00 2001 From: Micha Date: Tue, 23 Jun 2026 13:15:58 +0200 Subject: [PATCH] Activate Hetzner snapshot restore test after live validation Codex first live run passed (SUCCESS, 7 snapshots, single-file restore from .zfs/snapshot; report hetzner-snapshot-2026-06-23.md) with no ENV overrides. Set runbook status to active, document the run, and add the monthly cadence (15th, cron 0 6 15 * *) to schedule.md and the restore-tests README. Remaining host step: create the Unraid User Script restore-hetzner-snapshot-monthly. Co-Authored-By: Claude Opus 4.8 --- ops/restore-tests/README.md | 2 +- ops/restore-tests/hetzner-snapshot-runbook.md | 27 +++++++++---------- ops/restore-tests/schedule.md | 4 +++ 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ops/restore-tests/README.md b/ops/restore-tests/README.md index 47f32ce..e0a3cc6 100644 --- a/ops/restore-tests/README.md +++ b/ops/restore-tests/README.md @@ -79,7 +79,7 @@ Einziger Status-Ort ist die **Reifegrad-Tabelle** in `docs/RESTORE_MATRIX.md` - **Immich:** Foto-Dateien-Restore ist bewusst nicht Teil des Smokes (separater DR-Drill); Test-Postgres nutzt das produktive VectorChord-Image. - **Home Assistant:** nutzt das neueste HA-native Backup-Artefakt und eine Kopie der Mosquitto-Appdata; Testcontainer laufen nur auf localhost-Ports, ohne Traefik/Public Route. - **Unraid-Flash / Tailscale:** noch ohne vollstaendigen Erstlauf - `unraid-flash-runbook.md`, `tailscale-runbook.md`; offene Schritte in `docs/MASTER_TODO.md`. -- **Hetzner-Snapshot:** Infrastruktur-Test (kein Service-Restore): prueft `.zfs/snapshot` der Storage Box (Existenz, Retention, Einzeldatei-Restore) und belegt den snapshot-basierten Off-site-Schutz. Dispatcher `hetzner-snapshot`, Runbook `hetzner-snapshot-runbook.md`. Stand: v1, einmalige Live-Validierung gegen die Box ausstehend. +- **Hetzner-Snapshot:** Infrastruktur-Test (kein Service-Restore): prueft `.zfs/snapshot` der Storage Box (Existenz, Retention, Einzeldatei-Restore) und belegt den snapshot-basierten Off-site-Schutz. Dispatcher `hetzner-snapshot`, Runbook `hetzner-snapshot-runbook.md`. Live validiert 2026-06-23 (7 Snapshots, Einzeldatei-Restore ok); monatlich im `schedule.md`. ## Naechste Ausbaustufen diff --git a/ops/restore-tests/hetzner-snapshot-runbook.md b/ops/restore-tests/hetzner-snapshot-runbook.md index 5849c09..f714766 100644 --- a/ops/restore-tests/hetzner-snapshot-runbook.md +++ b/ops/restore-tests/hetzner-snapshot-runbook.md @@ -1,6 +1,6 @@ # Hetzner Storage Box Snapshot Restore - Runbook -Typ: Runbook · Stand: 2026-06-23 · Status: v1 (Live-Validierung ausstehend) +Typ: Runbook · Stand: 2026-06-23 · Status: aktiv (live validiert 2026-06-23) Belegt den Off-site-Schutz der Hetzner Storage Box. Append-only ist bewusst NICHT umgesetzt (DECISIONS 2026-06-01); der Schutz ist snapshot-basiert (DECISIONS @@ -27,21 +27,18 @@ Secret im Skript, kein Schreibzugriff, kein `prune`/`compact`. - neuester: `Automatic-2026-06-23T05-30-24` - Probe `hetzner_borg_appdata_critical/README`, 73 B, SHA256 erzeugt, Temp geloescht -## Ausstehend: einmalige Live-Validierung +## Live-Validierung (2026-06-23, Codex): erfolgreich -Das Skript ist nach den oben belegten Werten gebaut, aber noch nicht gegen die Box -gelaufen. Erstlauf: +Erstlauf ohne ENV-Anpassung gruen (`SUCCESS`), Defaults passten direkt: -```bash -bash /mnt/user/services/homelab-infra/ops/restore-tests/run-restore-checks.sh hetzner-snapshot --what-if -bash /mnt/user/services/homelab-infra/ops/restore-tests/run-restore-checks.sh hetzner-snapshot -``` +- Report: `/mnt/user/backups/restore-reports/hetzner-snapshot-2026-06-23.md` +- 7 Snapshots gefunden, neuester `Automatic-2026-06-23T05-30-24` +- Einzeldatei-Restore aus `.zfs/snapshot` erfolgreich -Falls die Storage-Box-Shell die SFTP-`ls`/`get`-Form oder den `.zfs/snapshot`-Pfad -anders erwartet, ueber ENV justieren (kein Code-Change noetig): -`SNAPSHOT_DIR`, `PROBE_FILE`, `SNAPSHOT_NAME_GLOB`, `SNAPSHOT_SSH_OPTS`, -`MIN_SNAPSHOTS`, `MAX_SNAPSHOT_AGE_HOURS`. Bitte den tatsaechlich funktionierenden -SFTP-Aufruf aus dem manuellen Lauf gegenpruefen (Key/Identity, Port). +ENV-Override (`SNAPSHOT_DIR`, `PROBE_FILE`, `SNAPSHOT_NAME_GLOB`, +`SNAPSHOT_SSH_OPTS`, `MIN_SNAPSHOTS`, `MAX_SNAPSHOT_AGE_HOURS`) bleibt fuer +kuenftige Abweichungen verfuegbar. -Nach erfolgreichem Erstlauf: in `schedule.md` aufnehmen (Vorschlag: monatlich, -analog Zufalls-Restore) und Status hier auf "aktiv" setzen. +**Verbleibender Host-Schritt (Codex/Du):** Unraid-User-Script +`restore-hetzner-snapshot-monthly` anlegen (Cron `0 6 15 * *`), Vorlage in +`unraid-user-scripts.md`. diff --git a/ops/restore-tests/schedule.md b/ops/restore-tests/schedule.md index 4a65ead..50477df 100644 --- a/ops/restore-tests/schedule.md +++ b/ops/restore-tests/schedule.md @@ -19,6 +19,7 @@ Monatlich: - `vaultwarden` Mini-Restore - `gitea` Mini-Restore, versetzt zum Vaultwarden-Lauf +- `hetzner-snapshot` Storage-Box Snapshot-Restore-Test (read-only `.zfs/snapshot`; Erstlauf 2026-06-23 erfolgreich) Alle 2 Monate: @@ -69,6 +70,8 @@ Immich am 2026-05-27; Paperless erneut am 2026-05-31; Authelia am - DR-/Restore-Sanity-Check - Quartalsweise am 2. Sonntag im zweiten Quartalsmonat, 08:30: - `immich` +- Jeden 15. des Monats, 06:00: + - `hetzner-snapshot` ## Unraid User Scripts Cron @@ -83,6 +86,7 @@ Vixie-Cron (Unraid) verknuepft `day-of-month` und `day-of-week` mit **OR**, soba | `restore-authelia-bimonthly` | `30 7 * * 6` | `m=$(date +%-m); d=$(date +%-d); case "$m" in 2\|4\|6\|8\|10\|12) [ "$d" -ge 8 ] && [ "$d" -le 14 ];; *) false;; esac` | zweiter Samstag in geraden Monaten 07:30 | | `restore-immich-quarterly` | `30 8 * * 0` | `m=$(date +%-m); d=$(date +%-d); case "$m" in 2\|5\|8\|11) [ "$d" -ge 8 ] && [ "$d" -le 14 ];; *) false;; esac` | zweiter Sonntag in Feb/Mai/Aug/Nov 08:30 | | `monthly-random-restore` | `0 9 1 * *` | - | erster Kalendertag im Monat 09:00 | +| `restore-hetzner-snapshot-monthly` | `0 6 15 * *` | - | 15. des Monats 06:00 (read-only Snapshot-Test) | **Warum so**: ein frueheres Schema wie `0 7 1-7 * 6` haette in Vixie-Cron die OR-Semantik ausgeloest und an jedem Tag 1-7 zusaetzlich zu jedem Samstag gefeuert (~11 Laeufe statt 1 pro Monat). Die obige Trennung Cron-Trigger + Shell-Guard ist die einzige robuste Loesung in Standard-Cron.