475 lines
27 KiB
Markdown
475 lines
27 KiB
Markdown
# Automatisches Update-Paket
|
|
|
|
Auf dem Arbeitsplatz die gelieferte `.run`-Datei und ihre `.sha256`-Datei per SCP
|
|
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
|
|
```
|
|
|
|
VERSION durch den tatsächlichen Dateinamen ersetzen. Ein Git-Checkout auf dem
|
|
Server ist nicht erforderlich. Der Installer benötigt die vorhandene Konfiguration
|
|
`/etc/app-backup/app-backup.conf` und die bisherigen aktiven Zugangsdaten.
|
|
|
|
Der Start ist die Freigabe für das Update einschließlich eines vollständigen
|
|
Backups mit zeitweiliger Unterbrechung der konfigurierten Anwendungen.
|
|
|
|
## Was automatisch passiert
|
|
|
|
Nach dem erfolgreichen Gemini-Lauf wurden Fortschrittsmeldungen, eine Prüfung
|
|
exportierter rclone-Optionen und der bytegenaue Vergleich des Abschlussmarkers
|
|
ergänzt. Für diese Härtung das aktuelle Paket im
|
|
vereinbarten Wartungsfenster über denselben Installer installieren; die bestehenden
|
|
Zugangsdaten und der Zeitplan bleiben erhalten. Der Installer führt erneut ein
|
|
vollständiges Abnahmebackup durch. Die technische Abnahme des bisherigen Satzes
|
|
bleibt gültig; der einmalige, überwundene HTTP-409 allein erfordert keinen Neustart.
|
|
|
|
Falls die neue Vorprüfung `Unsupported rclone environment override` meldet,
|
|
die genannte Einstellung in Shell oder systemd-Umgebung prüfen und entfernen
|
|
beziehungsweise in eine unterstützte Backup-Einstellung überführen. Keine
|
|
Optionswerte oder Zugangsdaten ins Protokoll kopieren. Globale rclone-Filter und
|
|
`RCLONE_SIZE_ONLY` können Sicherungsumfang beziehungsweise Inhaltsprüfung
|
|
abschwächen und sind im Backup-Prozess nicht unterstützt.
|
|
|
|
1. Paketinhalt per SHA-256 prüfen und geschützt unter `/var/tmp` entpacken.
|
|
2. Bestehende Einstellungen nach `/var/backups/app-backup-upgrade-XXXXXXXX` sichern.
|
|
3. Aktuelle Pfade und Einstellungen übernehmen; sichere Betriebsoptionen ergänzen.
|
|
4. Vorhandene Webdienste und direkt erkennbare Nextcloud-systemd-Writer zuordnen.
|
|
5. Crypt-Konfiguration, DB-Dateien, globales DB-Recht `RELOAD` und bei MariaDB
|
|
Zugriff auf Routinen-Metadaten prüfen;
|
|
vorhandene Schlüssel/Passwörter erhalten. Keine automatischen DB-Grants.
|
|
6. Vorprüfung mit geschützten Kopien durchführen. rsync prüft außerdem den Zugriff
|
|
auf Quellverzeichnisse und deren Attribute in einem privaten temporären
|
|
Prüfbereich, ohne Datei-Inhalte zu kopieren. Bei Fehlern bleibt das installierte
|
|
Paket samt Anwendungskonfiguration und Timer unverändert.
|
|
7. Einen von SSH unabhängigen systemd-Auftrag `app-backup-upgrade.service` mit
|
|
`--no-block` einreihen und die Sperren an ihn übergeben.
|
|
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 lokale/Remote-Retention durchführen. Anschließend den
|
|
abgeschlossenen Satz nochmals über Crypt herunterladen und mit dem Restore prüfen.
|
|
10. Erst bei Erfolg den Backup-Timer aktivieren und das Ergebnis protokollieren.
|
|
|
|
Es findet kein Import in produktive Anwendungen oder Datenbanken statt. Der
|
|
Remote-Prüflauf belegt Archivlesbarkeit, ersetzt aber keinen fachlichen Test-Restore.
|
|
|
|
## Verlauf und Ergebnis
|
|
|
|
```bash
|
|
sudo journalctl -fu app-backup-upgrade.service --no-pager
|
|
```
|
|
|
|
Der Starter nennt außerdem den **konkreten** Ergebnisordner:
|
|
|
|
```bash
|
|
sudo cat /var/backups/app-backup-upgrade-XXXXXXXX/result.txt
|
|
sudo less /var/backups/app-backup-upgrade-XXXXXXXX/update.log
|
|
```
|
|
|
|
Erwartet wird `SUCCESS`. Bei `QUEUED` oder `RUNNING` nicht parallel erneut starten.
|
|
`QUEUED` bedeutet, dass der Auftrag zur Übergabe vorbereitet wurde und noch kein
|
|
Worker den Start bestätigt hat. Ein erfolgreicher Starter bestätigt nur die
|
|
Annahme durch systemd; Installation und Backup können anschließend noch scheitern.
|
|
Nach Ende verschwindet die kurzlebige systemd-Unit durch `--collect` auch bei
|
|
Fehlern. `Unit ... could not be found` ist daher kein Erfolgsnachweis und verhindert
|
|
die Journalabfrage nicht. Log und Ergebnis bleiben erhalten. Diagnose ohne Pager:
|
|
|
|
```bash
|
|
sudo journalctl -u app-backup-upgrade.service -n 100 --no-pager -l
|
|
sudo systemctl status app-backup-upgrade.service --no-pager -l
|
|
```
|
|
|
|
Bleibt `QUEUED` stehen, zuerst das Journal prüfen: Ein Fehler noch vor dem Start
|
|
des Bash-Workers (z. B. ein nicht ausführbarer Paketpfad) kann noch nicht in
|
|
`update.log` oder `result.txt` durch den Worker protokolliert werden. Ein späterer
|
|
Sperr-Timeout erscheint dagegen in beiden Dateien. Nicht allein auf den Exit-Code
|
|
von `systemd-run` vertrauen.
|
|
`--foreground` führt den Vorgang stattdessen im aktuellen Terminal aus und ist
|
|
für Tests/Diagnose gedacht; dabei besteht keine Absicherung gegen SSH-Abbruch.
|
|
|
|
## Gezielte Rückfragen und Grenzen
|
|
|
|
### Mailberichte nach dem Update
|
|
|
|
Das Paket stellt die ausführlichen Mailberichte wieder bereit. Vorhandene Werte
|
|
für `ENABLE_MAIL_REPORT`, `MAIL_TO`, `MAIL_FROM`, `MAIL_SUBJECT_PREFIX` und
|
|
`MAIL_INCLUDE_LOG_TAIL_LINES` bleiben erhalten; sie müssen nicht neu eingegeben
|
|
werden. Eine bislang deaktivierte Berichtsfunktion bleibt deaktiviert. Fehlende
|
|
Absender-/Betreff-/Tail-Einstellungen erhalten die in README beschriebenen Defaults.
|
|
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
|
|
`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
|
|
MTA-Attrappe und versenden keine echten Nachrichten.
|
|
|
|
### Quellen und Writer
|
|
|
|
- **Zentrales Mailverzeichnis fehlt, etwa `/var/vmail`:** Der Installer fragt vor
|
|
der Installation nach dem tatsächlichen absoluten Pfad. Alternativ lässt sich
|
|
dieser mit `--mail-dir /tatsaechliche/mailablage` übergeben. Kein leeres
|
|
Ersatzverzeichnis anlegen: Das würde fehlende Maildaten nur verdecken.
|
|
Liegen **alle** Mailboxen in den angezeigten `MAIL_HOME_DIRS`, im Dialog `homes`
|
|
wählen und die vollständige Abdeckung bestätigen. `--mail-homes-only` erteilt
|
|
dieselbe ausdrückliche Bestätigung ohne Dialog. Dabei müssen die Home-Sicherung
|
|
aktiviert und alle konfigurierten Homes vorhanden sein. Excludes und
|
|
Dateisystemgrenzen gelten weiterhin; ausgeschlossene Verzeichnisse, verlinkte
|
|
externe Mailablagen und weitere Mounts sind dadurch nicht abgedeckt.
|
|
Postfix/Dovecot-Konfigurationen und Maildienst-Stopps bleiben aktiv.
|
|
Bei unbekannter Mailablage abbrechen und zuerst die Mailserver-Konfiguration
|
|
prüfen. Ein fehlender Pfad wird nie automatisch übersprungen.
|
|
- **Rclone-Datei nicht eindeutig:** Pfad im Dialog oder mit `--rclone-config FILE`
|
|
angeben. Eine user-eigene Datei wird in eine neue root-eigene Datei kopiert;
|
|
die vom Benutzer verwendete Originaldatei bleibt unverändert.
|
|
- **Gitea bisher nicht konfiguriert:** Aufnahme bestätigen oder bewusst
|
|
`--no-gitea` setzen. Absolute explizite Pfade und der MySQL-DB-Name können aus
|
|
`app.ini` übernommen werden. Mehrdeutige/relative Pfade müssen zuerst in der
|
|
vorhandenen Backup-Konfiguration ergänzt werden; es werden keine geratenen
|
|
Repository-Pfade eingetragen.
|
|
- **Nextcloud in crontab:** Der Installer fragt, ob der gefundene Cron-Dienst
|
|
während jeder Sicherung angehalten werden darf. Das betrifft auch andere
|
|
Cronjobs; währenddessen fällige Jobs können ausfallen. Alternativ Nextcloud
|
|
zuvor in einen eigenen systemd-Service/Timer übertragen. Bereits gestartete
|
|
direkte `cron.php`-/`occ`-Prozesse werden nach dem Writer-Stopp abgewartet
|
|
(Default 300 Sekunden), nicht blind beendet. Shell-Wrapper, externe Scheduler
|
|
und nicht direkt erkennbare Writer müssen explizit berücksichtigt werden.
|
|
- **Fehlende Basispakete:** Installation über `dnf` nach Rückfrage oder mit
|
|
`--install-deps`. Keine automatische Aktualisierung von PHP, DB-Server oder
|
|
rclone auf eine möglicherweise inkompatible Version.
|
|
- **Verschlüsselte rclone-Konfigurationsdatei:** Die für rclone benötigte
|
|
Entsperrung muss auch im systemd-Kontext verfügbar sein. Ohne verfügbare
|
|
Entsperrung bricht die Prüfung ab, statt unsichtbar auf eine Passworteingabe zu warten. Der Installer legt
|
|
keine neuen Crypt-Passwörter an und exportiert keine fremden Secret-Stores.
|
|
- **Früher eingecheckte DB-Passwörter:** Passwortrotation bleibt separat, weil
|
|
weitere Benutzer derselben Accounts nicht zuverlässig ermittelt werden können.
|
|
|
|
Optionen können kombiniert werden:
|
|
|
|
```bash
|
|
sudo bash app-backup-update-VERSION.run \
|
|
--rclone-config /root/.config/rclone/rclone.conf \
|
|
--enable-gitea --cron-services nextcloudcron.timer,nextcloudcron.service
|
|
```
|
|
|
|
Die Remote-Retention bleibt nach der Migration ausgeschaltet. Nach einem echten
|
|
Test-Restore bei Bedarf bewusst wieder aktivieren. Bestehende Timer-Zeitpläne
|
|
bleiben erhalten; beim Aktivieren kann `Persistent=true` einen Lauf nachholen.
|
|
|
|
## Fehler und Rückweg
|
|
|
|
### Startfehler nach genau 60 Sekunden bei älteren Paketen
|
|
|
|
Die Pakete `8e6c9a058fa9` und `56fbcdad74f4` enthielten einen Fehler in der
|
|
systemd-Übergabe: Der Starter hielt die Update-Sperre und wartete synchron auf
|
|
den Abschluss des Startauftrags einer `Type=oneshot`-Unit. Dieser Startauftrag
|
|
endet erst mit dem Worker; der Worker wartete aber selbst auf die Sperre des
|
|
Starters. Nach 60 Sekunden brach seine Sperranforderung ab, noch vor Installation
|
|
und Timer-Stopp. In diesem Ablauf ist kein Rollback erforderlich. Der ursprüngliche
|
|
Worker hatte vor dem Sperrwarten noch kein eigenes Log eingerichtet, daher konnte
|
|
die Fehlermeldung auf den systemd-Exit-Code beschränkt bleiben.
|
|
|
|
Das korrigierte Paket verwendet `systemd-run --no-block` und gibt zuerst die
|
|
Backup-Sperre, dann die Update-Sperre frei. Eine fehlgeschlagene Übergabe entzieht
|
|
auch einem möglicherweise schon eingereihten Worker die Freigabe. Die Sperren
|
|
bleiben als Schutz vor parallelen Backups/Updates erhalten. Erneut das **neue**
|
|
Paket starten; weder Sperrdateien löschen noch alte Worker manuell nachstarten.
|
|
|
|
Das Verhalten von `--no-block` und `--collect` ist in der
|
|
[systemd-Dokumentation](https://github.com/systemd/systemd/blob/v256/man/systemd-run.xml)
|
|
beschrieben, der Startabschluss von `oneshot` in
|
|
[systemd.service](https://github.com/systemd/systemd/blob/v256/man/systemd.service.xml).
|
|
|
|
### Fehlende Mailablage und erneuter Start
|
|
|
|
Ein Abbruch `Missing source: /var/vmail` bei der **Vorprüfung**, wie beim Paket
|
|
`8e6c9a058fa9`, erfordert kein Rollback. Mit dem korrigierten Paket erneut starten
|
|
und die Mailablage klären. Die bisherige Konfiguration und der Timer sind erhalten;
|
|
der abgebrochene Versuch enthält noch kein erfolgreiches neues Backup.
|
|
Bereits bewusst getroffene Entscheidungen können als Optionen mitgegeben werden:
|
|
|
|
```bash
|
|
sudo bash app-backup-update-VERSION.run --enable-gitea --cron-services crond.service
|
|
```
|
|
|
|
Diese Optionen passen nur, wenn Gitea aufgenommen werden soll und das Pausieren
|
|
aller Cronjobs über `crond.service` ausdrücklich akzeptiert wurde.
|
|
|
|
Für Mailablagen wie `/home/johannes/Mail` unter den konfigurierten Benutzerhomes
|
|
zusätzlich `--mail-homes-only` verwenden, sofern damit alle Postfächer erfasst sind:
|
|
|
|
```bash
|
|
sudo bash app-backup-update-VERSION.run \
|
|
--enable-gitea --cron-services crond.service --mail-homes-only
|
|
```
|
|
|
|
Der Installer zeigt die übernommenen Home-Verzeichnisse an. `Mail/` einschließlich
|
|
`cur`, `new`, `tmp` und Dovecot-Dateien wird mit den normalen Home-Excludes der
|
|
Vorlage vollständig kopiert, sofern es auf demselben Dateisystem liegt und kein
|
|
Verweis auf eine externe Ablage ist. Weitere Benutzer müssen in `MAIL_HOME_DIRS`
|
|
stehen; das Vorhandensein eines einzelnen Postfachs belegt nicht deren Abdeckung.
|
|
|
|
### Fehler nach Installationsbeginn
|
|
|
|
Bei einem Fehler nach Beginn der Installation bleibt der Backup-Timer gestoppt.
|
|
Es erfolgt kein automatisches Zurücksetzen über möglicherweise noch laufende oder
|
|
teilweise wiederhergestellte Anwendungen. Logs und gegebenenfalls
|
|
`recovery-*.json` im Workdir prüfen. Das kombinierte Rollback stellt die vorherigen
|
|
Paketdateien **und** die vorherige Backup-Hauptkonfiguration wieder her:
|
|
|
|
```bash
|
|
sudo bash /var/backups/app-backup-upgrade-XXXXXXXX/rollback-update.sh
|
|
```
|
|
|
|
Es verändert keine gesicherten Anwendungsdaten, rotiert keine Zugangsdaten und
|
|
startet den Timer nicht ungeprüft. Neu erzeugte root-eigene Kopien von rclone-Dateien
|
|
sowie strengere Dateirechte bleiben erhalten. Bei unterbrochener Vorbereitung
|
|
ohne Installationsbeginn ist kein Paket-Rollback erforderlich.
|
|
|
|
### Fehlendes DB-Recht RELOAD
|
|
|
|
`mariadb-dump: ... FLUSH ... Access denied ... RELOAD ... (1227)` bedeutet:
|
|
Die Anmeldung funktioniert, aber dem tatsächlich verwendeten DB-Konto fehlt das
|
|
globale Sperrrecht für `--lock-all-tables`. Ein pauschaler Wechsel auf einen Dump
|
|
ohne Sperren oder ausschließlich `--single-transaction` ist bei gemischten
|
|
Storage Engines kein gleichwertiger Ersatz. Das neue Paket prüft `RELOAD` bereits
|
|
vor Installation und Wartungsmodus über lesende Privileg-Metadaten.
|
|
|
|
Die tatsächlich authentifizierten Konten und Serverversionen ermitteln. Zunächst
|
|
eine Root-Shell starten:
|
|
|
|
```bash
|
|
sudo bash
|
|
```
|
|
|
|
Erst in dieser Shell den folgenden Block ausführen. Er gibt keine Passwörter
|
|
oder Authentifizierungshashes aus und beendet anschließend die Root-Shell:
|
|
|
|
```bash
|
|
source /etc/app-backup/app-backup.conf
|
|
query='SELECT CURRENT_USER(), VERSION()'
|
|
echo WordPress
|
|
mariadb --defaults-extra-file="$WP_DB_CNF" -N -B -e "$query"
|
|
echo Nextcloud
|
|
mariadb --defaults-extra-file="$NC_DB_CNF" -N -B -e "$query"
|
|
echo Gitea
|
|
mariadb --defaults-extra-file="$GITEA_DB_CNF" -N -B -e "$query"
|
|
exit
|
|
```
|
|
|
|
Nur die Zeilen für tatsächlich konfigurierte Anwendungen ausführen. Die getrennte
|
|
Root-Shell vermeidet Probleme durch kopierte Einrückungen an Here-Doc-Abschlussmarken.
|
|
|
|
Mit einem DB-Administratorkonto nur die betroffenen, vorhandenen Backup-Konten
|
|
berechtigen. Beispiel für das **zuvor tatsächlich identifizierte** Konto
|
|
`backup@localhost` (nicht ungeprüft übernehmen):
|
|
|
|
```sql
|
|
GRANT RELOAD ON *.* TO 'backup'@'localhost';
|
|
```
|
|
|
|
`RELOAD` ist ein globales Verwaltungsrecht zum Flush/Reload; deshalb wird es nicht
|
|
automatisch durch den Paketinstaller vergeben. Keine pauschalen `ALL PRIVILEGES`
|
|
oder `GRANT OPTION` erteilen. Wenn die CNF ein produktives Anwendungskonto verwendet,
|
|
ein separates Backup-Konto mit gezielten Rechten vorbereiten. Ein zusätzliches
|
|
`FLUSH PRIVILEGES` ist nach `GRANT` nicht notwendig. Quelle:
|
|
[MariaDB GRANT](https://mariadb.com/docs/server/reference/sql-statements/account-management-sql-statements/grant).
|
|
|
|
Für MariaDB prüft das Paket außerdem den Lesezugriff auf `mysql.proc`, den die
|
|
verwendete Option `--routines` benötigt. Falls dieser fehlt, gezielt für das
|
|
identifizierte Backup-Konto vergeben:
|
|
|
|
```sql
|
|
GRANT SELECT ON mysql.proc TO 'backup'@'localhost';
|
|
```
|
|
|
|
Auch dies ist ein Beispiel mit zu ersetzendem Kontonamen. Es erlaubt den Zugriff
|
|
auf Routinen-Metadaten datenbankübergreifend; kein `SELECT ON mysql.*` vergeben.
|
|
Quelle: [MariaDB mariadb-dump / routines](https://mariadb.com/docs/server/clients-and-utilities/backup-restore-and-import-clients/mariadb-dump).
|
|
|
|
Weitere erforderliche Rechte hängen von Views, Triggern und Events ab;
|
|
`RELOAD` allein ersetzt keine Leserechte auf den zu sichernden Datenbanken.
|
|
Die neue Prüfung deckt die globale Sperrberechtigung und MariaDB-Routinen-Metadaten
|
|
ab, nicht sämtliche möglichen Objektrechte. Der vollständige Abnahmelauf bleibt verpflichtend.
|
|
|
|
Beim gemeldeten Lauf vom 10.09.2026 um 14:41 Uhr war das Paket bereits installiert,
|
|
als der erste Dump scheiterte. Nextcloud verließ laut Log den Wartungsmodus und
|
|
Cron wurde wieder gestartet. Das ist **kein erfolgreiches Backup**; der Timer
|
|
bleibt bis zur Abnahme gestoppt. Nach Rechtekorrektur das aktuelle Paket erneut
|
|
starten: Es prüft, sichert und aktiviert den Timer erst nach erfolgreicher
|
|
Remote-Prüfung. Ein erneuter Paketlauf erhält die ursprüngliche Sicherung des
|
|
vorigen Update-Versuchs. Für einen Rückweg zum Stand vor dem ersten Installationslauf
|
|
ist dessen Rollback-Ordner maßgeblich; ein späterer Snapshot enthält bereits die
|
|
zuvor installierte Version.
|
|
|
|
Dienst-Stopps/-Starts und das Warten auf Nextcloud-Writer werden jetzt ausdrücklich
|
|
im Journal protokolliert. Eine längere Pause ohne CPU-Last lässt sich so einem
|
|
konkreten Dienst zuordnen; ohne dessen Journal lässt sich die Ursache der Pause
|
|
nicht aus ihrer Dauer allein bestimmen.
|
|
|
|
## SELinux: rsync-Zugriff verweigert (Exit 23)
|
|
|
|
Der Gemini-Lauf vom 10.09.2026 um 14:58 Uhr scheiterte nach drei erfolgreichen
|
|
DB-Dumps beim Kopieren von `/var/www/html`. Das Audit bestätigt rsync im Kontext
|
|
`rsync_t`: Lesen von `httpd_sys_content_t` sowie Attributänderungen und Relabeling
|
|
im Staging wurden verweigert. Zusätzlich wurden geerbte Sperrdeskriptoren beanstandet.
|
|
Die gestoppten Dienste wurden laut Journal wieder gestartet und Nextcloud verließ
|
|
den Wartungsmodus. Es entstand kein vollständiger neuer Sicherungssatz.
|
|
|
|
Das aktuelle Paket setzt für den Update-Auftrag und den installierten Backup-Dienst
|
|
`SELinuxContext=system_u:system_r:unconfined_service_t:s0` und startet beide über
|
|
`/bin/bash`. **Diese privilegierten Prozesse und ihre Kindprozesse laufen damit
|
|
ohne SELinux-Einschränkung.** SELinux bleibt systemweit aktiv; andere Dienste
|
|
behalten ihre bestehende Policy. Der Installer ändert keine globalen rsync-Booleans,
|
|
keine Quell-Labels und keine Quellberechtigungen. Ein nicht zugelassener Kontext
|
|
führt zu einem sichtbaren Startfehler.
|
|
|
|
Auf Gemini ist die Bash-Startkette mit diesem Kontext und erfolgreichem
|
|
rsync-Auflisten des Webverzeichnisses unter Enforcing geprüft. Der direkte
|
|
Unit-Start von `/usr/bin/rsync` scheiterte dagegen mit 203/EXEC und bildet die
|
|
Startkette des Pakets nicht ab. Manuelle Unit-Anpassungen sind nicht erforderlich:
|
|
das aktuelle Paket mit denselben Gitea-/Cron-/Mail-Optionen erneut starten.
|
|
|
|
Vor dem Wartungsmodus prüft das Paket über rsync die Quellverzeichnisse und die
|
|
Übernahme ihrer Verzeichnisattribute in einen privaten temporären Prüfbereich.
|
|
Dabei werden keine Dateiinhalte kopiert. Die Probe erfasst nicht jede untergeordnete
|
|
Datei; der vollständige Kopierlauf und die Remote-Prüfung bleiben erforderlich.
|
|
rsync erhält keine geerbten Sperrdeskriptoren; die Elternprozesse halten die Sperren
|
|
weiter. Der SELinux-Kontext des Backup-Prozesses erscheint im Protokoll.
|
|
|
|
Bei einem erneuten Fehler `update.log`, die ausgegebene Ergebnisdatei und die
|
|
passenden AVC-Meldungen prüfen. Maßgeblich für den erfolgreichen Abschluss bleibt
|
|
`SUCCESS` in `result.txt`; erst danach aktiviert der Installer den Backup-Timer.
|
|
Eine Wiederherstellungsprobe auf einem separaten System steht weiterhin aus.
|
|
|
|
## Erneuter Dienststart während der Sicherung
|
|
|
|
Am 10.09.2026 starteten auf Gemini um 15:15 Uhr Apache und PHP-FPM während der
|
|
Nextcloud-Datenkopie erneut. Paket `c0a24b63fc1c` hatte die SELinux-Zugriffe bereits
|
|
korrigiert, schützte jedoch nicht vor fremden Startaufträgen. Den betroffenen
|
|
Lauf nicht als konsistente Sicherung abnehmen, auch falls Upload/Hashprüfung
|
|
anschließend erfolgreich waren. Der konkrete Auslöser des Startauftrags ist
|
|
noch offen. Die 90 Sekunden Apache-Stopp sind dagegen durch dessen Journal
|
|
erklärt: Timeout beim Beenden, anschließend SIGKILL durch systemd. Das neue Paket
|
|
ändert weder Apache-Timeout noch seine Signalbehandlung pauschal.
|
|
|
|
Einen noch laufenden alten Update-Auftrag kontrolliert beenden:
|
|
|
|
```bash
|
|
sudo systemctl stop app-backup-upgrade.service
|
|
sudo journalctl --no-pager -u app-backup-upgrade.service -n 60
|
|
sudo systemctl --no-pager is-active httpd php-fpm gitea postfix dovecot crond
|
|
```
|
|
|
|
Im Protokoll die Wiederaufnahme und das Verlassen des Wartungsmodus prüfen.
|
|
Bei Fehlern die ausgegebene `recovery-*.json` beachten. Erst nach abgeschlossenem
|
|
alten Auftrag das aktuelle Paket mit den bisherigen Gitea-/Cron-/Mail-Optionen
|
|
starten. Bestehende Sicherungssätze und Arbeitsverzeichnisse nicht pauschal löschen.
|
|
|
|
Das neue Paket richtet für die Kopierphase vorübergehende systemd-Startbedingungen
|
|
ein und prüft Writer-Zustände sowie Aktivierungszeitpunkte vor/nach den Kopien.
|
|
Es entfernt beim Wiederanlauf nur eigene Ergänzungen; bei einem teilweise
|
|
ausgeführten Restore bleiben sie bis zur manuellen Prüfung bestehen. Einzelheiten
|
|
zur gezielten Freigabe stehen in `Dokumentation.md` bei der Wiederanlaufhilfe.
|
|
Die permanente Dienstkonfiguration und vorhandene Maskierungen bleiben erhalten.
|
|
Die Meldung `Copy window complete; writer guards verified` bestätigt das Ende
|
|
der geprüften Kopierphase. Abgeschlossen ist die Paketabnahme erst bei `SUCCESS`
|
|
in der Ergebnisdatei nach vollständiger Remote-Prüfung.
|
|
|
|
Der Abbruchpfad wurde ebenfalls korrigiert: Bisher erreichte TERM bei
|
|
`KillMode=mixed` zunächst nur den Update-Hauptprozess. Eine wartende Bash konnte
|
|
dadurch den Stop bis zum Ende ihres Backup-/Upload-Kindprozesses verzögern.
|
|
Die neuen Units verwenden `KillMode=control-group`; die Protokollprozesse bleiben
|
|
während der Fehlerbehandlung verfügbar. Nach einem Update-Abbruch das Journal
|
|
und die Dienstzustände prüfen; insbesondere ein Stop-Timeout ist kein Nachweis
|
|
für eine erfolgreiche Wiederaufnahme. Die Änderung wirkt für neue Aufträge,
|
|
nicht nachträglich für einen bereits gestarteten alten Worker.
|
|
|
|
## OneDrive: HTTP 409 resourceModified und stilles Journal
|
|
|
|
Der Lauf auf Gemini vom 10.09.2026 ab 15:30 Uhr hat die geschützte Kopierphase
|
|
und Dienstwiederaufnahme erfolgreich abgeschlossen. Um 15:46:11 meldete rclone
|
|
1.74.3 bei `wordpress.tar.zst` HTTP 409 `resourceModified`; das deutet auf einen
|
|
Versions-/eTag-Konflikt am OneDrive-Objekt. Der konkrete Auslöser ist anhand
|
|
dieser Meldung nicht bestimmt. Das später übermittelte Protokoll bestätigt:
|
|
Der erste Kopierversuch endete um 15:56:33 mit einem Fehler, der zweite war um
|
|
15:58:03 erfolgreich. Die Rückleseprüfung meldete um 15:59:37 `0 differences found`
|
|
und `15 matching files`. Danach bestand die separate Remote-Restore-Prüfung
|
|
für 14 Archive, gefolgt von `SUCCESS` und `Backup-Timer aktiv.`
|
|
Der Satz `appbackup_2026-09-10_13-30-17_ff95c1ac` hat damit die technische
|
|
Paketabnahme bestanden. Das zuvor gelesene `RUNNING` stammte aus der noch
|
|
laufenden Prüfung. Auch die mit `ERROR` protokollierte Zeile
|
|
`Attempt 2/6 succeeded` beschreibt einen erfolgreichen Wiederholungsversuch.
|
|
Eine erneute Installation allein wegen dieses überwundenen Konflikts ist nicht nötig.
|
|
|
|
HTTP 409 ist in dieser rclone-Version nicht in der allgemeinen Liste unmittelbar
|
|
wiederholter OneDrive-HTTP-Fehler enthalten. `--low-level-retries 20` bedeutet daher
|
|
nicht, dass genau dieser Fehler sofort 20-mal versucht wird. Die standardmäßig
|
|
bis zu sechs Versuche über `--retries` betreffen den übergeordneten Kopierauftrag;
|
|
andere Dateiübertragungen können vor dessen Wiederholung noch laufen. Bei als
|
|
fatal oder nicht wiederholbar eingestuften Fehlern kann rclone früher abbrechen.
|
|
Quelle: [rclone 1.74.3 OneDrive-Code](https://github.com/rclone/rclone/blob/v1.74.3/backend/onedrive/onedrive.go),
|
|
[Wiederholungen](https://rclone.org/docs/#retries-int).
|
|
|
|
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
|
|
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).
|
|
|
|
`RCLONE_TIMEOUT="1h"` ist die bestehende I/O-Leerlauffrist, keine Gesamtlaufzeit
|
|
und kein Versprechen einer Meldung pro Minute. `RUNNING` und der systemd-Zustand
|
|
`activating/start` bei der oneshot-Unit belegen keinen Datenfortschritt. Bei einem
|
|
stillen alten Auftrag Prozesszustand und TCP-Zähler mit `ps`/`ss` prüfen;
|
|
steigende Zähler belegen Netzwerkverkehr, aber noch keinen erfolgreichen Upload.
|
|
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.
|
|
|
|
## Paket reproduzieren
|
|
|
|
Aus einem sauberen, eingecheckten Repository:
|
|
|
|
```bash
|
|
python3 tools/build-update-package.py
|
|
```
|
|
|
|
Ausgabe: `dist/app-backup-update-COMMIT.run` und zugehörige SHA-256-Datei.
|
|
Das Paket enthält nur explizit freigegebene Programm-/Dokumentationsdateien und
|
|
Credential-Vorlagen; keine Git-Historie, echten CNF-Dateien oder Backupdaten.
|
|
Die Prüfsumme schützt vor Übertragungsfehlern, ist keine digitale Signatur.
|
|
Das ausführbare Paket ausschließlich über euren vertrauenswürdigen Kanal beziehen.
|
|
|
|
## Verifikation der Lieferung
|
|
|
|
65 Testfälle im vollständigen Durchlauf erfolgreich (603,4 Sekunden), einschließlich Mailberichte, Versandfehler/-Timeout, Header-Schutz und Paketupdate mit erhaltenen Mail-Einstellungen. ShellCheck und Shell-Syntaxprüfung erfolgreich. Der MTA wird durch eine lokale Attrappe ersetzt; die Tests versenden keine echten E-Mails. Die Tests für eine über Umgebungsvariablen abgeschwächte Inhaltsprüfung und den nicht bytegenauen Marker-Vergleich reproduzierten die Fehler vor der Korrektur und bestanden danach.
|
|
|
|
Die Tests enthalten echte MariaDB-Dumps/Imports und lokale rclone-Crypt-Roundtrips;
|
|
systemd/occ und die systemd-run-Übergabe sind simuliert. Das Übergabemodell
|
|
berücksichtigt jetzt das Warten auf den oneshot-Startauftrag: Der Regressionstest
|
|
scheiterte mit dem alten Code und war nach dem Fix erfolgreich. Geprüft sind auch
|
|
abgewiesene Übergaben, eingereihte Worker trotz fehlgeschlagener Antwort und
|
|
persistente Fehlerprotokolle bei belegter Update-Sperre. Die tatsächliche
|
|
SELinux-Durchsetzung wird im Debian-Testcontainer nicht nachgebildet; der erfolgreiche
|
|
Bash-/rsync-Lesetest auf Gemini wurde separat vom Betreiber durchgeführt. Die vollständige
|
|
Server-/OneDrive-Prüfung erfolgt beim Paketlauf. Ein fachlicher Restore
|
|
auf einem separaten Testsystem bleibt erforderlich.
|
|
|
|
Die neuen Tests bilden fremde Startaufträge während rsync, zwischenzeitliche
|
|
Neustarts, bestehende Maskierungen und Fehler bei der Sperrfreigabe ab. Die
|
|
Condition-Auswertung (Sperrverzeichnis vorhanden/entfernt) und Unit-Syntax wurden
|
|
zusätzlich mit echtem `systemd-analyze` geprüft. Der tatsächliche systemd-Manager
|
|
und SELinux auf Gemini wurden anschließend im vom Betreiber ausgeführten
|
|
Paketlauf mit geschützter Kopie und erfolgreichem Abschluss geprüft. Die fachliche
|
|
Wiederherstellung auf einem separaten Testsystem bleibt offen.
|