Files
ansible-content-stabil/roles/webapp-shortcuts/tasks/main.yml
T
adminandClaude Sonnet 5 e4edcf1011 Webapp-Mechanismus (Phase 2): neue Rolle webapp-shortcuts
Kundeneigene URLs (workspace_webapps, siehe admin/provisioning-server)
werden als .desktop-Menueintrag (/usr/share/applications) UND
best-effort als Desktop-Icon ausgeliefert - kein present/absent pro
Eintrag wie sonst im Katalog, sondern ein echter ABGLEICH: die Rolle
bekommt bei jedem Lauf die komplette aktuelle Liste und sorgt dafuer,
dass GENAU diese Eintraege existieren (Datei-Identifikation ueber die
stabile DB-UUID, keine Namens-Slugifizierung noetig). Laeuft deshalb
IMMER (site.yml-Play-Var tuxflotte_webapps, agent.py haengt sie immer
in --tags ein, siehe admin/provisioning-agent), nicht nur bei
Aenderungen.

Desktop-Icon-Ablage bewusst pragmatisch: /etc/skel/Desktop (kuenftige
Nutzer) + bestehende /home/*/Desktop-Ordner, falls schon vorhanden -
kein erzwungenes Anlegen. Haengt an der noch offenen ADR-0026
(kein final festgelegter primaerer interaktiver Nutzer-Account) - deckt
ab, was heute real existiert (z.B. den 'gast'-Account aus
guest-session), ohne auf die endgueltige Klaerung zu warten.

ECHT END-ZU-ENDE GETESTET (nicht nur Syntax-Check): echter
ansible-playbook-Lauf gegen localhost mit Mock-Daten - Anlegen
(mit+ohne Favicon), Aktualisieren, vollstaendiges Entfernen bei leerer
Liste, Idempotenz. Favicon-Download-Pfad mit echter URL verifiziert.
ansible-core dafuer neu installiert (vorher nicht vorhanden).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLk93dhDMrkPXefVdknMV9
2026-09-09 14:59:09 +02:00

141 lines
5.6 KiB
YAML

# Webapp-Mechanismus (Phase 2, 09.09.2026): kundeneigene URLs (kein fester
# Katalog-Merkmal wie sonst im Auftragskatalog - jeder Workspace hat seine
# eigene, freie Liste, siehe fetch_workspace_webapps() in
# provisioning-server/app.py). Deshalb kein present/absent pro Eintrag wie
# bei den anderen Rollen, sondern ein ECHTER ABGLEICH: die Rolle bekommt bei
# jedem Lauf die komplette aktuelle Liste (tuxflotte_webapps) und sorgt
# dafür, dass GENAU diese Einträge existieren - alles andere (frühere,
# inzwischen entfernte Webapps) wird aufgeräumt. Läuft deshalb bei jedem
# ansible-pull IMMER (siehe agent.py apply_roles()), nicht nur wenn sich
# etwas geändert hat.
#
# Dateibenennung nutzt die stabile UUID aus der DB (item.id), keine
# Slugifizierung des Namens nötig - vermeidet Kollisionen/Sonderzeichen-
# Probleme bei Namensänderungen.
- name: Ensure marker directory exists
ansible.builtin.file:
path: /run/tuxflotte/agent/applied
state: directory
mode: "0755"
- name: Ensure icon and applications directories exist
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ tuxflotte_webapp_icons_dir }}"
- "{{ tuxflotte_webapp_applications_dir }}"
- /etc/skel/Desktop
- name: Find existing tuxflotte-webapp .desktop files
ansible.builtin.find:
paths: "{{ tuxflotte_webapp_applications_dir }}"
patterns: "tuxflotte-webapp-*.desktop"
register: tuxflotte_webapp_existing_files
- name: Desired vs. vorhandene .desktop-Pfade ermitteln
ansible.builtin.set_fact:
tuxflotte_webapp_desired_files: >-
{{
tuxflotte_webapps
| map(attribute='id')
| map('regex_replace', '^(.*)$', tuxflotte_webapp_applications_dir ~ '/tuxflotte-webapp-\1.desktop')
| list
}}
tuxflotte_webapp_existing_paths: "{{ tuxflotte_webapp_existing_files.files | map(attribute='path') | list }}"
- name: Stale-Dateien (nicht mehr in der aktuellen Liste) berechnen
ansible.builtin.set_fact:
tuxflotte_webapp_stale_files: "{{ tuxflotte_webapp_existing_paths | difference(tuxflotte_webapp_desired_files) }}"
- name: Remove stale webapp .desktop files (nicht mehr in der aktuellen Liste)
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop: "{{ tuxflotte_webapp_stale_files }}"
- name: Download favicon for each webapp (falls vorhanden)
ansible.builtin.get_url:
url: "{{ item.icon_url }}"
dest: "{{ tuxflotte_webapp_icons_dir }}/{{ item.icon_url | basename }}"
mode: "0644"
timeout: 10
loop: "{{ tuxflotte_webapps }}"
loop_control:
label: "{{ item.name }}"
when: item.icon_url is not none
# Best-effort: ein einzelnes nicht erreichbares Favicon (Seite down,
# Netzwerkproblem auf dem Geraet) soll nicht den ganzen Lauf abbrechen -
# der .desktop-Eintrag selbst wird trotzdem angelegt (Icon zeigt dann
# kurzzeitig auf eine fehlende Datei, GTK faellt auf ein Platzhalter-Icon
# zurueck, kein Absturz).
ignore_errors: true
- name: Create/update .desktop menu entry for each webapp
ansible.builtin.template:
src: webapp.desktop.j2
dest: "{{ tuxflotte_webapp_applications_dir }}/tuxflotte-webapp-{{ item.id }}.desktop"
mode: "0644"
loop: "{{ tuxflotte_webapps }}"
loop_control:
label: "{{ item.name }}"
- name: Copy .desktop entries into /etc/skel/Desktop (für künftig neu angelegte Nutzer)
ansible.builtin.copy:
src: "{{ tuxflotte_webapp_applications_dir }}/tuxflotte-webapp-{{ item.id }}.desktop"
dest: "/etc/skel/Desktop/tuxflotte-webapp-{{ item.id }}.desktop"
mode: "0755"
remote_src: true
loop: "{{ tuxflotte_webapps }}"
loop_control:
label: "{{ item.name }}"
- name: Remove stale .desktop entries from /etc/skel/Desktop
ansible.builtin.file:
path: "/etc/skel/Desktop/{{ item | basename }}"
state: absent
loop: "{{ tuxflotte_webapp_stale_files }}"
# Bestehende Nutzer-Homeverzeichnisse (z.B. der "gast"-Account aus der
# guest-session-Rolle, falls aktiv): nur befüllen, wenn dort bereits ein
# Desktop-Ordner existiert (kein aufgezwungenes Anlegen für Nutzer, deren
# Desktop-Umgebung keine Desktop-Icons zeigt). ADR-0026 (kein primärer
# interaktiver Nutzer-Account bisher final festgelegt) ist hier eine
# bekannte offene Abhängigkeit - dieser bewusst pragmatische Ansatz deckt
# ab, was heute an Accounts real existiert, ohne auf die endgültige
# Klärung zu warten. Siehe project_phase2_app_store_merkmale-Memory.
- name: Bestehende Nutzer-Homeverzeichnisse mit Desktop-Ordner ermitteln
ansible.builtin.find:
paths: /home
file_type: directory
patterns: "Desktop"
recurse: true
depth: 2
register: tuxflotte_webapp_user_desktops
- name: .desktop-Einträge in bestehende Nutzer-Desktop-Ordner kopieren
ansible.builtin.copy:
src: "{{ tuxflotte_webapp_applications_dir }}/tuxflotte-webapp-{{ item.0.id }}.desktop"
dest: "{{ item.1.path }}/tuxflotte-webapp-{{ item.0.id }}.desktop"
mode: "0755"
remote_src: true
loop: "{{ tuxflotte_webapps | product(tuxflotte_webapp_user_desktops.files) | list }}"
loop_control:
label: "{{ item.0.name }} -> {{ item.1.path }}"
- name: Überzählige .desktop-Einträge aus bestehenden Nutzer-Desktop-Ordnern entfernen
ansible.builtin.file:
path: "{{ item.1.path }}/{{ item.0 | basename }}"
state: absent
loop: "{{ tuxflotte_webapp_stale_files | product(tuxflotte_webapp_user_desktops.files) | list }}"
loop_control:
label: "{{ item.0 }} -> {{ item.1.path }}"
- name: Record that the webapp-shortcuts role ran
ansible.builtin.copy:
dest: /run/tuxflotte/agent/applied/webapp-shortcuts.marker
content: "{{ ansible_date_time.iso8601 }}: {{ tuxflotte_webapps | length }} webapp(s)\n"
mode: "0644"