Recover disk space safely and complete metadata-only backup updates

This commit is contained in:
admin committed 2026-09-21 16:30:38 +02:00
1 parent 04283a607c
commit a5a7e38853
17 files changed
+827 -209

No files matched your search

+126 -41
View File
@@ -1,55 +1,140 @@
# Automatisches Update-Paket
## Deployment des bereitgestellten Pakets 3730ab4676a5
## Update vom 21.09.2026: Speicherblockade auflösen
Stand 15.09.2026: Der Code-Commit `3730ab4676a5` ist auf `origin/master`
veröffentlicht. Das daraus gebaute Paket und seine SHA-256-Datei liegen lokal
unter `dist/`; äußere Prüfsumme, interne Payload-Prüfsumme und alle 33 enthaltenen
Dateien wurden geprüft. Die nachfolgende Dokumentationsaktualisierung ändert den
Programmstand nicht. Das Paket bleibt für die bereits übermittelte Installation
gültig. Übertragung, Installation und neue Serverabnahme sind noch nicht bestätigt.
Das Paket enthält die unten beschriebenen Änderungen vom 16.09. und die neue
Speicherstrategie aus [SPEICHER.md](SPEICHER.md). Bei Platznot darf die automatische
Bereinigung jetzt bis auf `SPACE_KEEP_LOCAL=1` bestätigte lokale Sicherung
zurückgehen. Die normale Retention bleibt bei `RETENTION_KEEP_LAST=3`.
Der neue Standard gilt auch ohne Ergänzung der bestehenden Konfiguration.
Vor jeder Entfernung werden lokale Inhalte, Remote-Größen sowie Manifest und
Abschlussmarker geprüft. Die OneDrive-Sicherung wird dabei nicht gelöscht.
Die Übertragungs- und Startbefehle im folgenden Abschnitt gelten auch für dieses
Paket. Die Speicherbereinigung läuft bereits in der Paket-Vorprüfung. Es ist daher
kein vorheriges manuelles Löschen nötig. Der Starter kann für die lokale
Archivprüfung einige Zeit benötigen; das ausgegebene `preflight.log` zeigt den
Fortschritt. Bei weiterem Platzmangel enthält es eine Bestandsliste und das
verbleibende Defizit. Die Grenzen und das weitere Vorgehen stehen in `SPEICHER.md`.
Nach Installation lässt sich die Vorbereitung auch separat wiederholen:
```bash
sudo bash /usr/local/sbin/app-backup.sh --prepare-space
sudo bash /usr/local/sbin/app-backup.sh --check
df -h /var/backups/app-backup
```
`--prepare-space` löscht geeignete lokale Kopien nach den beschriebenen Prüfungen.
Es stoppt keine Anwendungen und erzeugt kein neues Backup. Das eigentliche Update
erstellt dagegen ein Abnahmebackup mit Anhalten der konfigurierten Writer.
Ein Rollback stellt gelöschte lokale Kopien nicht wieder her; sie bleiben offsite.
Die Abnahme auf Gemini steht bis zum neuen `SUCCESS` in `result.txt` aus.
### Lokale Prüfung am 21.09.2026
Der Gesamtlauf bestand mit 131 Fällen (123 erfolgreich, acht planmäßig
übersprungen; 993,3 Sekunden). Danach beziehungsweise ergänzend bestanden die
zwölf abschließenden Speicher-/Retry-Tests, zwei zusätzliche Integrationsfälle
für beschädigte Rückfallkopien und Signalabbrüche sowie alle drei Tests gegen
echten Benutzer-systemd. Zusammen sind **132 unterschiedliche Tests** erfolgreich
abgedeckt. Fünf optionale Tests mit zusätzlichen Docker-Datenbankcontainern wurden
bei dieser Änderung nicht erneut ausgeführt. Die Basissuite verwendet eine echte
isolierte MariaDB und lokale rclone-Crypt-Ziele; produktive Dienste und Mailversand
werden simuliert. ShellCheck, Shell-Syntax und `git diff --check` bestanden.
Geprüft sind insbesondere die Speicherblockade bei drei lokalen Kopien,
sofortiger Bereinigungsstopp bei ausreichendem Platz, Erhalt der letzten geprüften
und aller unbestätigten Kopien, unveränderte Offsite-Daten, beschädigte Manifeste/
Marker, begrenzte Wiederholungen, Signalabbrüche und Mount-/Recovery-Schutz.
Paketinstallation, ai-rem-Einbindung und Rollback bestanden ebenfalls. Das ersetzt
nicht die noch ausstehende Installation und Speicher-/Backup-Abnahme auf Gemini.
## Update vom 16.09.2026: Upload ohne Archiv-Rücklesen, ai-rem wieder aufnehmen
Der tägliche Lauf lädt Archive und Manifest über Crypt hoch und prüft anschließend
Dateiexistenz und Größe mit `rclone check --size-only`. Der kleine `COMPLETE`-Marker
wird zuletzt hochgeladen und weiterhin bytegenau bestätigt. Die Platzbereinigung
verwendet ebenfalls nur Remote-Dateiexistenz und Größen. Lokale Archivprüfungen
bleiben vollständig erhalten. Es gibt keinen täglichen Download der Archive.
Auch die Update-Abnahme endet nach erfolgreichem Backup und Remote-Dateiprüfung.
Sie startet keinen Offsite-Restore mehr. `SUCCESS` in `result.txt` bestätigt daher
Installation, Backup, Upload und Dateiprüfung; der separate Inhalts- und
Wiederherstellungsnachweis entsteht beim monatlichen Restore-Test. Schäden mit
unveränderter Dateigröße können erst beim Restore erkannt werden.
`--enable-ai-rem` ergänzt die auf Gemini geprüften Pfade `/srv/ai-rem`
(einschließlich Daten, Compose-Datei und eigener Sicherungen) und `/etc/ai-rem`
(einschließlich Environment-Datei). Vorhandene `EXTRA_PATHS` bleiben in ihrer
Reihenfolge erhalten; neue Pfade werden als weitere `extra-N` angehängt.
Wiederholte Aktivierung erzeugt keine zusätzlichen Einträge dieser Pfade.
Während der Kopie werden zuerst Healthcheck-, Backup- und Prune-Timer, danach ihre
Services und `ai-rem.service` angehalten. So wird die eingebettete Datenbank bei
beendetem Container kopiert. Vorher aktive Dienste starten nach der Kopie in
umgekehrter Reihenfolge wieder. Fehlende Pfade oder Units brechen die Vorbereitung
ab. Der Monatslauf prüft und entpackt auch diese Zusatzarchive; er startet keinen
ai-rem-Anwendungscontainer und führt keinen fachlichen Datenbanktest für ai-rem aus.
Die systemd-Units und Hilfsprogramme außerhalb dieser beiden Pfade müssen für eine
Neuinstallation separat verfügbar sein.
### Übertragen und starten
Nach dem Commit wird das Paket mit `python3 tools/build-update-package.py` aus dem
sauberen Repository gebaut. Der Dateiname enthält die ersten zwölf Zeichen des
Commits. In den folgenden Befehlen `VERSION` durch diesen Wert ersetzen; die
bereitgestellte Datei liegt unter `dist/`.
Auf dem Arbeitsplatz:
```bash
cd /home/johannes/localdev/app-backup/dist
scp app-backup-update-3730ab4676a5.run \
app-backup-update-3730ab4676a5.run.sha256 \
scp app-backup-update-VERSION.run app-backup-update-VERSION.run.sha256 \
johannes@gemini.jr-it-services.de:~/
```
Auf Gemini im Wartungsfenster starten; während der Datenkopie werden die
konfigurierten Anwendungen angehalten:
Auf Gemini im Wartungsfenster (Anwendungen werden während der Kopie angehalten):
```bash
ssh johannes@gemini.jr-it-services.de
cd ~
sha256sum -c app-backup-update-3730ab4676a5.run.sha256 &&
sudo bash app-backup-update-3730ab4676a5.run
sha256sum -c app-backup-update-VERSION.run.sha256 &&
sudo bash app-backup-update-VERSION.run --enable-ai-rem --enable-restore-test
```
Der bereits aktivierte Restore-Test wird übernommen; ein vorheriger Rollback
ist nicht erforderlich. Der Auftrag läuft unabhängig von der SSH-Verbindung.
Ein vorheriger Rollback ist nicht erforderlich. Bestehende Zugangsdaten und
Zeitpläne werden übernommen. `--enable-restore-test` stellt sicher, dass der
Monatstest aktiv ist, und bereitet sein MariaDB-Testimage vor. Diese kleine lokale
DB-Vorprüfung lädt keine Backup-Archive von OneDrive. Neue Timer laufen am ersten
Tag des Monats um 06:00 Uhr plus bis zu 15 Minuten Verzögerung; vorhandene Timer
behalten ihren Zeitplan. `Persistent=true` kann einen verpassten Monatstermin nachholen.
Der Auftrag läuft unabhängig von SSH. Verlauf und Ergebnis:
```bash
sudo journalctl -fu app-backup-upgrade.service --no-pager
```
`Strg+C` beendet nur die Loganzeige. Den vom Starter genannten Ergebnisordner
verwenden und `XXXXXXXX` durch dessen tatsächlichen Suffix ersetzen:
```bash
# Strg+C beendet nur die Loganzeige.
# Den tatsächlichen Ergebnisordner aus der Starter-Ausgabe einsetzen:
sudo cat /var/backups/app-backup-upgrade-XXXXXXXX/result.txt
sudo systemctl list-timers app-backup.timer app-restore-test.timer --no-pager
```
Erst `SUCCESS` in dieser neuen Ergebnisdatei bestätigt Installation, Backup und
Remote-Restore-Prüfung. Bei `QUEUED` oder `RUNNING` keinen zweiten Lauf starten.
Bei `FAILED` die Ergebnisdatei und die letzten Journalzeilen auswerten:
Erst `SUCCESS` in der neuen `result.txt` bestätigt den Abschluss. Bei `QUEUED` oder
`RUNNING` keinen zweiten Auftrag starten. Der abgenommene Lauf steht in
`uploaded-backup-run`; ein neuer Restore-Erfolg wird beim Update nicht behauptet.
Nach dem Monatstest stehen Ergebnis und letzte erfolgreiche Probe unter
`/var/backups/app-backup/restore-test/state.json` und `last-success.json`.
```bash
sudo journalctl -u app-backup-upgrade.service -n 150 --no-pager -l
```
Der fehlgeschlagene lokale Satz `appbackup_2026-09-15_21-03-40_21b6efeb`
bleibt erhalten. Das Update veröffentlicht ihn nicht nachträglich und setzt
seinen fehlenden `UPLOADED`-Nachweis nicht künstlich. Es erstellt einen neuen Lauf.
### Historische Fehleranalysen bis 15.09.2026
Die folgenden Nachträge beschreiben den damaligen Ablauf einschließlich sofortiger
Rücklese- und Restore-Abnahme. Für neue Installationen gilt der oben beschriebene
Ablauf vom 16.09.; die damaligen Paketnamen sind keine aktuelle Installationsanweisung.
## Nachtrag vom 15.09.2026: Healthcheck verdrängt Apache-Stop
@@ -143,12 +228,12 @@ Produktionsserie lesen, passendes lokales Image wiederverwenden oder laden und
einen isolierten Probeimport einschließlich Bereinigung ausführen. Manuelles
`docker pull` ist auf Gemini nicht mehr erforderlich. Die Option aktiviert
zugleich das adaptive Arbeitsbudget; Details: [RESTORE_TEST.md](RESTORE_TEST.md).
Danach prüft der Worker sein neues Offsite-Backup vollständig mit Entpacken und
DB-Import. Erst bei Erfolg aktiviert er Monatstimer und Boot-Bereinigung.
Nach erfolgreichem Backup mit Remote-Dateiprüfung aktiviert der Worker
Monatstimer und Boot-Bereinigung. Der vollständige Offsite-Restore folgt beim Monatstermin.
Vor der Vorprüfung werden erkannte Überreste fehlgeschlagener Backups bereinigt
und der nächste Snapshot geplant. Reicht der Platz nicht, werden geeignete ältere
lokale Kopien nach vollständiger Offsite-Rückleseprüfung entfernt; die neuesten
lokale Kopien nach lokaler Inhaltsprüfung und Remote-Datei-/Größenprüfung entfernt; die neuesten
`RETENTION_KEEP_LAST` bleiben geschützt. Diese Platzbereinigung gilt auch während
einer Update-Abnahme ohne reguläre Retention. Sie wird nicht durch Paketrollback
rückgängig gemacht; entfernte vollständige lokale Sätze bleiben offsite verfügbar.
@@ -169,7 +254,7 @@ auf den Server übertragen. Auf dem Server im selben Verzeichnis prüfen/starten
```bash
sha256sum -c app-backup-update-VERSION.run.sha256
sudo bash app-backup-update-VERSION.run --enable-restore-test
sudo bash app-backup-update-VERSION.run --enable-ai-rem --enable-restore-test
```
VERSION durch den tatsächlichen Dateinamen ersetzen. Ein Git-Checkout auf dem
@@ -212,14 +297,13 @@ abschwächen und sind im Backup-Prozess nicht unterstützt.
8. Backup-Timer stoppen, Paket mit Rollback-Inventar installieren, Konfiguration
atomar übernehmen und Rechte der aktiven root-eigenen Zugangsdaten korrigieren.
9. Vollständiges Backup ohne reguläre lokale/Remote-Altersretention durchführen.
Platzbereinigung bleibt erlaubt. Bei aktiviertem Restore-Test den Satz
komponentenweise herunterladen, entpacken und seine DB-Dumps isoliert importieren;
sonst alle Archive einzeln herunterladen und vollständig prüfen.
Platzbereinigung bleibt erlaubt. Upload mit anschließender Dateiexistenz-/
Größenprüfung und Bestätigung des Abschlussmarkers; keine Archivdownloads.
10. Erst bei Erfolg den Backup-Timer aktivieren und das Ergebnis protokollieren.
Es findet kein Import in produktive Anwendungen oder Datenbanken statt. Der
Prüflauf belegt bei aktiviertem Restore-Test auch Entpacken und DB-Import, ersetzt
aber keinen fachlichen Anwendungstest.
Update-Prüflauf bestätigt den Upload. Entpacken und DB-Import werden separat
beim Monatslauf geprüft; ein fachlicher Anwendungstest bleibt zusätzlich erforderlich.
## Verlauf und Ergebnis
@@ -288,7 +372,7 @@ Die neue Python-Berichtskomponente wird vom Installer samt Rollback installiert.
Beim Abnahmebackup entsteht eine Mail mit Laufzeit, Größen, Upload-Prüfstatus und
Log-Auszug. Das Update ist erst mit `SUCCESS` in seiner `result.txt` nach der
zusätzlichen Restore-Prüfung abgeschlossen. Fehlt die Mail, im Backup-Log nach
Remote-Dateiprüfung abgeschlossen. Fehlt die Mail, im Backup-Log nach
`mail report failed` suchen und die lokale `report_LAUF.eml`, sendmail-Verfügbarkeit,
MTA-Queue und Empfänger-/Aliaszustellung prüfen. Keine erneute Sicherung allein
zum Testen der Mailzustellung starten. Die Entwicklungstests verwenden eine lokale
@@ -604,7 +688,7 @@ Quelle: [rclone 1.74.3 OneDrive-Code](https://github.com/rclone/rclone/blob/v1.7
Die bisherigen Aufträge zeigten normale Fortschrittsstatistiken nicht an:
rclone meldet sie standardmäßig auf INFO, die normale Logschwelle ist NOTICE.
Das aktuelle Paket setzt `--stats-log-level NOTICE --stats-one-line` mit
`RCLONE_STATS_INTERVAL="1m"` und meldet die Phasen Upload, Rücklesen und
`RCLONE_STATS_INTERVAL="1m"` und meldet die Phasen Upload, Remote-Dateiprüfung und
Freigabe des Abschlussmarkers. Statistiken gehen nach stderr, damit maschinell
gelesene Marker und Dateilisten auf stdout unverändert bleiben.
Quelle: [rclone-Statistiken](https://rclone.org/docs/#stats-log-level-loglevel).
@@ -619,9 +703,10 @@ Quelle: [I/O-Leerlauffrist](https://rclone.org/docs/#timeout-duration).
Eine neue Paketdatei oder geänderte Config ergänzt keine Statistiken im bereits
laufenden rclone-Prozess. Keinen zweiten Upload parallel starten und den
vorhandenen lokalen Satz nicht löschen. Ein einzelner 409-Fehler begründet keine
Abschwächung der Prüfungen durch `--ignore-existing`/`--size-only`.
Entscheidend bleiben erfolgreiches Rücklesen,
Manifest-/Archivprüfung und `SUCCESS` in der Ergebnisdatei des konkreten Auftrags.
Änderung der Upload-Optionen wie `--ignore-existing`. Seit 16.09.2026 wird
`--size-only` gezielt beim Metadatenvergleich eingesetzt. Entscheidend sind lokale
Manifest-/Archivprüfung, erfolgreicher Upload mit Remote-Dateiprüfung und
`SUCCESS` in der Ergebnisdatei; der Monatslauf liefert den separaten Restore-Nachweis.
## Paket reproduzieren