# BAK-02 – Prüfprotokoll: Objekt-Storage-Backup/Snapshots Welle 1, keine Vorbedingungen. ## Grundsatzentscheidung: restic statt Eigenbau Nutzerentscheidung: restic statt einer Neuimplementierung, weil restic alle vier Akzeptanzkriterien mit ausgereiftem, breit geprüftem Tooling erfüllt (Content-defined Chunking für Dedup, `check --read-data` für Vollständigkeit, `forget --keep-last` für Rotation, Repository-Verschlüsselung ab Werk). Installiert via `apt-get install restic` (Version 0.18.0). Backup-Quelle ist ein lokaler Verzeichnisbaum — für den FDN-03-`LocalDriver` direkt dessen Basisverzeichnis. Für S3-gestützte Produktions-Deployments (Betriebsmodus 2/3 aus `STORAGE-KONZEPT.md` Abschnitt 6.2) wäre ein vorgelagerter Sync-Schritt (z. B. `rclone`) nötig, um Bucket-Inhalte lokal zu spiegeln, bevor restic sie sichert — restic sichert Dateibäume, keine S3-Buckets direkt. Das bleibt hier bewusst unimplementiert (kein konkreter S3-Produktionsbestand vorhanden, der das aktuell erfordert), aber architektonisch vorgesehen und dokumentiert (`README.md`). ## Umsetzung - `internal/objectbackup.InitRepo` — idempotent, erkennt "bereits initialisiert" am `restic init`-Fehlertext statt zu scheitern. - `internal/objectbackup.Backup` — `restic backup --json`, parst die `summary`-Zeile (mehrere JSON-Zeilen in der Ausgabe, gezielt die mit `message_type=="summary"` gesucht). - `internal/objectbackup.Check` — `restic check [--read-data]` (Akzeptanz- kriterium 3: Vollständigkeitsprüfung). - `internal/objectbackup.Forget` — `restic forget --keep-last N --prune` (Rotation). - `cmd/objectbackup-cli` — `backup `/`check`/`rotate`, aufgerufen von systemd-Timern (stündlich/wöchentlich/täglich). ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Zweiter Sicherungslauf nach unverändertem Bestand überträgt keine Daten erneut | **bestanden** — `TestBackup_UnchangedSecondRunTransmitsNothingNew`: zweiter Lauf gegen unveränderten Bestand liefert `files_new=0`, `files_changed=0`, `files_unmodified=1` | | 2 | Zwei identische Testdateien belegen nachweislich nur einmal Speicherplatz | **bestanden** — `TestBackup_DeduplicatesIdenticalContent`: zwei Dateien mit identischem Inhalt erzeugen `data_blobs=1`, nicht 2 — echter Dedup-Nachweis über restics Content-defined Chunking, nicht nur Namensvergleich | | 3 | Vollständigkeitsprüfung erkennt ein fehlendes Objekt in der Sicherung | **bestanden** — `TestCheck_DetectsCorruptedPack`: ein Byte in einer echten Repository-Pack-Datei gekippt, `Check(readData=true)` schlägt danach fehl (unbeschädigt zuvor erfolgreich) — dieselbe Vorgehensweise wie die manuelle Recherche vor der Implementierung | Zusätzlich (nicht explizit als Pflichtprüfung gefordert, aber Teil von Akzeptanzkriterium 3 „lässt sich einzeln prüfen"): `TestForget_ KeepsOnlyRequestedSnapshotCount` — 3 Sicherungsläufe, `Forget(keepLast=1)` reduziert auf genau 1 verbleibenden Snapshot. ## Korrektur an BAK-01 im selben Rutsch: Backup-Zielverzeichnis Nutzerhinweis aufgegriffen: `NEXARCH_BACKUP_DIR` zeigte bei BAK-01 ursprünglich auf `/var/backups/nexarch` (Root-Dateisystem des LXC- Containers, nicht auf einem der beiden dedizierten ZFS-Datasets). Korrigiert auf `/var/nexarch-archiv/backups/postgres` (persistentes Dataset `zfs/data/subvol-1131-disk-0`), NICHT `/var/nexarch-test/` (ephemeres Dataset `ssd-rpool-data/swap/subvol-1131-disk-0`, wird von `reset-test-env.sh`-Skripten anderer Module geleert). `objectbackup-cli`s Repository liegt von Anfang an korrekt unter `/var/nexarch-archiv/backups/objects`. Beide Pfade real auf 192.168.1.131 verifiziert (`df`/`mount` bestätigt ZFS-Dataset-Zuordnung), BAK-01s Vollsicherung nach der Korrektur erneut über systemd ausgelöst und bestätigt am neuen Ort gelandet. ZFS-seitige Snapshot-/Replikations-Strategie für `nexarch/archiv` bleibt bewusst außerhalb dieses Tickets (Infra-Runbook, siehe `STORAGE-KONZEPT.md` Abschnitt 7 „Backup vs. Storage-Redundanz" sowie den Hinweis, `zfs dedup=on` NICHT zu setzen — App-seitige Dedup über restic genügt, ZFS-Dedup wäre auf dem 4-GB-Testhost ein Speicherrisiko). ## Echte Verdrahtung auf 192.168.1.131 - `objectbackup-cli` gebaut nach `/opt/nexarch-archive/bin/` - `/etc/nexarch/archive-objectbackup.env` (0600) - 3 systemd-Timer installiert und aktiviert: Sicherung stündlich (`:30`), Vollständigkeitsprüfung wöchentlich (So. 04:00 UTC), Rotation täglich (03:30 UTC) — `systemctl list-timers` bestätigt alle scharf - Jeder der drei Dienste einmal über `systemctl start` ausgelöst, alle mit `status=0/SUCCESS`; Journal bestätigt inhaltlich korrekte Ausgabe ## Build/Test-Ergebnis (192.168.1.131, `make check`) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues go test ./... -p 1 -count=1 -> 2/2 Pakete mit Tests ok (internal/backup, internal/objectbackup), 0 Fehlschläge ``` ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real gegen echtes restic-Tooling erfüllt. BAK-01-Pfadfehler im selben Rutsch korrigiert und erneut end-to-end verifiziert.