197 lines
8.3 KiB
YAML
197 lines
8.3 KiB
YAML
---
|
|
# ============================================================================
|
|
# 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: "[selfheal] Repair any half-configured dpkg/apt state (prevents cascade failures)"
|
|
ansible.builtin.shell: |
|
|
dpkg --configure -a || true
|
|
apt-get -y -f install || true
|
|
register: dpkg_selfheal
|
|
changed_when: "'Setting up' in (dpkg_selfheal.stdout | default(''))"
|
|
failed_when: false
|
|
|
|
- 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."
|