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
141 lines
5.6 KiB
YAML
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"
|