83d7988c72
Task "KalliLab H Drive Nearline Pull" am 2026-06-21 von S4U auf LogonType
Interactive ("Nur ausfuehren, wenn der Benutzer angemeldet ist") umgestellt.
Kein gespeichertes Passwort noetig, da michi der dauerhaft angemeldete
Konsolen-User ist. Per Scheduler ausgeloest, Ergebnis 0x0 verifiziert
(SMB-Zugriff vorhanden, Spiegel frisch).
Doku korrigiert: README beschreibt jetzt Interactive als angewendete Loesung
(Password war nur die nicht genutzte Alternative). MASTER_TODO: Root-Cause
behoben, nur noch optionale Healthchecks-URL offen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
142 lines
6.2 KiB
Markdown
142 lines
6.2 KiB
Markdown
# H:/ Nearline-Backup — Struktur und Betrieb
|
|
|
|
Stand: 2026-06-21
|
|
|
|
## Rolle der H:/
|
|
|
|
Die externe HDD (asmedia ASM235, 7.4 TB, Laufwerk `H:`) dient ausschließlich als
|
|
**Nearline-Backup-Spiegel** für kritische Dumps und Git-Bundles.
|
|
|
|
Sie ist kein Primär-Backup (das ist Hetzner/Borg) und kein dauerhaftes Archiv.
|
|
|
|
## Sollzustand
|
|
|
|
```
|
|
H:\
|
|
└── kallilab-nearline-backups\
|
|
├── borg-dumps\latest\ ← aktuelle DB-Dumps (per Script)
|
|
├── git-bundles\gitea\ ← Gitea-Repo-Bundles (per Script)
|
|
├── _dr-kit\ ← SSH-Keys, Offline-Secrets (manuell)
|
|
├── _logs\ ← Robocopy-Logs je Lauf
|
|
└── _reports\ ← Markdown-Reports je Lauf
|
|
```
|
|
|
|
Nichts weiteres gehört dauerhaft auf die H:/.
|
|
Temporäre Recovery- oder Backup-Ordner aus Notfallsituationen sind nach
|
|
Abschluss zu löschen.
|
|
|
|
## Automatischer Pull
|
|
|
|
`pull-critical-backups.ps1` zieht per Robocopy vom Unraid-SMB-Share:
|
|
|
|
- `\\192.168.178.58\backups\borg\dumps\latest` → `borg-dumps\latest\`
|
|
- `\\192.168.178.58\backups\git-bundles\gitea` → `git-bundles\gitea\`
|
|
|
|
Der Windows Scheduled Task `KalliLab H Drive Nearline Pull` laeuft seit
|
|
2026-05-28 taeglich 05:30. Das Script kopiert bewusst **nicht** mit `/MIR` und
|
|
loescht nichts auf H:/; alte Artefakte werden nur nach manueller Sichtpruefung
|
|
entfernt.
|
|
|
|
> **Wichtig — Task-LogonType (kein S4U!):** Der Task darf **nicht** mit `S4U`
|
|
> laufen ("Unabhaengig von der Benutzeranmeldung ausfuehren" *mit* angehaktem
|
|
> "Kennwort nicht speichern"). S4U-Laeufe haben keine Netzwerk-Anmelde-
|
|
> informationen und erreichen den authentifizierten SMB-Share
|
|
> `\\192.168.178.58\backups` nicht -> jeder geplante Lauf bricht still mit
|
|
> Exitcode 1 ab, ohne Report. Genau das passierte 2026-06-19 bis 2026-06-21
|
|
> (Spiegel still veraltet).
|
|
>
|
|
> **Behoben am 2026-06-21:** Task auf **"Nur ausfuehren, wenn der Benutzer
|
|
> angemeldet ist"** (LogonType `Interactive`) umgestellt. Das braucht **kein**
|
|
> gespeichertes Passwort und funktioniert, weil `michi` der dauerhaft
|
|
> angemeldete Konsolen-User ist (gesperrter Bildschirm zaehlt als angemeldet).
|
|
> Per Planer ausgeloest und mit Ergebnis `0x0` verifiziert. Alternative waere
|
|
> LogonType `Password` (gespeichertes Passwort), erfordert aber das
|
|
> Windows-Passwort.
|
|
|
|
Aufruf zum Testen:
|
|
|
|
```powershell
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File G:\Gitea_Clone\homelab-infra\ops\h-drive-nearline\pull-critical-backups.ps1 -WhatIf
|
|
```
|
|
|
|
Das Script schließt bewusst aus:
|
|
- `unraid-flash-config.tar.gz` (0600 root:root, nicht per SMB zugänglich → Restore aus Hetzner-Borg)
|
|
- Migration-/Cutover-Verzeichnisse (`immich-vectorchord-*`, `pg18-major-*`, `redis8-*` etc.)
|
|
|
|
## Externer Dead-Man's-Switch
|
|
|
|
Der Pull lief ~2026-06-04 bis 2026-06-18 still gestoppt, ohne dass etwas Alarm
|
|
schlug (Scheduled Task fehlte; Prometheus auf Unraid sieht den baerchen-Pull
|
|
nicht). Gegenmittel: ein externer Heartbeat. `pull-critical-backups.ps1` pingt am
|
|
Lauf-Anfang `/start`, am Ende den Erfolg und im Fehlerfall `/fail`. Bleibt der
|
|
Erfolgs-Ping aus, alarmiert der externe Dienst von aussen.
|
|
|
|
Die Integration ist **endpoint-agnostisch**: jede Healthchecks-kompatible URL
|
|
funktioniert (Healthchecks.io-Cloud oder self-hosted). Ist keine URL gesetzt, ist
|
|
der Switch ein No-Op und der Pull laeuft unveraendert weiter.
|
|
|
|
URL-Quelle (in dieser Reihenfolge):
|
|
|
|
1. Parameter `-HealthchecksUrl`
|
|
2. ENV `HEALTHCHECKS_NEARLINE_URL`
|
|
3. Datei `%USERPROFILE%\.kallilab\healthchecks-nearline-url.txt`
|
|
|
|
Die Ping-URL ist eine Capability-URL -> wie ein Secret behandeln, nie ins Repo
|
|
(siehe `docs/SECRETS_MAP.md`).
|
|
|
|
### Operator-Setup (einmalig)
|
|
|
|
1. Check anlegen (Healthchecks.io oder self-hosted): Period = 1 Tag, Grace z. B.
|
|
2-3 h passend zum taeglichen 05:30-Task. Ping-URL kopieren.
|
|
2. Auf baerchen die URL hinterlegen, z. B. als Datei:
|
|
```powershell
|
|
New-Item -ItemType Directory -Force -Path "$HOME\.kallilab" | Out-Null
|
|
Set-Content -LiteralPath "$HOME\.kallilab\healthchecks-nearline-url.txt" -Value "https://hc-ping.com/<uuid>" -NoNewline
|
|
```
|
|
(alternativ als persistente User-Umgebungsvariable `HEALTHCHECKS_NEARLINE_URL`.)
|
|
3. Testlauf: `pull-critical-backups.ps1` ausfuehren; im Healthchecks-Dashboard
|
|
muss ein "success"-Ping ankommen.
|
|
|
|
### Borg-Pre-Hook-Pendant
|
|
|
|
Den gleichen Switch gibt es host-seitig in `ops/borg-ui/scripts/pre-borg.sh`.
|
|
URL dort via ENV `HEALTHCHECKS_BORG_URL` oder Datei
|
|
`/mnt/user/appdata/secrets/healthchecks_borg_url` (chmod 600), bewusst als
|
|
**eigener** Check (getrennter Heartbeat fuer die Unraid-Backup-Vorpruefung).
|
|
|
|
## _dr-kit
|
|
|
|
Enthält offline hinterlegte Schlüssel und Secrets für den DR-Fall:
|
|
- `dr-hetzner` / `dr-hetzner.pub` — SSH-Key für Hetzner Storage Box
|
|
- `dr-readonly` / `dr-readonly.pub` — Read-only Deploy-Key
|
|
- `KOmodo Secrets.txt` — Komodo Stack ENV-Offline-Dokumentation
|
|
|
|
Diese Dateien sind **manuell** zu pflegen und **nicht** vom Pull-Script verwaltet.
|
|
|
|
## Archiv-Ordner
|
|
|
|
Temporäre Notfall-Artefakte verbleiben als `_archiv-*`-Ordner bis zur bewussten
|
|
Löschentscheidung:
|
|
|
|
| Ordner | Inhalt | Anlassdatum |
|
|
|---|---|---|
|
|
| `kallilab-recovery\_archiv-nvme-crash-image-2026-05-14\` | nvme0n1 Disk-Image (1863 GB) + Crash-Runbooks aus dem Mai-2026-Ausfall | 2026-05-14 |
|
|
|
|
## Aufräum-Historie
|
|
|
|
| Datum | Aktion |
|
|
|---|---|
|
|
| 2026-06-10 | `OneDrive - Stroetmann Group\` gelöscht (leer) |
|
|
| 2026-06-10 | SSH-Keys + Secrets aus nearline-Root in `_dr-kit\` verschoben |
|
|
| 2026-06-10 | Migration-Artefakt-Verzeichnisse in `borg-dumps\latest\` gelöscht (immich-vectorchord-*, pg18-major-*, redis8-*, nextcloud-redis-pre-redis8-*, shared-redis-pre-redis8-*) |
|
|
| 2026-06-10 | Pre-major-prod-Dumps gelöscht (PG17→PG18-Migration abgeschlossen) |
|
|
| 2026-06-10 | `kallilab-recovery\2026-05-15\` gelöscht (DNS-Restore-Reste) |
|
|
| 2026-06-10 | `kallilab-recovery\2026-05-14\` → `_archiv-nvme-crash-image-2026-05-14\` umbenannt |
|
|
| 2026-06-10 | `kallilab-recovery\disk1-phase2-2026-05-23\` gelöscht (1677 GB Media-Share-Kopie; Unraid-Share verifiziert vollständig) |
|
|
|
|
## Offene Punkte
|
|
|
|
- `Windows-Neuaufsetzen-Backup\` (48 GB): nach vollständiger Rückspielung auf D:\ löschen
|
|
- `_archiv-nvme-crash-image-2026-05-14\` (1863 GB): löschen sobald sicher, dass nichts mehr aus dem alten System benötigt wird
|
|
- Log-Rotation für `_logs\` und `_reports\`: manuell oder per Script, Empfehlung 30 Tage
|