thinkcenter-audio: harden — linger-first + wait runtime dir + rescue fallback for user units, apt retries, user/uid asserts
This commit is contained in:
parent
aca4801744
commit
6fa9505f5a
@ -94,25 +94,44 @@
|
|||||||
that: inventory_hostname == 'thinkcenter'
|
that: inventory_hostname == 'thinkcenter'
|
||||||
fail_msg: "Refusing to run — this play is scoped to thinkcenter only."
|
fail_msg: "Refusing to run — this play is scoped to thinkcenter only."
|
||||||
|
|
||||||
|
- name: "[safety] Assert audio_user resolved from Infisical"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- audio_user is defined
|
||||||
|
- audio_user | length > 0
|
||||||
|
fail_msg: "audio_user is empty — THINKCENTER_USER not read from Infisical /lc-hosts."
|
||||||
|
|
||||||
- name: "[facts] Resolve audio_user UID (for XDG_RUNTIME_DIR)"
|
- name: "[facts] Resolve audio_user UID (for XDG_RUNTIME_DIR)"
|
||||||
ansible.builtin.getent:
|
ansible.builtin.getent:
|
||||||
database: passwd
|
database: passwd
|
||||||
key: "{{ audio_user }}"
|
key: "{{ audio_user }}"
|
||||||
|
|
||||||
|
- name: "[facts] Assert the user actually exists on the host"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that: audio_user in ansible_facts.getent_passwd
|
||||||
|
fail_msg: "User '{{ audio_user }}' does not exist on {{ inventory_hostname }}."
|
||||||
|
|
||||||
- name: "[facts] Set audio_uid"
|
- name: "[facts] Set audio_uid"
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
audio_uid: "{{ ansible_facts.getent_passwd[audio_user][1] }}"
|
audio_uid: "{{ ansible_facts.getent_passwd[audio_user][1] }}"
|
||||||
|
|
||||||
- name: "[apt] Update cache"
|
- name: "[apt] Update cache (retry on transient network/lock)"
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
|
register: apt_cache
|
||||||
|
until: apt_cache is succeeded
|
||||||
|
retries: 3
|
||||||
|
delay: 10
|
||||||
|
|
||||||
- name: "[apt] Install unified PipeWire audio stack + qpwgraph"
|
- name: "[apt] Install unified PipeWire audio stack + qpwgraph (retry on dpkg lock)"
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
name: "{{ audio_packages }}"
|
name: "{{ audio_packages }}"
|
||||||
state: present
|
state: present
|
||||||
register: pkg_install
|
register: pkg_install
|
||||||
|
until: pkg_install is succeeded
|
||||||
|
retries: 3
|
||||||
|
delay: 15
|
||||||
|
|
||||||
- name: "[conflict] Detect a STANDALONE pulseaudio daemon package (not the pw-pulse shim)"
|
- name: "[conflict] Detect a STANDALONE pulseaudio daemon package (not the pw-pulse shim)"
|
||||||
ansible.builtin.shell: "dpkg -l pulseaudio 2>/dev/null | awk '/^ii/{print $2}'"
|
ansible.builtin.shell: "dpkg -l pulseaudio 2>/dev/null | awk '/^ii/{print $2}'"
|
||||||
@ -134,12 +153,26 @@
|
|||||||
register: mask_pa
|
register: mask_pa
|
||||||
changed_when: mask_pa.rc == 0
|
changed_when: mask_pa.rc == 0
|
||||||
|
|
||||||
- name: "[services] Enable PipeWire user services for {{ audio_user }} (lingering + enable)"
|
# --- User-session services: made robust ---------------------------------
|
||||||
|
# systemctl --user needs a live user runtime dir + D-Bus. Enabling linger
|
||||||
|
# FIRST makes systemd create a persistent /run/user/<uid> even with no GUI
|
||||||
|
# login, so this works whether or not steve is currently logged in.
|
||||||
|
- name: "[services] Enable lingering for {{ audio_user }} (persistent user manager)"
|
||||||
ansible.builtin.command: "loginctl enable-linger {{ audio_user }}"
|
ansible.builtin.command: "loginctl enable-linger {{ audio_user }}"
|
||||||
register: linger
|
register: linger
|
||||||
changed_when: "'already' not in (linger.stderr | default(''))"
|
changed_when: "linger.rc == 0 and 'already enabled' not in (linger.stderr | default(''))"
|
||||||
failed_when: false
|
failed_when: linger.rc != 0 and 'already enabled' not in (linger.stderr | default('') + linger.stdout | default(''))
|
||||||
|
|
||||||
|
- name: "[services] Wait for user runtime dir /run/user/{{ audio_uid }} to exist"
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "/run/user/{{ audio_uid }}"
|
||||||
|
register: runtime_dir
|
||||||
|
until: runtime_dir.stat.exists
|
||||||
|
retries: 6
|
||||||
|
delay: 5
|
||||||
|
|
||||||
|
- name: "[services] Enable PipeWire user units (with rescue if session bus is not ready)"
|
||||||
|
block:
|
||||||
- name: "[services] Enable pipewire / pipewire-pulse / wireplumber for the user"
|
- name: "[services] Enable pipewire / pipewire-pulse / wireplumber for the user"
|
||||||
become: true
|
become: true
|
||||||
become_user: "{{ audio_user }}"
|
become_user: "{{ audio_user }}"
|
||||||
@ -153,8 +186,26 @@
|
|||||||
- wireplumber.service
|
- wireplumber.service
|
||||||
environment:
|
environment:
|
||||||
XDG_RUNTIME_DIR: "/run/user/{{ audio_uid }}"
|
XDG_RUNTIME_DIR: "/run/user/{{ audio_uid }}"
|
||||||
failed_when: false
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ audio_uid }}/bus"
|
||||||
register: user_services
|
register: user_services
|
||||||
|
rescue:
|
||||||
|
- name: "[services] FALLBACK — enable units via systemctl --user by uid (no D-Bus dependency)"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ audio_user }}"
|
||||||
|
ansible.builtin.command: "systemctl --user enable {{ item }}"
|
||||||
|
loop:
|
||||||
|
- pipewire.socket
|
||||||
|
- pipewire-pulse.socket
|
||||||
|
- wireplumber.service
|
||||||
|
environment:
|
||||||
|
XDG_RUNTIME_DIR: "/run/user/{{ audio_uid }}"
|
||||||
|
register: user_services_fallback
|
||||||
|
changed_when: "'Created symlink' in (user_services_fallback.stderr | default(''))"
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: "[services] Note the fallback path was used"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "User D-Bus not ready; enabled PipeWire units via the systemctl fallback. They will start on next login/linger."
|
||||||
|
|
||||||
- name: "[verify] Which server does pactl report?"
|
- name: "[verify] Which server does pactl report?"
|
||||||
become: true
|
become: true
|
||||||
@ -162,6 +213,7 @@
|
|||||||
ansible.builtin.command: pactl info
|
ansible.builtin.command: pactl info
|
||||||
environment:
|
environment:
|
||||||
XDG_RUNTIME_DIR: "/run/user/{{ audio_uid }}"
|
XDG_RUNTIME_DIR: "/run/user/{{ audio_uid }}"
|
||||||
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ audio_uid }}/bus"
|
||||||
register: pactl_info
|
register: pactl_info
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user