feat: stille Datenverlust-Pfade geschlossen, gemeinsame Shell-Lib (v0.7.0)
Vor dem Rollout durchgesehen und die verbliebenen Stellen geschlossen, an denen etwas schiefgehen konnte, ohne dass es irgendwo sichtbar wurde. Datenverlust: - veraPDF: das in [verapdf].binary konfigurierte Programm wird im Preflight geprueft. Bisher galt bei falschem Pfad JEDE Datei als "nicht konform" — Ergebnis nach error/, Original geloescht (Default delete). run_verapdf() trennt jetzt ausserdem ein echtes FAIL-Urteil von einer Stoerung (VeraPdfUnavailable: nicht startbar, abgestuerzt, kein PASS/FAIL in der Ausgabe). Bei Stoerung wandern Original UND Ergebnis nach error/, das Original wird nicht entsorgt. - Gleichnamige Dateien wurden in outgoing/, error/ und beim Ordner-Upload mit abweichendem target kommentarlos ueberschrieben. Jetzt Zeitstempel daneben, mit Warnung; ProcessResult.output traegt den echten Pfad. Robustheit: - Kaputtes oder nicht lesbares TOML beim Start: Exit 2 statt Traceback. - RestartPreventExitStatus=2 in der Unit — Exit 2 (Config/Preflight) laeuft nicht mehr endlos neu, die Instanz bleibt sichtbar failed stehen. - Toter watchdog-Observer wird erkannt: Exit 3, systemd setzt den Watch neu auf. Vorher blieb die Unit "active" und verarbeitete nichts mehr. - Relative Pfade in [paths]/archive_dir/target sind ein Config-Fehler statt still unter /opt zu landen. - Fehler beim Archivieren entwertet den Durchlauf nicht mehr: Upload und Mail laufen, Sichtbarkeit ueber log.error + "OK mit Warnung"-Mail. - Nicht-PDFs in incoming/ werden beim Start-Scan gesammelt gemeldet. - Logging explizit nach stdout (die Doku versprach das schon). Struktur: - Neue lib/common.sh, von install.sh und update.sh gesourct. Die doppelte venv_is_healthy() gibt es nur noch einmal, in der gruendlichen Fassung — die schlanke in install.sh haette eine nach einem Distro-Sprung kaputte venv als gesund durchgewunken (nachgewiesen). - install.sh warnt in Containern, wenn systemd-journald nicht laeuft. Doku: Dateisystem-Festlegung (ext4/xfs/zfs, kein CIFS/NFS wegen inotify), Debian 13 in LXC auf Proxmox scheitert an journald (243/CREDENTIALS, AppArmor blockiert sd-mkdcreds) inkl. Abhilfe, echte Speicher-Messwerte, Exit-Code-Tabelle. 254 Tests gruen (vorher 152). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+34
-3
@@ -28,16 +28,24 @@ sudo ./update.sh --no-smoke-test # ohne Rauchtest durchlaufen
|
||||
es den gespeicherten Pfad aus `/opt/pdf-ocr-hotfolder/.repo_path` — **das Repo
|
||||
muss also liegen bleiben**, das Tool kopiert daraus.
|
||||
|
||||
`install.sh` und `update.sh` teilen sich seit 0.7.0 die Datei `lib/common.sh`
|
||||
(Log-Funktionen, Root-Prüfung, Layout-Pfade, apt-Paketliste, venv-Prüfung).
|
||||
`update.sh` sourct bevorzugt die Fassung **neben sich** im Repo und fällt auf
|
||||
die installierte unter `/opt/pdf-ocr-hotfolder/lib/` zurück; fehlt sie
|
||||
überall, bricht es sofort ab statt mitten im Lauf. Die apt-Paketliste schneidet
|
||||
es zusätzlich noch einmal per `sed` aus der Repo-Fassung heraus — beim Update
|
||||
soll die neue Liste gelten, nicht die eventuell ältere installierte Kopie.
|
||||
|
||||
## Was das Skript tut — in dieser Reihenfolge
|
||||
|
||||
| # | Schritt | Anmerkung |
|
||||
|---|---------|-----------|
|
||||
| 1 | **Instanzen erfassen** | aktiv / kaputt / bewusst gestoppt, siehe [unten](#instanz-erfassung) |
|
||||
| 2 | **System-Pakete abgleichen** | Liste wird aus `install.sh` extrahiert, `apt-get install` ist idempotent |
|
||||
| 2 | **System-Pakete abgleichen** | Liste wird aus `lib/common.sh` des Repos extrahiert, `apt-get install` ist idempotent |
|
||||
| 3 | **venv prüfen** | passt sie noch zum System-Python? Läuft **vor** dem Stoppen, damit man es früh sieht |
|
||||
| 4 | **Instanzen stoppen** | nur die, die vorher liefen oder kaputt waren |
|
||||
| 5 | **Backup** | [Inhalt und Ort](#backup) |
|
||||
| 6 | **Code kopieren** | `pdf_ocr_hotfolder/`, `requirements.txt`, `VERSION`, `config.example.toml`, `.repo_path` |
|
||||
| 6 | **Code kopieren** | `pdf_ocr_hotfolder/`, **`lib/`**, `requirements.txt`, `VERSION`, `config.example.toml`, `.repo_path` |
|
||||
| 7 | **Dependencies** | `pip install --upgrade -r requirements.txt` — oder venv-Neubau, falls nötig. Versionssprünge der gepinnten Pakete werden [benannt](#versionssprünge-der-kernabhängigkeiten) |
|
||||
| 8 | **systemd-Units** | Template-Unit aus dem Repo, LXC-Drop-in nachziehen, `daemon-reload` |
|
||||
| 9 | **Berechtigungen** | Code gehört dem primären User (i.d.R. `pdfocr`) |
|
||||
@@ -114,7 +122,7 @@ Vor dem ersten Eingriff auf der Platte schreibt `update.sh` ein Archiv:
|
||||
|
||||
| Enthalten | Nicht enthalten |
|
||||
|-----------|-----------------|
|
||||
| `/opt/pdf-ocr-hotfolder/` (Code) | die **venv** (`venv/`, `venv.old-*`) |
|
||||
| `/opt/pdf-ocr-hotfolder/` (Code **inkl. `lib/`**) | die **venv** (`venv/`, `venv.old-*`) |
|
||||
| `/etc/pdf-ocr-hotfolder/` (alle Instanz-Configs) | die **Datenverzeichnisse** `/var/lib/pdf-ocr-hotfolder/` |
|
||||
| Template-Unit `pdf-ocr-hotfolder@.service` | `__pycache__`, `*.pyc` |
|
||||
| alle Drop-in-Verzeichnisse `…@*.service.d` | |
|
||||
@@ -303,6 +311,15 @@ validiert die `[output]`-Sektion.
|
||||
| **1** | Config nutzbar, aber mit **Warnungen** | Kein Abbruchgrund, der Dienst läuft. Die Warnungen aber **nachziehen** — sie nennen entweder einen Key, dessen Bedeutung sich geändert hat, oder einen Eintrag, der ins Leere läuft (s. [Config-Drift](#config-drift-nach-einem-update)) |
|
||||
| **2** | Config **unbrauchbar** — der Dienst würde nicht starten | Sofort korrigieren. Die Instanz gilt als **nicht** erfolgreich aktualisiert, das Update endet mit Exit 1 |
|
||||
|
||||
`--check-config` selbst kennt nur 0/1/2. Der **Dienst** kennt seit 0.7.0
|
||||
zusätzlich **Exit 3** (Verzeichnis-Watch gestorben, Neustart erwünscht) — und
|
||||
die Unit startet bei **Exit 2** absichtlich **nicht** mehr neu
|
||||
(`RestartPreventExitStatus=2`), die Instanz bleibt sichtbar `failed` stehen.
|
||||
Für das Update heißt das: eine Instanz mit Config-Fehler verschwindet nicht
|
||||
mehr in einem stillen 5-Sekunden-Crash-Loop, sondern fällt in der
|
||||
Zusammenfassung auf. Die vollständige Tabelle:
|
||||
[INSTALLATION.md](INSTALLATION.md#exit-codes).
|
||||
|
||||
Kennt der installierte Code `--check-config` noch nicht (Update von einem Stand
|
||||
vor 0.6.0), erkennt `update.sh` das an der argparse-Meldung, überspringt die
|
||||
Prüfung mit einer Warnung und läuft weiter.
|
||||
@@ -361,6 +378,20 @@ dem Fall mit Exit 2 ab; ab Ghostscript 10.02.1 ist PDF/A unproblematisch.
|
||||
> `requirements.txt` pinnt darum 17.x, und der Preflight prüft beides zusammen.
|
||||
> Hintergrund: [INSTALLATION.md](INSTALLATION.md#ghostscript-bug-auf-debian-12).
|
||||
|
||||
### Relative Pfade — Fehler seit 0.7.0
|
||||
|
||||
Bis 0.6.3 wurde ein relativer Pfad in `[paths]`, `[output].archive_dir` oder
|
||||
`[upload.folder].target` klaglos angenommen und gegen das `WorkingDirectory`
|
||||
der Unit aufgelöst, also unter `/opt/pdf-ocr-hotfolder/`. Seit 0.7.0 ist das
|
||||
ein **Config-Fehler mit Exit 2**: `--check-config` meldet ihn beim Update, und
|
||||
der Dienst startet nicht.
|
||||
|
||||
Das ist der einzige Fall, in dem ein Update von 0.6.x eine bisher „laufende"
|
||||
Instanz stoppen kann. Er ist gewollt — eine solche Instanz schrieb an einer
|
||||
Stelle, an der niemand sie gesucht hat. Abhilfe: den Pfad absolut eintragen
|
||||
und, falls dort Dateien liegen, den Inhalt von `/opt/pdf-ocr-hotfolder/<pfad>`
|
||||
vorher herüberholen.
|
||||
|
||||
### Unbekannte Keys
|
||||
|
||||
Einträge, die zu keiner Sektion und keinem Key gehören, werden beim Laden
|
||||
|
||||
Reference in New Issue
Block a user