|
|
|
|
@@ -18,21 +18,28 @@
|
|
|
|
|
- backend_phase1_app_data_root.startswith('/')
|
|
|
|
|
- backend_phase1_navidrome_data_dir.startswith(backend_phase1_app_data_root + '/')
|
|
|
|
|
- backend_phase1_syncthing_root.startswith(backend_phase1_app_data_root + '/')
|
|
|
|
|
- >-
|
|
|
|
|
not (backend_phase1_music_sync_enabled | bool) or
|
|
|
|
|
(backend_phase1_music_source_dir.startswith(backend_phase1_archive_dir + '/')
|
|
|
|
|
and backend_phase1_music_sync_calendar | length > 0)
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
Disable the rootful media-stack gate and provide the Atlas LAN bind
|
|
|
|
|
address, firewall sources, and absolute ZFS-backed paths before
|
|
|
|
|
enabling phase one. This role does not manage Prometheus or migrate
|
|
|
|
|
application data.
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Read the rootless service account
|
|
|
|
|
ansible.builtin.getent:
|
|
|
|
|
database: passwd
|
|
|
|
|
key: "{{ backend_phase1_username }}"
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Record rootless service account IDs
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
backend_phase1_uid: "{{ ansible_facts['getent_passwd'][backend_phase1_username][1] }}"
|
|
|
|
|
backend_phase1_gid: "{{ ansible_facts['getent_passwd'][backend_phase1_username][2] }}"
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Read system service state before starting rootless Syncthing
|
|
|
|
|
ansible.builtin.service_facts:
|
|
|
|
|
@@ -65,6 +72,7 @@
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.dataset }}"
|
|
|
|
|
register: backend_phase1_zfs_facts
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Require mounted datasets at the declared paths
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
@@ -79,6 +87,23 @@
|
|
|
|
|
loop: "{{ backend_phase1_zfs_facts.results }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.item.dataset }}"
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Inspect the music copy source
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ backend_phase1_music_source_dir }}"
|
|
|
|
|
register: backend_phase1_music_source_stat
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Require an existing music source directory
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- backend_phase1_music_source_stat.stat.isdir | default(false)
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
{{ backend_phase1_music_source_dir }} must exist before enabling the daily music copy.
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Enable lingering for the rootless service account
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
@@ -87,12 +112,14 @@
|
|
|
|
|
- enable-linger
|
|
|
|
|
- "{{ backend_phase1_username }}"
|
|
|
|
|
creates: "/var/lib/systemd/linger/{{ backend_phase1_username }}"
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Start the rootless user systemd manager
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "user@{{ backend_phase1_uid }}.service"
|
|
|
|
|
state: started
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Create rootless Quadlet and application directories
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
@@ -113,6 +140,43 @@
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.path }}"
|
|
|
|
|
|
|
|
|
|
- name: Install rsync for the daily music copy
|
|
|
|
|
ansible.builtin.dnf:
|
|
|
|
|
name: rsync
|
|
|
|
|
state: present
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Create the rootless user systemd directory
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ backend_phase1_user_systemd_dir }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: "{{ backend_phase1_username }}"
|
|
|
|
|
group: "{{ backend_phase1_user_group }}"
|
|
|
|
|
mode: "0700"
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Install the daily music copy service
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: atlas-music-sync.service.j2
|
|
|
|
|
dest: "{{ backend_phase1_user_systemd_dir }}/atlas-music-sync.service"
|
|
|
|
|
owner: "{{ backend_phase1_username }}"
|
|
|
|
|
group: "{{ backend_phase1_user_group }}"
|
|
|
|
|
mode: "0644"
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Install the daily music copy timer
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: atlas-music-sync.timer.j2
|
|
|
|
|
dest: "{{ backend_phase1_user_systemd_dir }}/atlas-music-sync.timer"
|
|
|
|
|
owner: "{{ backend_phase1_username }}"
|
|
|
|
|
group: "{{ backend_phase1_user_group }}"
|
|
|
|
|
mode: "0644"
|
|
|
|
|
when: backend_phase1_music_sync_enabled | bool
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Render the rootless Navidrome Quadlet
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: atlas-navidrome.container.j2
|
|
|
|
|
@@ -140,6 +204,7 @@
|
|
|
|
|
XDG_RUNTIME_DIR: "/run/user/{{ backend_phase1_uid }}"
|
|
|
|
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ backend_phase1_uid }}/bus"
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|
|
|
|
|
- name: Permit NPM access to phase-one web interfaces through Aegis
|
|
|
|
|
ansible.posix.firewalld:
|
|
|
|
|
@@ -186,3 +251,19 @@
|
|
|
|
|
when:
|
|
|
|
|
- backend_phase1_start_services | bool
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Enable the daily music copy timer
|
|
|
|
|
become_user: "{{ backend_phase1_username }}"
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: atlas-music-sync.timer
|
|
|
|
|
scope: user
|
|
|
|
|
state: started
|
|
|
|
|
enabled: true
|
|
|
|
|
daemon_reload: true
|
|
|
|
|
environment:
|
|
|
|
|
XDG_RUNTIME_DIR: "/run/user/{{ backend_phase1_uid }}"
|
|
|
|
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ backend_phase1_uid }}/bus"
|
|
|
|
|
when:
|
|
|
|
|
- backend_phase1_music_sync_enabled | bool
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
tags: [music_sync]
|
|
|
|
|
|