🌲 Zero Deploy — Handbuch v0

Der reproduzierbare Weg von der frischen SD-Karte bis der Krümel sich seine
Mission aussucht. Drei Phasen, sauber getrennt nach Hand: #mensch (Identität),
#maschine (Nutzlast), #menschmaschine (Nutzung).
Ergänzt das operative Runbook scripts/RC1_ONBOARD.md —
dies hier ist die kanonische Kette, jenes der Peer-Schritt am Hub.

Status: v0. Push-Modell, agentless. Der Zero hält nie einen Git-Cred.
Seine lokalen Bash-Edits reiten über den Mac zurück ins Gitea (er pusht nie selbst).


Die Bootstrap-Naht: der Key wird auf der SD geboren, nicht nach dem Boot

Das war das fehlende Puzzleteil. Nach dem ersten Boot gibt es keinen SSH-Key und
keinen Clone — wenn man erst dann anfängt. Die Auflösung: der Key entsteht eine
Stufe früher, im Pi Imager selbst.

  • Pi Imager: https://www.raspberrypi.com/software/
  • Beim Schreiben kommt der erste Prompt → „Einstellungen bearbeiten"
    (OS-Customisation). Genau hier sitzt die einzige #mensch-Handbewegung.

Und: ein Git-Clone auf dem Zero ist zum Provisionieren gar nicht nötig. Ansible
ist push/agentless — es läuft vom Control-Node (M4) aus und trägt alles rüber.
Der Clone existiert nur als lesbare Bash-Arbeitskopie für den Krümel (Phase 2).


Phase 1 — #mensch · Identität (Admin/Lehrer)

1.1 SD vorbereiten & flashen (Pi Imager, erster Prompt)

Im OS-Customisation-Dialog vor dem Schreiben setzen:

Feld Wert Warum
Hostname crumbzero02 = Mesh-Name, = NetBox-Handle
SSH aktivieren nur Public-Key Control-Node-Pubkey (M4) einfügen — sonst kommt kein Ansible an
Benutzer sysop einheitlicher Deploy-User
WLAN SSID + PSK „first wifi" — die erste Erreichbarkeit
Locale / Keyboard wie Standort Kleinkram, spart späteres Nachfassen

Der Public-Key liegt danach im /boot-firstrun-Hook und ist beim ersten Boot
schon in ~sysop/.ssh/authorized_keys. Kein Passwort, kein manuelles Kopieren.

1.2 Booten & erreichen

Zero booten. Vom Control-Node erreichen (WLAN/LAN), MAC steht in den Facts:

ssh sysop@crumbzero02.local        # oder per IP aus dem Router/ARP

1.3 In die Bestandsaufnahme (crumbconnect + NetBox)

crumbconnect gibt der Maschine ihre VPN-Identität (Runbook §① —
scripts/crumbconnect.sh auf den Zero, HUB_PUBKEY/MY_IP=10.42.0.22/32),
Pubkey kommt raus → am Hub registrieren (vpn-hub.yml, Runbook §②).

NetBox-Identität inkl. MAC läuft schon fertig über netbox-raspis.yml
(Site/Role/Tag/Device/Interface/MAC/primary_mac/IP — per SSH-Facts):

ansible-playbook netbox-raspis.yml --limit crumbzero02 --check --diff   # trocken
ansible-playbook netbox-raspis.yml --limit crumbzero02                  # dann echt

Damit ist die „MAC willkommen heißen" erledigt — die NIC kennt die Range als
diesen einen. witness.class = device-registered greift ab hier
(siehe docs/CRUMBFOREST_OUTBOX_v0.md §4a).
Ehrliche Grenze: MAC ist software-setzbar → Geräte-Identität, keine
Hardware-Attestierung.

Voraussetzung: host_vars/crumbzero02.yml mit nb_site/nb_role, und die
Inventar-Zeile unter [ozm_linux] (bzw. als Tunnel-Peer).


Phase 2 — #maschine · Nutzlast (Deploy)

MAC erkannt → jetzt kommt das Ziel. Zwei Schichten, bewusst getrennt:

2.1 missions-core — das austauschbare Rust-Target

Das aarch64-Binary aus Release OZM_Nullfeld_v1 v0.1.0 (Runbook §③):

scp crumb-missions sysop@10.42.0.22:/home/sysop/crumb-missions
scp missions-core/deploy/crumb-missions.service sysop@10.42.0.22:/home/sysop/
ssh sysop@10.42.0.22 '
  sudo cp ~/crumb-missions.service /etc/systemd/system/
  sudo systemctl daemon-reload && sudo systemctl enable --now crumb-missions
  curl -s localhost:8791/health
'

Austauschbar heißt austauschbar: das Binary darf jederzeit gegen eine neue
Version getauscht werden. Es ist das Ziel, nicht die Wahrheit.

2.2 Die lesbare Bash — die editierbare Wahrheit

Die Bash-Variante (missions-bash/) ist die lesbare Schicht, die der Krümel
anfassen kann. Als Arbeitskopie auf dem Zero:

  • Lokale Änderungen des Krümels an der Zero-Bash sind echt und dürfen der
    nächste Commit / Branch werden.
  • Der Zero pusht nicht selbst (kein Git-Cred). Der Rückweg: der Mac holt
    den Diff und spiegelt ihn ins Gitea (SOT-Drift-Regel — Gerät vor Gitea prüfen,
    Geräte ohne Push-Cred driften still).

Rust = austauschbares Ziel. Bash = lesbare, editierbare Wahrheit. Beide
nebeneinander, keine Hierarchie.


Phase 3 — #menschmaschine · Nutzung (der Krümel)

Jetzt kann der Krümel loslegen und sich seine Missionen aussuchen — der
Missions-Selector / die Crew (siehe KEKSHANDBUCH_ZERO_v0.0.md).
Ergebnisse kommen am LED-Streifen an, nicht am Screen
(docs/CRUMBFOREST_OUTBOX_v0.md): Inbox hoch
(gehasht, antwortlos), Outbox runter (morgen grün), crumbtype in Echtzeit.


Die Kette auf einen Blick

        #mensch  ·  Identität              #maschine · Nutzlast        #menschmaschine
   ┌──────────────────────────────┐   ┌──────────────────────────┐   ┌──────────────┐
 1 │ SD flashen (Pi Imager):      │   │ MAC erkannt → Deploy:    │   │ Krümel wählt │
   │  Hostname·SSH-KEY·User·WLAN  │   │  · missions-core (Rust,  │   │  Missionen   │
 2 │ Boot → per SSH erreichbar    │   │    austauschbar)         │   │  · LED-Feed  │
 3 │ crumbconnect → Pubkey → Hub  │   │  · lesbare Bash          │   │    (kein     │
 4 │ netbox-raspis.yml (+MAC) ✔   │   │    (editierbar → Commit) │   │    Screen)   │
   └──────────────────────────────┘   └──────────────────────────┘   └──────────────┘
     Key auf der SD geboren.            Zero hält keinen Git-Cred.      Machen statt
     Ansible push, kein Clone nötig.    Edits reiten via Mac zurück.    Lernen.

Was v0 NICHT festlegt

  • Dünner Orchestrator zero-deploy.yml (importiert netbox-raspis + vpn-hub +
    Deploy in einem Lauf) — erst wenn die Handschritte sitzen.
  • Bash-Rückspiegelung als Automatik (bleibt v0 bewusst Hand-am-Mac).
  • hw-attested (Secure Element/TPM) — nie setzen, bis real gebaut.