Files
duffyduckandClaude Opus 5 59e7224297 Handbuch auf MkDocs-Basis, mit Bildschirmfotos aus dem Programm
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>
2026-08-09 12:39:30 +02:00

5.0 KiB
Raw Permalink Blame History

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