Thomas Stallinger 28e6c067a1 feat: add present/absent branching for Auftragskatalog roles
Adds a tuxflotte_state variable, threaded from a new
tuxflotte_auftrag_states dict in site.yml (role name -> present/absent,
populated by the agent from the checkin response's "auftraege" list,
see ADR-0010) down into each role via include_role vars. Roles not
present in that dict default to "present" via .get(), so today's
purely workspace-composed, additive-only behavior is unchanged.

Retrofits all three existing placeholder roles with the present/absent
branch as the reference implementation of the convention, and
documents it in the README for future catalog-eligible roles. This is
what makes deselecting an Auftrag actually revert something instead of
just stopping future re-application.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 09:34:05 +02:00

ansible-content

Ansible-Rollen, die der Tuxflotte Provisioning Agent per ansible-pull gegen installierte Geräte anwendet.

Rollennamen entsprechen 1:1 der Spalte ansible_role in der blueprints-Tabelle des Provisioning-Servers (siehe provisioning-server/migrations/0005_seed_workspace_backend_blueprint_data.sql).

site.yml bindet jede Rolle unter einem zu ihrem Namen passenden Tag ein. Der Agent ruft sie über:

ansible-pull -U <repo-url> --tags <rolle1>,<rolle2>,... -i localhost, site.yml

Aktueller Stand

Alle Rollen sind Platzhalter — sie hinterlegen nur eine Marker-Datei unter /run/tuxflotte/agent/applied/<rolle>.marker, um die End-to-End-Pipeline (Server → Agent → ansible-pull → Rolle) nachzuweisen. Echte Rolleninhalte folgen später.

present/absent (Auftragskatalog, ADR-0010)

Merkmale, die für die geräteweise Ad-hoc-Zuweisung über den Auftragskatalog freigegeben sind (merkmale.im_auftragskatalog = true), können nicht nur zugewiesen, sondern auch wieder abgewählt werden — und das muss real etwas zurückbauen, nicht nur zukünftige Anwendung verhindern.

Dafür reicht der Agent bei jedem ansible-pull-Lauf eine Variable tuxflotte_auftrag_states durch (Rollenname → "present"/"absent", aus der Check-in-Antwort auftraege), die site.yml pro Rolle als tuxflotte_state an die jeweilige Rolle weiterreicht. Rollen, die dort nicht auftauchen (zum Beispiel weil sie nur workspace-komponiert sind, nicht katalogfähig), laufen unverändert additiv über --tags, ohne absent-Zustand — siehe tuxflotte_auftrag_states.get(<rolle>, 'present') in site.yml.

Jede Rolle, die katalogfähig werden soll, muss deshalb ihre Tasks auf tuxflotte_state verzweigen:

- name: <Merkmal anwenden>
  ...
  when: tuxflotte_state == "present"

- name: <Merkmal zurückbauen>
  ...
  when: tuxflotte_state == "absent"

tuxflotte_state hat in roles/<name>/defaults/main.yml den Default present, damit die Rolle auch bei direkter Verwendung ohne die site.yml-Verdrahtung nicht auf eine undefinierte Variable trifft.

Rollen, die nie katalogfähig werden (rein workspace-komponierte Merkmale), brauchen keinen absent-Zweig — das ist bewusst kein Zwang für alle Rollen, nur für die, die tatsächlich im Auftragskatalog landen.

Neue Rolle hinzufügen

  1. roles/<name>/tasks/main.yml anlegen
  2. roles/<name>/defaults/main.yml mit tuxflotte_state: present anlegen
  3. Eintrag in site.yml mit tags: <name> und vars: tuxflotte_state: "{{ tuxflotte_auftrag_states.get('<name>', 'present') }}" ergänzen
  4. Entsprechenden ansible_role-Wert in der blueprints-Tabelle referenzieren
  5. Nur falls die Rolle katalogfähig werden soll (im_auftragskatalog = true): Tasks wie oben auf tuxflotte_state verzweigen, sonst reicht der additive Pfad ohne when
Description
No description provided
Readme 53 KiB