26 Kapitel in vier Teilen, in der Reihenfolge, in der man sie braucht: erst sichern, dann Dateien holen, dann ganze Maschinen wiederherstellen, dahinter der Nachschlagteil. Gebaut wird mit MkDocs + Material. Bewusst ohne Netzabhaengigkeiten: keine Schriften vom CDN (font: false), Volltextsuche mit deutschem Stemming liegt neben den Seiten. Im Notfall steht vielleicht das halbe Netz - dann nuetzt eine Doku im Internet nichts. handbuch/bauen.sh baut handbuch/site/ handbuch/bauen.sh ansehen Vorschau auf 127.0.0.1:8000 install.sh nimmt das gebaute Handbuch mit nach /usr/share/doc/pvesnap/handbuch/ - falls es vorliegt. Auf dem Host selbst wird nichts gebaut, mkdocs gehoert nicht auf einen Hypervisor. Die 28 Bildschirmfotos sind nicht abfotografiert, sondern erzeugt: Der echte Programmcode laeuft in einem Pseudo-Terminal gegen einen erfundenen Proxmox-Host (Attrappen fuer pvesh, perl und rbd), pyte baut den Bildschirm nach, heraus faellt ein SVG. Damit stimmen sie garantiert mit dem Programm ueberein, sind reproduzierbar und enthalten keine echten Daten. Die Werkstatt dafuer liegt unter handbuch/werkstatt/ samt LIESMICH.md. Nebenbei: die Schlussmeldung von install.sh warb noch mit --exchange, das mit dem eingebauten Austauschlaufwerk weggefallen ist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.0 KiB
Die Bildschirmfoto-Werkstatt
Die Bilder im Handbuch sind keine abfotografierten Terminals, sondern werden erzeugt — aus dem echten Programmcode, gegen einen erfundenen Proxmox-Host.
./aufnehmen.sh # alle Bilder neu
./aufnehmen.sh explorer # nur die, deren Name "explorer" enthält
Ergebnis: handbuch/docs/bilder/*.svg
Das hat drei Gründe:
- Sie stimmen. Es läuft wirklich
pvesnap/recovery_ui.py, nicht eine Nachbildung. Ändert sich die Tastenleiste, ändert sich das Bild. - Sie sind reproduzierbar. Derselbe Aufruf ergibt dasselbe Bild — gleiche Daten, gleiche Uhrzeiten, gleiche Snapshot-Namen.
- Kein echter Host wird angefasst. Weder Daten noch Namen aus einer echten Umgebung landen im Handbuch.
Wie es funktioniert
scenes.py Liste aller Aufnahmen: Name, Szene, Tastenfolge, Titel
└─ probe.py startet eine Szene in einem Pseudo-Terminal
└─ stage.sh hängt die Kulisse an die richtigen Pfade (Namensraum)
└─ run.py biegt die Pfade im Programmcode um und ruft die Oberfläche auf
└─ pvesnap/… der echte Programmcode
└─ shot.py baut den Bildschirm nach und schreibt ihn als SVG
demo.py — die Kulisse
Baut unter werkstatt/demo/ ein erfundenes Rechenzentrum auf: zwei Nodes, zehn
Gäste, ein paar hundert Snapshots, zwei laufende Wiederherstellungen, drei
Austauschlaufwerke und einen Dateibaum für den Explorer.
Ein fester Zeitpunkt (NOW) sorgt dafür, dass zwei Aufnahmen derselben
Liste gleich aussehen — sonst würde die Beschreibung im Handbuch nicht mehr
zum Bild passen.
bin/pvesh, bin/perl, bin/rbd — die Attrappen
pvesnap spricht mit Proxmox über genau drei Programme. Alle drei liegen hier als
kleine Python-Skripte, die aus demo/state.json antworten. Sie stehen im PATH
vor den echten.
Nichts davon verändert etwas — die schreibenden Aufrufe geben brav eine UPID zurück und tun sonst nichts.
run.py — die Pfade umbiegen
Setzt vor dem Start die Konstanten um, die sonst auf einen echten Host zeigen:
recovery.REGISTRY = demo/lib/recovery.json
transfer.INDEX = demo/lib/transfer/index.json
transfer.CONF_ROOT = demo/pve/nodes
Der Programmcode selbst wird nicht angefasst. Die Bilder zeigen also wirklich das, was auf dem Host auch zu sehen ist.
stage.sh — die Pfade, die im Bild stehen
Der Explorer zeigt Pfade an. Im Handbuch sollen das die Pfade eines echten
Hosts sein (/run/pvesnap/mnt/…, /root, /etc/pvesnap.conf) und nicht die
Arbeitsverzeichnisse dieser Werkstatt.
Deshalb läuft jede Aufnahme in einem eigenen Mount-Namensraum
(unshare -r -m): Dort dürfen wir uns die Pfade hinbiegen, ohne am System
etwas zu verändern. /etc bekommt eine Overlay-Schicht, damit die
Konfiguration dort liegt, wo sie hingehört.
shot.py — der Bildschirmnachbau
Startet das Programm in einem Pseudo-Terminal fester Größe (118 × 32), spielt Tastendrücke ein, lässt pyte den Bildschirm nachbilden und schreibt das Ergebnis als SVG.
Zwei Feinheiten, die Zeit gekostet haben:
textLength auf jedem Textstück. Das SVG bettet keine Schrift ein — es
soll ja klein bleiben und offline funktionieren. Damit das Zeichenraster
trotzdem in jedem Browser sitzt, wird jede Zeichenkette fest vermessen.
NCURSES_NO_UTF8_ACS=1. ncurses zeichnet Rahmen sonst über den
Ersatzzeichensatz (ESC ( 0). pyte ignoriert das im UTF-8-Betrieb, und aus den
Linien würden Buchstaben (lqqqk statt ┌───┐). Mit der Variablen liefert
ncurses echte Unicode-Rahmenzeichen.
Eine Szene nachsehen
Zum Ausprobieren, ohne ein Bild zu schreiben — gibt den Bildschirm als Text aus:
../.venv/bin/python probe.py recovery
../.venv/bin/python probe.py recovery enter p
COLS=140 ROWS=40 ../.venv/bin/python probe.py explorer ab ab enter
Tastennamen: ab auf links rechts enter tab esc space f2 f3 f5 f7 f9,
alles andere wird als Zeichen geschickt.
Verfügbare Szenen stehen in run.py unter SZENEN.
Eine Aufnahme hinzufügen
In scenes.py eine Zeile ergänzen:
("recovery-neuerkram", "recovery", ["enter", "p"],
"root@pve1 — pvesnap-recovery"),
Fünftes Feld optional: Wartezeit in Sekunden, für Bildschirme, hinter denen noch etwas arbeitet (sonst hält der Nachbau den letzten Stand fest, während im Hintergrund noch ein Proxmox-Task läuft).
Braucht es dafür eine neue Szene, kommt sie in run.py dazu.
Wenn etwas nicht klappt
| Symptom | Ursache |
|---|---|
| Bild ist leer oder zeigt einen Traceback | scenes.py meldet das selbst — mit probe.py nachsehen |
Rahmen bestehen aus lqqqk |
NCURSES_NO_UTF8_ACS=1 fehlt in probe.umgebung() |
| Pfade zeigen ins Scratchpad | unshare -r ging nicht; aufnehmen.sh prüft das vorher |
| Pfeiltasten bewegen nichts | Es muss \x1bOB sein, nicht \x1b[B — curses schaltet auf den Anwendungsmodus |
| Ein Bildschirm hängt bei „bitte warten" | Eine Antwort der Attrappe fehlt; mit log_level=DEBUG sieht man den Aufruf |