ADR-0010 decides that an Auftrag is technically a Merkmal, not a new parallel entity: it reuses the existing Merkmal/Blueprint/ansible-role mechanism from ADR-0002, but adds a device-level, independently toggleable assignment path (device_merkmale) alongside the existing workspace-level one. Deselecting an Auftrag needs to actually revert it, so checkin will need to declare a full present/absent state per catalog entry rather than just an additive list; that role-level and API-level work is deferred, this only settles the data model. Also adds a single generic, append-only event log (device_merkmal_events) for both selection changes and agent-reported execution results, instead of several purpose-specific tables, so future event types don't require schema changes. Extends 09-data-model-v1.md and the glossary accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
5.2 KiB
Markdown
42 lines
5.2 KiB
Markdown
# ADR-0010: Auftragskatalog als geräteweise Zuweisung bestehender Merkmale
|
|
|
|
**Status:** Beschlossen
|
|
**Datum:** 03.08.2026
|
|
|
|
## Kontext
|
|
|
|
Nach der Kernschleife des Provisioning Agent (Check-in, Ansible-Pull, siehe `13-live-provisioning-boot.md` und `06-backend-api.md`) sollte als nächster Ausbauschritt ein „Auftragskatalog" entstehen: eine Sammlung einzeln zuweisbarer Aufgaben, die ein Gerät auch nach der Erstinstallation zusätzlich zu seiner Bereitstellungsvorlage bekommen kann, gruppiert in Kategorien.
|
|
|
|
Zwei Anforderungen an diesen Katalog waren zu Beginn der Diskussion offen:
|
|
|
|
1. Ein Auftrag muss nach der Zuweisung auch wieder **abwählbar** sein, und das Abwählen muss real etwas zurückbauen, nicht nur zukünftige Anwendung verhindern.
|
|
2. Pro Gerät muss **transparent nachvollziehbar** sein, was wann wie durchgeführt wurde.
|
|
|
|
Die naheliegende erste Frage war, ob dafür ein neues, eigenständiges „Auftrag"-Modell nötig ist, oder ob sich das bestehende Merkmal/Blueprint-Modell (ADR-0002, `12-feature-blueprint-model.md`) wiederverwenden lässt. Ein Auftrag im hier gemeinten Sinn ist fachlich nicht von einem Merkmal zu unterscheiden: eine einzelne, distributionsunabhängig benannte Eigenschaft, die pro Backend als Ansible-Rolle umgesetzt und über den bestehenden Ansible-Pull-Mechanismus angewendet wird. Der einzige Unterschied ist der Zuweisungsweg: ein Merkmal wird bisher ausschließlich über die Workspace-Zugehörigkeit einer Bereitstellungsvorlage zugewiesen (zum Zeitpunkt der Installation, für die Lebensdauer des Geräts fix). Ein Auftrag soll zusätzlich direkt einem einzelnen, bereits laufenden Gerät zugewiesen und wieder entzogen werden können.
|
|
|
|
## Entscheidung
|
|
|
|
Ein Auftrag ist technisch ein Merkmal. Es wird kein separates Auftrag/Auftrag-Blueprint-Modell parallel zu Merkmal/Blueprint eingeführt.
|
|
|
|
Merkmale, die für die geräteweise Ad-hoc-Zuweisung freigegeben sind, werden über ein neues Attribut `im_auftragskatalog` markiert und optional einer `Kategorie` zugeordnet (neues, eigenständiges Kernobjekt, siehe `09-data-model-v1.md`).
|
|
|
|
Die Ad-hoc-Zuweisung eines Merkmals zu einem einzelnen Gerät ist eine neue, von der Workspace-Zugehörigkeit (`workspace_merkmale`) unabhängige Beziehung (`device_merkmale`), mit einem Aktiv-Flag statt einer reinen Zeile-existiert-oder-nicht-Semantik. Das Deselektieren eines Auftrags setzt dieses Flag auf inaktiv, statt die Zeile zu löschen.
|
|
|
|
Für jedes Gerät wird beim Check-in der vollständige Soll-Zustand aller katalogfähigen Merkmale (nicht nur die neu hinzugekommenen) an den Agenten übermittelt, je Merkmal mit explizitem Zustand `present` oder `absent`. Das ist rein aus dem aktuellen Auswahlstand ableitbar und erfordert keine serverseitige Historie. Damit ein Deselektieren real etwas zurückbaut, muss die zugehörige Ansible-Rolle einen `absent`-Zweig besitzen; das ist eine Erweiterung der Rollenkonvention aus `12-feature-blueprint-model.md`, keine Änderung an diesem Dokument selbst.
|
|
|
|
Für die Nachvollziehbarkeit pro Gerät wird ein einziges, generisches, ausschließlich anhängendes Ereignisprotokoll (`device_merkmal_events`) eingeführt, statt mehrerer spezialisierter Log-Tabellen. Ein `event_type`-Feld unterscheidet sowohl Auswahländerungen (`selected`, `deselected`) als auch vom Agenten gemeldete Ausführungsergebnisse (`applied`, `apply_failed`, `removed`, `remove_failed`). Damit der Agent Ausführungsergebnisse überhaupt melden kann, braucht die Check-in-API einen neuen, additiven Report-Kanal; dessen genaue Form wird nicht in diesem ADR, sondern bei der Umsetzung in `08-provisioning-api.md` spezifiziert.
|
|
|
|
Workspace-komponierte Merkmale (nicht im Auftragskatalog) bleiben von dieser Änderung unberührt: sie werden weiterhin ausschließlich additiv über `--tags` angewendet, ohne `absent`-Zustand. Die Frage, ob sich eine Workspace-Zusammensetzung nachträglich für ein bereits provisioniertes Gerät ändern und zurückbauen lassen soll, ist ein separates, hier bewusst nicht adressiertes Problem.
|
|
|
|
## Konsequenzen
|
|
|
|
Neue Merkmale, die in den Auftragskatalog aufgenommen werden sollen, brauchen zusätzlich zum bestehenden Blueprint pro Backend eine `absent`-Umsetzung in der jeweiligen Ansible-Rolle. Merkmale, die ausschließlich über Workspaces zugewiesen werden, sind davon nicht betroffen.
|
|
|
|
Der Check-in-Response wird um einen expliziten `state`-Wert je Katalogeintrag erweitert; das ist rückwärtskompatibel additiv, kein Bruch der bestehenden, bereits gegen die QEMU-Testumgebung verifizierten Check-in-Antwort.
|
|
|
|
Ein neuer Report-Endpoint wird nötig, damit Ausführungsergebnisse serverseitig sichtbar werden. Bis dieser existiert, bleibt die einzige Ausführungsevidenz lokal auf dem Gerät (`/run/tuxflotte/agent/applied/`), wie bereits heute.
|
|
|
|
Das Datenmodell bleibt für künftige Auftragsarten erweiterbar, ohne neue Tabellen: neue Ereignisarten sind neue `event_type`-Werte, keine Schema-Änderung. Sollten künftig Aufträge nötig werden, die sich nicht als idempotenter Zielzustand beschreiben lassen (echte einmalige Aktionen ohne Present/Absent-Semantik), ist das ein eigenständiges, hier nicht getroffenes Entwurfsproblem.
|
|
|
|
Details zum Datenmodell: `09-data-model-v1.md`. Details zum Merkmal/Blueprint-Grundmodell: `12-feature-blueprint-model.md`, ADR-0002.
|