life-church: add thinkcenter-obs media playbook (thinkcenter-only, error-checked)

This commit is contained in:
Samuel James 2026-09-03 14:13:19 +00:00
parent 369298bc80
commit 4d0346b970

View File

@ -0,0 +1,163 @@
---
# ============================================================================
# life-church/playbooks/thinkcenter-obs.yml
# Install OBS Studio on thinkcenter via the official OBS PPA (latest stable),
# plus v4l2loopback (virtual camera) + ffmpeg. thinkcenter ONLY. Idempotent.
# Native packages only (no flatpak/snap — matches the homelab audio rule).
# become password from Infisical /lc-hosts at runtime.
#
# Mint gotcha handled: `add-apt-repository` mis-detects Mint's codename ("zena")
# instead of the Ubuntu base ("noble"). We add the PPA source explicitly pinned
# to the Ubuntu base codename so apt can resolve it.
#
# UNDO:
# sudo apt remove --purge obs-studio v4l2loopback-dkms
# sudo add-apt-repository --remove ppa:obsproject/obs-studio
# (or delete /etc/apt/sources.list.d/obsproject-*.list + key)
# ============================================================================
# --- Play 1 (localhost): fetch thinkcenter sudo pass from Infisical ----------
- name: "thinkcenter OBS — 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: OBS on thinkcenter ONLY -----------------------------------------
- name: "Install OBS Studio on thinkcenter"
hosts: thinkcenter
gather_facts: true
become: true
vars:
ansible_become_pass: "{{ hostvars['localhost'].thinkcenter_become_pass }}"
obs_ppa_codename: noble # Ubuntu base for Mint 22.3 (NOT 'zena')
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 (apt/PPA path)"
ansible.builtin.assert:
that: ansible_facts.os_family == 'Debian'
fail_msg: "This playbook targets Debian/Ubuntu (Mint). Host is {{ ansible_facts.os_family }}."
- name: "[repo] Ensure keyrings dir exists"
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
- name: "[repo] Fetch OBS PPA signing key into keyring (modern signed-by method)"
ansible.builtin.get_url:
url: "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xBC7345F522079769F5BBE987EFC71127F425E228"
dest: /etc/apt/keyrings/obsproject-obs-studio.asc
mode: "0644"
force: false
register: obs_key
until: obs_key is succeeded
retries: 3
delay: 10
- name: "[repo] Add OBS PPA source pinned to Ubuntu base codename (avoids Mint 'zena' bug)"
ansible.builtin.apt_repository:
repo: "deb [signed-by=/etc/apt/keyrings/obsproject-obs-studio.asc] https://ppa.launchpadcontent.net/obsproject/obs-studio/ubuntu {{ obs_ppa_codename }} main"
filename: obsproject-obs-studio
state: present
update_cache: false
register: obs_repo
- name: "[repo] Update apt cache (retry on transient failure)"
ansible.builtin.apt:
update_cache: true
register: apt_cache
until: apt_cache is succeeded
retries: 3
delay: 15
- name: "[apt] Install OBS Studio + virtual-cam + ffmpeg (retry on dpkg lock)"
ansible.builtin.apt:
name:
- obs-studio
- v4l2loopback-dkms
- v4l2loopback-utils
- ffmpeg
state: present
register: obs_install
until: obs_install is succeeded
retries: 3
delay: 15
- name: "[vcam] Configure v4l2loopback module for the OBS virtual camera"
ansible.builtin.copy:
dest: /etc/modprobe.d/obs-v4l2loopback.conf
mode: "0644"
content: |
options v4l2loopback devices=1 video_nr=10 card_label="OBS Virtual Camera" exclusive_caps=1
register: vcam_conf
- name: "[vcam] Load v4l2loopback now (non-fatal if module build pending a reboot)"
community.general.modprobe:
name: v4l2loopback
state: present
register: vcam_load
failed_when: false
- name: "[verify] OBS binary present + version"
ansible.builtin.command: obs --version
register: obs_ver
changed_when: false
failed_when: false
- name: "[verify] Assert OBS installed"
ansible.builtin.assert:
that: "'obs-studio' in (obs_install.stdout | default('')) or obs_ver.rc == 0 or ('OBS' in (obs_ver.stdout | default('')) | string)"
fail_msg: "OBS Studio does not appear to be installed."
success_msg: "OBS Studio installed."
- name: "[report] OBS summary"
ansible.builtin.debug:
msg:
- "===== thinkcenter OBS Studio ====="
- "packages changed this run : {{ obs_install.changed }}"
- "OBS version : {{ obs_ver.stdout | default('(query failed — check after login)') | trim }}"
- "v4l2loopback module loaded: {{ 'yes' if vcam_load.rc | default(1) == 0 else 'not yet (loads on Start Virtual Camera / reboot)' }}"
- "NOTE: on Mint X11 use XSHM/XComposite capture sources; PipeWire capture is for Wayland."