fix: Ghostscript-Angebot log nicht mehr, fehlende Voraussetzungen dokumentiert (v0.7.1)

Befunde aus dem ersten echten Erstinstallations-Test auf frischen Debian-12-
und Debian-13-Containern. Der Weg selbst hat getragen (Basis-Install,
Instanz-Anlage, zweite Instanz, Update mit Rauchtest, Rollback) — diese
Stellen haben gelogen oder gefehlt:

- Das Ghostscript-Backports-Angebot auf Debian 12 war ein garantierter
  Leerlauf, der "aktualisiert ✓" meldete: bookworm-backports enthaelt gar
  kein ghostscript (am Paketindex verifiziert). Die Routine sucht jetzt den
  echten Kandidaten, vergleicht vorher/nachher und raeumt eine nur zur Probe
  angelegte Quelle wieder weg.
- Derselbe untaugliche Rat stand in der Preflight-Meldung, der
  pdfa_level-Warnung, config.example.toml und vier Doku-Dateien — ueberall
  ersetzt durch die echten Optionen.
- Mehrzeilige Log-Hinweise waren durch "echo -e" zerrissen und nicht
  kopierbar; log_* nutzt jetzt printf mit %s.
- pip-freeze.txt landete beim Rollback als /pip-freeze.txt im
  Wurzelverzeichnis, liegt jetzt unter opt/pdf-ocr-hotfolder/.
- git und sudo fehlen auf dem Proxmox-Debian-Template; "sudo ./install.sh"
  scheitert dort. Beide Wege dokumentiert, git als Voraussetzung ergaenzt,
  HTTPS-Clone als Normalfall.
- Rollback: systemctl start kann kein Glob. journald-Reparatur: Instanzen
  danach neu starten, sonst bleibt das Journal leer.

254 Tests gruen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 01:36:42 +02:00
parent cd803a3dfe
commit 465ff8873f
15 changed files with 611 additions and 101 deletions
+58 -6
View File
@@ -24,6 +24,13 @@ sudo ./update.sh --rebuild-venv # venv zwingend neu bauen (nach dist-upgrade)
sudo ./update.sh --no-smoke-test # ohne Rauchtest durchlaufen
```
> **`sudo` oder direkt als `root`.** `update.sh` braucht root-Rechte, nicht
> `sudo`. Wer als `root` arbeitet — im Proxmox-Debian-Standard-Template der
> Normalfall, dort ist `sudo` gar nicht installiert —, lässt das `sudo` bei
> jedem Befehl dieser Seite einfach weg: `./update.sh`. Ebenso setzt `git pull`
> ein installiertes **`git`** voraus; siehe
> [INSTALLATION.md](INSTALLATION.md#pakete-die-auf-einem-frischen-system-fehlen-können).
`update.sh` muss aus dem Repo laufen. Findet es sich nicht selbst im Repo, liest
es den gespeicherten Pfad aus `/opt/pdf-ocr-hotfolder/.repo_path` — **das Repo
muss also liegen bleiben**, das Tool kopiert daraus.
@@ -126,10 +133,14 @@ Vor dem ersten Eingriff auf der Platte schreibt `update.sh` ein Archiv:
| `/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` | |
| `pip-freeze.txt` — `pip freeze` der **alten** venv plus Zeitstempel und Versionssprung | |
| `opt/pdf-ocr-hotfolder/pip-freeze.txt` — `pip freeze` der **alten** venv plus Zeitstempel und Versionssprung | |
`pip-freeze.txt` ist die Versicherung für den Fall, dass ein neuer Pin Ärger
macht: man sieht schwarz auf weiß, welche Paketversionen vorher liefen.
macht: man sieht schwarz auf weiß, welche Paketversionen vorher liefen. Sie
liegt im Archiv unter `opt/pdf-ocr-hotfolder/` und landet beim Entpacken nach
`/` folglich als `/opt/pdf-ocr-hotfolder/pip-freeze.txt` — also neben der
Installation statt im Wurzelverzeichnis. Ein Code-Tausch beim nächsten Update
löscht sie nicht (dort fliegen nur `pdf_ocr_hotfolder/` und `lib/`).
**Rechte:** Das Archiv enthält die Instanz-Configs und damit **Klartext-Passwörter**
(SMTP, Nextcloud, SFTP). Es wird deshalb mit `umask 077` erzeugt und danach auf
@@ -153,24 +164,65 @@ Das Backup-Archiv ist wurzelrelativ gepackt und lässt sich direkt zurückspiele
sudo systemctl stop 'pdf-ocr-hotfolder@*'
sudo tar -xzf /var/backups/pdf-ocr-hotfolder/backup-YYYYmmdd-HHMMSS.tar.gz -C /
sudo systemctl daemon-reload
sudo systemctl start 'pdf-ocr-hotfolder@<instanz>'
sudo systemctl start pdf-ocr-hotfolder@kunde-a
sudo systemctl start pdf-ocr-hotfolder@kunde-b # jede Instanz einzeln!
```
Das Skript nennt diesen Befehl mit dem konkreten Archivnamen selbst — sowohl
beim Abbruch als auch bei einer erkannten Regression.
> ⚠️ **`start` kann kein Glob.** `systemctl stop 'pdf-ocr-hotfolder@*'` trifft
> alle laufenden Instanzen, weil systemd dafür die **bereits geladenen** Units
> auflösen kann. Beim Starten gibt es nichts aufzulösen:
> `systemctl start 'pdf-ocr-hotfolder@*'` startet eine Instanz mit dem
> wörtlichen Namen `*` — und scheitert. **Bei mehreren Instanzen muss jede
> einzeln gestartet werden.** Welche es sind:
> `ls /etc/pdf-ocr-hotfolder/*.toml`. Am Stück:
>
> ```bash
> for f in /etc/pdf-ocr-hotfolder/*.toml; do
> n=$(basename "$f" .toml)
> sudo systemctl start "pdf-ocr-hotfolder@$n"
> done
> systemctl status 'pdf-ocr-hotfolder@*' --no-pager
> ```
### Was ein Rollback nachweislich zurückholt
Einmal real durchgespielt (Debian 12 **und** 13, Update auf den neuen Stand,
danach Rollback auf das Backup). Zurück kamen korrekt:
- **der Code** unter `/opt/pdf-ocr-hotfolder/` inklusive `lib/` — die alte
Version lief danach wieder,
- **alle Instanz-Configs** unter `/etc/pdf-ocr-hotfolder/` — **mit den
`640`-Rechten und dem `root:<service-gruppe>`-Eigentum**; die
Klartext-Passwörter bleiben also geschützt, `tar` stellt Modus und Eigentümer
mit her,
- die **Template-Unit** `pdf-ocr-hotfolder@.service` und
- die **Drop-ins** unter `…@*.service.d/` (LXC-Kompat, User-Drop-in).
Nach `daemon-reload` und dem Einzelstart liefen die Instanzen wieder mit dem
alten Stand. Was dabei **nicht** zurückkommt, steht im nächsten Abschnitt.
### Grenzen des Rollbacks
Ein Rollback ist ein **Overlay**, kein exaktes Zurücksetzen:
Ein Rollback ist ein **Overlay**, kein exaktes Zurücksetzen — beides im Test
bestätigt:
- **Die venv ist nicht im Backup.** Wurde sie beim Update neu gebaut oder
hat `pip install --upgrade` Pakete angehoben, holt das Rollback den alten
Stand der Pakete **nicht** zurück. Dafür ist `pip-freeze.txt` aus dem Archiv
da: die dort genannten Versionen lassen sich von Hand wiederherstellen
da — nach dem Entpacken unter `/opt/pdf-ocr-hotfolder/pip-freeze.txt`: die
dort genannten Versionen lassen sich von Hand wiederherstellen
(`venv/bin/pip install -r …`).
Im Test lief nach dem Rollback die **alte** Code-Version in der **neuen**
venv — was hier gutging, weil sich die Pins nicht geändert hatten. Verlassen
darf man sich darauf nicht: nach einem Update mit Versionssprung gehört die
venv nach dem Rollback von Hand auf den alten Paketstand gebracht.
- **Dateien, die es vorher nicht gab, bleiben liegen.** `tar -x` legt nur an und
überschreibt; es löscht nichts. Eine mit dem neuen Stand hinzugekommene Datei
im Code-Verzeichnis überlebt das Rollback. Sauberer ist deshalb
im Code-Verzeichnis überlebt das Rollback — im Test nachgestellt und
bestätigt. Sauberer ist deshalb
`rm -rf /opt/pdf-ocr-hotfolder/pdf_ocr_hotfolder` **vor** dem Entpacken.
- **Die Datenverzeichnisse sind nicht im Backup** — gewollt. Ein Rollback
verändert keine PDFs, weder in `incoming/` noch in `error/`.