--- # ============================================================================ # life-church/playbooks/thinkcenter-kdenlive.yml # Install Kdenlive (video editor) on thinkcenter via apt, plus the extras that # make it usable on Cinnamon: Breeze icons (fixes blank toolbar icons), MLT # engine, frei0r effects, LADSPA audio effects, and extra codecs. # thinkcenter ONLY. Idempotent. Native packages (no flatpak/snap). # become password from Infisical /lc-hosts at runtime. # # NOTE: Ubuntu 24.04/Mint 22.3 ships Kdenlive 23.08.x (stable, ~1.5yr behind # upstream). This installs that native build + the fixups it needs on Cinnamon. # # UNDO: # sudo apt remove --purge kdenlive # sudo apt autoremove --purge # (breeze-icon-theme / frei0r-plugins / codecs are shared — leave them.) # ============================================================================ # --- Play 1 (localhost): fetch thinkcenter sudo pass from Infisical ---------- - name: "thinkcenter Kdenlive — resolve become password from Infisical" hosts: localhost gather_facts: false tasks: - name: "[resolve] Infisical creds from env" ansible.builtin.set_fact: infisical_client_id: "{{ lookup('env','INFISICAL_CLIENT_ID') }}" infisical_client_secret: "{{ lookup('env','INFISICAL_CLIENT_SECRET') }}" infisical_project_id: "{{ lookup('env','INFISICAL_PROJECT_ID') }}" infisical_url: "{{ lookup('env','INFISICAL_API_URL') | default('http://192.168.122.41:8080', true) }}" infisical_env_slug: "{{ lookup('env','INFISICAL_ENV_SLUG') | default('prod', true) }}" - name: "[resolve] Assert Infisical creds present" ansible.builtin.assert: that: - infisical_client_id | length > 0 - infisical_client_secret | length > 0 - infisical_project_id | length > 0 fail_msg: "Infisical creds missing from Semaphore environment 'infisical-dev'." - name: "[infisical] Log in" infisical.vault.login: url: "{{ infisical_url }}" auth_method: universal_auth universal_auth_client_id: "{{ infisical_client_id }}" universal_auth_client_secret: "{{ infisical_client_secret }}" register: infisical_login no_log: true - name: "[infisical] Read /lc-hosts" infisical.vault.read_secrets: login_data: "{{ infisical_login.login_data }}" project_id: "{{ infisical_project_id }}" env_slug: "{{ infisical_env_slug }}" path: "/lc-hosts" as_dict: true register: lc_secrets no_log: true - name: "[set] Stash thinkcenter sudo pass" ansible.builtin.set_fact: thinkcenter_become_pass: "{{ lc_secrets.secrets['THINKCENTER_SUDO_PASS'] }}" no_log: true # --- Play 2: Kdenlive on thinkcenter ONLY ------------------------------------ - name: "Install Kdenlive on thinkcenter" hosts: thinkcenter gather_facts: true become: true vars: ansible_become_pass: "{{ hostvars['localhost'].thinkcenter_become_pass }}" kdenlive_packages: - kdenlive # the editor (pulls MLT, Qt/KF5 automatically) - breeze-icon-theme # fixes blank toolbar icons on Cinnamon - frei0r-plugins # video effects/transitions via MLT (data bundled in this pkg) - swh-plugins # LADSPA audio effects - ladspa-sdk - libavcodec-extra # broad/restricted codec support (import fixes) - mediainfo # clip inspection tasks: - name: "[safety] Confirm we are on thinkcenter" ansible.builtin.assert: that: inventory_hostname == 'thinkcenter' fail_msg: "Refusing to run — this play is scoped to thinkcenter only." - name: "[safety] Confirm Ubuntu-family host" ansible.builtin.assert: that: ansible_facts.os_family == 'Debian' fail_msg: "This playbook targets Debian/Ubuntu (Mint). Host is {{ ansible_facts.os_family }}." - name: "[apt] Update cache (retry on transient failure)" ansible.builtin.apt: update_cache: true cache_valid_time: 3600 register: apt_cache until: apt_cache is succeeded retries: 3 delay: 15 # Robustness: never let a single wrong package name abort the run. Query # apt-cache for each desired package and install only the ones that exist, # warning about any that don't. `kdenlive` itself is asserted mandatory. - name: "[apt] Determine which desired packages actually exist in apt" ansible.builtin.shell: >- for p in {{ kdenlive_packages | join(' ') }}; do if apt-cache show "$p" >/dev/null 2>&1; then echo "$p"; fi done args: executable: /bin/bash register: pkg_probe changed_when: false - name: "[apt] Compute available vs missing" ansible.builtin.set_fact: pkgs_available: "{{ pkg_probe.stdout_lines }}" pkgs_missing: "{{ kdenlive_packages | difference(pkg_probe.stdout_lines) }}" - name: "[apt] Warn about any unavailable packages (non-fatal)" ansible.builtin.debug: msg: "Skipping packages not present in apt on this host: {{ pkgs_missing }}" when: pkgs_missing | length > 0 - name: "[apt] Assert Kdenlive itself is available" ansible.builtin.assert: that: "'kdenlive' in pkgs_available" fail_msg: "The 'kdenlive' package is not available in apt — cannot proceed." - name: "[apt] Install available Kdenlive package set (retry on dpkg lock)" block: - name: "[apt] Install packages" ansible.builtin.apt: name: "{{ pkgs_available }}" state: present register: kden_install until: kden_install is succeeded retries: 3 delay: 15 rescue: - name: "[apt] FALLBACK — install Kdenlive core only (drop optional extras)" ansible.builtin.apt: name: "{{ pkgs_available | reject('equalto','libavcodec-extra') | list }}" state: present register: kden_install_fallback until: kden_install_fallback is succeeded retries: 3 delay: 15 - name: "[apt] Note extras were reduced" ansible.builtin.debug: msg: "Full set failed (likely libavcodec-extra conflict); installed Kdenlive core. Add codecs manually if a clip won't import." # Verify via package DB, NOT by running the binary: kdenlive is a Qt GUI app # and `kdenlive --version` aborts (rc=-6) when there's no X display over SSH. - name: "[verify] Query kdenlive package status" ansible.builtin.command: dpkg-query -W -f='${Status} ${Version}' kdenlive register: kden_pkg changed_when: false failed_when: false - name: "[verify] kdenlive binary present on PATH" ansible.builtin.command: which kdenlive register: kden_bin changed_when: false failed_when: false - name: "[verify] MLT renderer (melt) present" ansible.builtin.command: which melt register: melt_which changed_when: false failed_when: false - name: "[verify] Assert Kdenlive + MLT engine installed" ansible.builtin.assert: that: - "'install ok installed' in (kden_pkg.stdout | default(''))" - kden_bin.rc == 0 - melt_which.rc == 0 fail_msg: "Kdenlive/MLT missing. pkg='{{ kden_pkg.stdout | default('') }}', bin rc={{ kden_bin.rc }}, melt rc={{ melt_which.rc }}" success_msg: "Kdenlive + MLT engine present." - name: "[report] Kdenlive summary" ansible.builtin.debug: msg: - "===== thinkcenter Kdenlive =====" - "packages changed this run : {{ kden_install.changed | default(kden_install_fallback.changed | default(false)) }}" - "Kdenlive package : {{ kden_pkg.stdout | default('n/a') | trim }}" - "kdenlive binary : {{ kden_bin.stdout | default('n/a') | trim }}" - "MLT renderer (melt) : {{ melt_which.stdout | default('n/a') | trim }}" - "NOTE: Ubuntu ships Kdenlive 23.08 (native). For the newest release use the official AppImage instead."