6.5 KiB
6.5 KiB
0022 – Ausrollen: Betriebsmodi, Push, Änderungsübersicht, Diff, Rollback, Live-Status (M4)
- Status: Akzeptiert
- Datum: 2026-10-13
Kontext
M3 rollt jede neue Revision sofort auf alle Agents aus. M4 verlangt laut Brief Betriebsmodi pro Agent, „Jetzt ausrollen“ aus dem UI, Entwürfe, eine Diff-Ansicht, den Deployment-Status live und Rollback über das UI. Grundlage sind ADR 0007, 0009 und 0021.
Entscheidung
Betriebsmodi und Soll-Revision
auto_pull(Standard): Soll-Revision ist immer die neueste Revision; neue Revisionen werden sofort gepusht (wie M3).manual: Soll-Revision ist die zuletzt ausdrücklich für diesen Agent ausgerollte Revision (agents.target_revision, anfangs 0). Ohne Push ändert sich nichts.- Umschalten über
PATCH /agents/{id}(mode, Rechtsettings.admin). Der Server teilt dem verbundenen Agent den neuen Modus über ein erneutesWelcomemit (Stream wird dazu neu aufgebaut: der Hub trennt die Verbindung, der Agent verbindet sich sofort neu).
Push („Jetzt ausrollen“)
POST /revisions/{n}/deploy(Rechtdeploy) mit optionaler Agent-Liste (leer = alle nicht gesperrten Agents). Für jeden Agent legt der Server ein Deployment im Zustandpendingmit eigener ID an, setzt beimanual-Agentstarget_revision = nund sendetApplyRevisionCommand(n, deployment_id)über den Stream, falls verbunden.- Ältere Revisionen als die neueste dürfen nicht auf
auto_pull-Agents gepusht werden (sie würden beim nächsten Abruf wieder auf die neueste wechseln), und keine Revision darf auf einen Agent gepusht werden, der bereits eine neuere aktiv hat (der Replay-Schutz des Agents nach ADR 0009 würde sie ablehnen): in beiden Fällen Fehlerrollback_required; dafür gibt es den Rollback. Die gerade aktive Revision erneut zu pushen ist erlaubt (erneutes Anwenden). - Der Agent merkt sich die IDs der zuletzt bearbeiteten Push-Deployments und wendet dieselbe ID nie zweimal an; ein erneut angekündigter, schon bearbeiteter Push führt nur zum erneuten Senden des Berichts. Der Server beantwortet doppelte Berichte erfolgreich, ohne etwas zu ändern, und kündigt nur Deployments im Zustand
pendingan. - Nicht verbundene Agents erhalten offene Push-Aufträge beim nächsten Verbindungsaufbau (der Server sendet die offenen
pending-Deployments erneut) bzw. beim Polling:GetDesiredStateResponse.deployment_idist gesetzt, solange ein Push offen ist; der Agent behandelt die Soll-Revision dann als Push, auch im Modusmanual. ReportDeploymentmit dieser ID schließt das Deployment ab (Ergebnis wie bisher). Berichte ohne ID (Pulls) werden wie in M3 als neue Zeile gespeichert.
Änderungsübersicht („Entwürfe“)
- IPAM-Änderungen wirken sofort in der Datenbank; ausgerollt wird erst mit einer Revision. Eine eigene
pending_change-Tabelle ist deshalb unnötig: Die offenen Änderungen ergeben sich aus dem Audit-Log seit der neuesten Revision, der Unterschied in der Konfiguration aus dem Vergleich „jetzt erzeugt“ gegen „neueste Revision“ (erzeugt mit deren Nummer, damit die SOA-Seriennummer keinen Unterschied vortäuscht). GET /config/pendingliefert beides; die Oberfläche zeigt „X Änderungen warten auf Ausrollen“ in der Kopfzeile.
Diff
GET /revisions/{n}/diff?against=m(Standard m = n−1) liefert pro Datei Status (added,removed,modified) und einen Unified-Diff (Paketserver/internal/textdiff, Myers-Algorithmus, 3 Kontextzeilen). Unveränderte Dateien werden ausgelassen.
Rollback
POST /revisions/{n}/rollbackerzeugt eine neue Revision mit dem Inhalt von n (ADR 0009). Damit die SOA-Seriennummer trotzdem steigt, wird nicht der alte Text kopiert, sondern die gespeicherte Generator-Eingabe von n (config_revisions.source, JSON, ab Migration 00004) mit der neuen Nummer erneut gerendert. Revisionen ohne gespeicherte Eingabe (vor M4) können nicht zurückgerollt werden (rollback_unavailable).- Danach gilt die neue Revision wie jede andere:
auto_pull-Agents erhalten sie sofort,manual-Agents nach einem Push.
Live-Status
GET /eventsliefert einen Server-Sent-Events-Strom für angemeldete Benutzer (Rechtipam.read). Ereignisse enthalten nur Kennungen, keine Daten:agent(id),deployment(id,agent_id,revision),revision(number),pending; seit M5 außerdemaddresses(network_ids) für Adressen, die die Lease-Erfassung angelegt oder geändert hat (ADR 0023). Die Oberfläche lädt daraufhin die betroffenen Abfragen neu und fällt bei Verbindungsabbruch auf Polling zurück. Alle 25 s ein Kommentar als Keepalive.- SSE statt WebSocket: nur Server→Browser nötig, funktioniert mit Sitzungscookie, Proxys und
EventSourceohne Zusatzbibliothek; der Endpunkt nutzt die bestehende Sitzungsprüfung. - Quelle ist ein prozessinterner Ereignisbus (
server/internal/events), den Dienst und Agent-API bei Änderungen benachrichtigen. Mehrere Server-Instanzen sind nicht vorgesehen (ADR 0006).
Präzisierungen bei der Umsetzung
- Beim Wechsel nach
manualwirdtarget_revisionauf die neueste Revision gesetzt: Der Agent bleibt auf seinem Stand, statt eine Soll-Revision 0 anzuzeigen. - Offene Pushes werden auch dann
superseded, wenn eine neue Revision oder ein Rollback sie fürauto_pull-Agents überholt, beim Wechsel nachauto_pull(für ältere Revisionen) und wenn beim Verbinden oder Abrufen eine andere Revision Soll ist. Ein später doch eintreffender Bericht überschreibtsupersededmit dem echten Ergebnis. - „Änderungen seit der neuesten Revision“ werden über die Audit-ID des
revision.create/revision.rollback-Eintrags abgegrenzt, nicht über Zeitstempel (Server- und Datenbankuhr können abweichen). Die Einträge enthalten keine IP-Adressen, weil auch Leser sie abrufen. - Die Revisionsnummer steht auch im Kopfkommentar der BIND-Dateien; ein Rollback-Diff zeigt daher neben der Seriennummer eine Kommentarzeile je Datei.
- Der Ereignisstrom beginnt mit
retry: 5000, sendet alle 25 s: keepaliveund endet mit der Sitzung (abgemeldet, abgelaufen, Benutzer gesperrt; geprüft je Keepalive-Intervall, ohne die Sitzung zu verlängern).
Konsequenzen
- Revisionen bleiben unveränderlich, Rollbacks sind nachvollziehbar und die Seriennummer steigt immer.
- Die Oberfläche braucht kein Polling mehr für Agents und Deployments; Polling bleibt als Rückfall.
- Ein offener Push für einen dauerhaft abgeschalteten Agent bleibt
pending, bis der Agent sich meldet, gelöscht wird oder ein neuer Push ihn ersetzt (ältere offene Deployments desselben Agents werden dabei alssupersededabgeschlossen).