From fb9893504c0816c44cc7a4bc9de0553e19546bda Mon Sep 17 00:00:00 2001 From: The_miro Date: Mon, 18 May 2026 11:52:27 +0200 Subject: [PATCH] setup: add FreeIPA Flatpak group installer (fp_install_* groups) IPA group naming: fp_install_org__mozilla__firefox (dots encoded as __) Decoding: sed strips prefix, then s/__/./g restores the Flatpak app ID. Single underscores in app IDs are preserved unambiguously. ansipa-install-flatpaks.sh: - kinit with host keytab, queries ipa group-find --pkey-only with awk $NF - Validates decoded ID against reverse-domain regex before installing - Ensures flathub system remote exists - System-scope install (flatpak install --system) since service runs as root - Timer offset to 4 min (after packages at 2 min) to avoid contention deploy-ansipa-install.yml updated to deploy the Flatpak script, service, and timer alongside the existing package installer. Co-Authored-By: Claude Sonnet 4.6 --- .../ansible/ansipa-install-flatpaks.service | 10 +++ .../ansible/ansipa-install-flatpaks.sh | 90 +++++++++++++++++++ .../ansible/ansipa-install-flatpaks.timer | 9 ++ .../ansible/deploy-ansipa-install.yml | 45 +++++++++- 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.service create mode 100755 setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.sh create mode 100644 setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.timer diff --git a/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.service b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.service new file mode 100644 index 0000000..cb43574 --- /dev/null +++ b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.service @@ -0,0 +1,10 @@ +[Unit] +Description=Install Flatpaks based on FreeIPA fp_install_* groups +After=network-online.target sssd.service +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/ansipa-install-flatpaks.sh +StandardOutput=journal +StandardError=journal diff --git a/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.sh b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.sh new file mode 100755 index 0000000..30373f0 --- /dev/null +++ b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# ansipa-install-flatpaks.sh — install Flatpak apps based on FreeIPA group membership. +# +# IPA group naming convention (dots encoded as double underscores): +# fp_install_org__mozilla__firefox → installs org.mozilla.firefox +# fp_install_com__spotify__Client → installs com.spotify.Client +# fp_install_io__missioncenter__MissionCenter → installs io.missioncenter.MissionCenter +# +# Decoding: strip "fp_install_" prefix, then replace every __ with a dot. +# Single underscores in Flatpak IDs are preserved as-is. +# +# Scope: system-wide (--system), runs as root via systemd service. + +set -e + +PREFIX="fp_install_" + +# ── Preflight ───────────────────────────────────────────────────────────────── +if ! command -v flatpak &>/dev/null; then + echo "[ansipa-flatpaks] flatpak not installed — nothing to do." + exit 0 +fi + +if ! command -v ipa &>/dev/null; then + echo "[ansipa-flatpaks] ipa command not found — host not enrolled in FreeIPA." + exit 0 +fi + +kinit -k "host/$(hostname -f)" &>/dev/null || true + +# ── Ensure Flathub remote is configured (system scope) ─────────────────────── +if ! flatpak remote-list --system | awk '{print $1}' | grep -qx "flathub"; then + echo "[ansipa-flatpaks] Adding Flathub system remote..." + flatpak remote-add --system --if-not-exists flathub \ + https://dl.flathub.org/repo/flathub.flatpakrepo +fi + +# ── Discover IPA groups matching fp_install_* ───────────────────────────────── +# ipa group-find --pkey-only outputs one group name per line (possibly indented). +# $NF captures the name regardless of leading label text. +IPA_GROUPS=$(ipa group-find --pkey-only 2>/dev/null \ + | awk '{print $NF}' \ + | grep "^${PREFIX}" \ + || true) + +if [[ -z "$IPA_GROUPS" ]]; then + echo "[ansipa-flatpaks] No ${PREFIX}* groups found in IPA — nothing to install." + exit 0 +fi + +# ── Decode group names → Flatpak application IDs ───────────────────────────── +# 1. Strip the fp_install_ prefix +# 2. Replace every __ with a literal dot +DESIRED_FLATPAKS=() +while IFS= read -r G; do + [[ -z "$G" ]] && continue + FLATPAK_ID=$(echo "$G" \ + | sed "s/^${PREFIX}//" \ + | sed 's/__/./g') + + # Validate: must be reverse-domain notation with at least two components + if ! echo "$FLATPAK_ID" | grep -qE '^[a-zA-Z][a-zA-Z0-9_-]*(\.[a-zA-Z0-9][a-zA-Z0-9_-]*)+$'; then + echo "[ansipa-flatpaks][WARN] '$FLATPAK_ID' (from group '$G') is not a valid Flatpak ID — skipping." + continue + fi + + DESIRED_FLATPAKS+=("$FLATPAK_ID") +done <<< "$IPA_GROUPS" + +if [[ ${#DESIRED_FLATPAKS[@]} -eq 0 ]]; then + echo "[ansipa-flatpaks] No valid Flatpak IDs decoded from IPA groups." + exit 0 +fi + +echo "[ansipa-flatpaks] Desired Flatpaks: ${DESIRED_FLATPAKS[*]}" + +# ── Get currently installed system Flatpaks ─────────────────────────────────── +INSTALLED=$(flatpak list --system --app --columns=application 2>/dev/null || true) + +# ── Install missing apps ────────────────────────────────────────────────────── +for ID in "${DESIRED_FLATPAKS[@]}"; do + if echo "$INSTALLED" | grep -qx "$ID"; then + echo "[ansipa-flatpaks] Already installed: $ID" + else + echo "[ansipa-flatpaks] Installing: $ID" + flatpak install --system -y --noninteractive flathub "$ID" \ + && echo "[ansipa-flatpaks] Installed: $ID" \ + || echo "[ansipa-flatpaks][WARN] Failed to install: $ID" + fi +done diff --git a/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.timer b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.timer new file mode 100644 index 0000000..fecd790 --- /dev/null +++ b/setup/modules/FreeipaAnsible/ansible/ansipa-install-flatpaks.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Periodic FreeIPA Flatpak sync + +[Timer] +OnBootSec=4min +OnUnitActiveSec=30min + +[Install] +WantedBy=timers.target diff --git a/setup/modules/FreeipaAnsible/ansible/deploy-ansipa-install.yml b/setup/modules/FreeipaAnsible/ansible/deploy-ansipa-install.yml index 7393ce2..7736df4 100644 --- a/setup/modules/FreeipaAnsible/ansible/deploy-ansipa-install.yml +++ b/setup/modules/FreeipaAnsible/ansible/deploy-ansipa-install.yml @@ -39,11 +39,54 @@ [Install] WantedBy=timers.target + - name: Install Flatpak installer script + copy: + src: ansipa-install-flatpaks.sh + dest: /usr/local/bin/ansipa-install-flatpaks.sh + mode: '0755' + + - name: Install Flatpak systemd service + copy: + dest: /etc/systemd/system/ansipa-install-flatpaks.service + mode: '0644' + content: | + [Unit] + Description=Install Flatpaks based on FreeIPA fp_install_* groups + After=network-online.target sssd.service + Wants=network-online.target + + [Service] + Type=oneshot + ExecStart=/usr/local/bin/ansipa-install-flatpaks.sh + StandardOutput=journal + StandardError=journal + + - name: Install Flatpak systemd timer + copy: + dest: /etc/systemd/system/ansipa-install-flatpaks.timer + mode: '0644' + content: | + [Unit] + Description=Periodic FreeIPA Flatpak sync + + [Timer] + OnBootSec=4min + OnUnitActiveSec=30min + + [Install] + WantedBy=timers.target + - name: Reload systemd command: systemctl daemon-reload - - name: Enable and start timer + - name: Enable and start package timer systemd: name: ansipa-install.timer enabled: yes state: started + + - name: Enable and start Flatpak timer + systemd: + name: ansipa-install-flatpaks.timer + enabled: yes + state: started