135 lines
4.5 KiB
YAML
135 lines
4.5 KiB
YAML
|
|
---
|
||
|
|
# The user, the directories, and the binary.
|
||
|
|
|
||
|
|
- name: Install Navidrome's runtime dependencies
|
||
|
|
apt:
|
||
|
|
name:
|
||
|
|
# Navidrome shells out to ffmpeg for on-the-fly transcoding. Without it
|
||
|
|
# the server starts fine and every format the client cannot play natively
|
||
|
|
# simply fails, which looks like a client bug.
|
||
|
|
- ffmpeg
|
||
|
|
- curl
|
||
|
|
state: present
|
||
|
|
update_cache: true
|
||
|
|
|
||
|
|
- name: Create the navidrome system group
|
||
|
|
group:
|
||
|
|
name: "{{ navidrome_group }}"
|
||
|
|
system: yes
|
||
|
|
state: present
|
||
|
|
|
||
|
|
- name: Create the navidrome system user
|
||
|
|
user:
|
||
|
|
name: "{{ navidrome_user }}"
|
||
|
|
group: "{{ navidrome_group }}"
|
||
|
|
system: yes
|
||
|
|
shell: /usr/sbin/nologin
|
||
|
|
home: "{{ navidrome_data_dir }}"
|
||
|
|
create_home: no
|
||
|
|
comment: "Navidrome Music Server"
|
||
|
|
state: present
|
||
|
|
|
||
|
|
- name: Create the navidrome data directory
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: "{{ navidrome_data_dir }}"
|
||
|
|
state: directory
|
||
|
|
owner: "{{ navidrome_user }}"
|
||
|
|
group: "{{ navidrome_group }}"
|
||
|
|
mode: '0750'
|
||
|
|
|
||
|
|
- name: Create the navidrome config directory
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: "{{ navidrome_config_dir }}"
|
||
|
|
state: directory
|
||
|
|
owner: root
|
||
|
|
group: "{{ navidrome_group }}"
|
||
|
|
mode: '0750'
|
||
|
|
|
||
|
|
# Two principals share this tree and neither is root: the curator writes it
|
||
|
|
# through beets, Navidrome only reads it. setgid (the 2) is load-bearing -
|
||
|
|
# without it, files beets creates land in the curator's own group and Navidrome
|
||
|
|
# cannot read them, which presents as an empty library rather than an error.
|
||
|
|
- name: Create the music library directory
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: "{{ navidrome_music_dir }}"
|
||
|
|
state: directory
|
||
|
|
owner: "{{ navidrome_curator_user }}"
|
||
|
|
group: "{{ navidrome_group }}"
|
||
|
|
mode: '2750'
|
||
|
|
|
||
|
|
- name: Create the incoming staging directory
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: "{{ navidrome_incoming_dir }}"
|
||
|
|
state: directory
|
||
|
|
owner: "{{ navidrome_curator_user }}"
|
||
|
|
group: "{{ navidrome_curator_user }}"
|
||
|
|
mode: '0755'
|
||
|
|
|
||
|
|
# check_mode: no on the next two - this repo verifies with `--check --diff`, so
|
||
|
|
# the role has to survive a dry run. A read-only version probe and a temp
|
||
|
|
# directory are both harmless to perform for real, and without them every task
|
||
|
|
# below evaluates against an undefined navidrome_tmp.path and the check aborts.
|
||
|
|
- name: Check the installed navidrome version
|
||
|
|
ansible.builtin.command: "{{ navidrome_bin_path }} --version"
|
||
|
|
register: navidrome_installed_version
|
||
|
|
changed_when: false
|
||
|
|
failed_when: false
|
||
|
|
check_mode: no
|
||
|
|
|
||
|
|
- name: Decide whether navidrome needs installing
|
||
|
|
ansible.builtin.set_fact:
|
||
|
|
navidrome_needs_install: "{{ navidrome_version not in (navidrome_installed_version.stdout | default('')) }}"
|
||
|
|
|
||
|
|
- name: Create a temporary directory for the navidrome download
|
||
|
|
ansible.builtin.tempfile:
|
||
|
|
state: directory
|
||
|
|
suffix: navidrome
|
||
|
|
register: navidrome_tmp
|
||
|
|
when: navidrome_needs_install | bool
|
||
|
|
check_mode: no
|
||
|
|
|
||
|
|
# checksum: is the verification. Upstream publishes navidrome_checksums.txt per
|
||
|
|
# release but signs nothing, so there is no signature to check the way
|
||
|
|
# roles/monero checks binaryfate's - this pins the exact artefact and no more.
|
||
|
|
- name: Download the navidrome release tarball
|
||
|
|
ansible.builtin.get_url:
|
||
|
|
url: "{{ navidrome_url }}"
|
||
|
|
dest: "{{ navidrome_tmp.path }}/navidrome.tar.gz"
|
||
|
|
checksum: "sha256:{{ navidrome_sha256 }}"
|
||
|
|
mode: '0644'
|
||
|
|
when: navidrome_needs_install | bool and not ansible_check_mode
|
||
|
|
|
||
|
|
- name: Unpack the navidrome tarball
|
||
|
|
ansible.builtin.unarchive:
|
||
|
|
src: "{{ navidrome_tmp.path }}/navidrome.tar.gz"
|
||
|
|
dest: "{{ navidrome_tmp.path }}"
|
||
|
|
remote_src: yes
|
||
|
|
when: navidrome_needs_install | bool and not ansible_check_mode
|
||
|
|
|
||
|
|
- name: Install the navidrome binary
|
||
|
|
ansible.builtin.copy:
|
||
|
|
src: "{{ navidrome_tmp.path }}/navidrome"
|
||
|
|
dest: "{{ navidrome_bin_path }}"
|
||
|
|
remote_src: yes
|
||
|
|
owner: root
|
||
|
|
group: root
|
||
|
|
mode: '0755'
|
||
|
|
when: navidrome_needs_install | bool and not ansible_check_mode
|
||
|
|
notify: Restart navidrome
|
||
|
|
|
||
|
|
- name: Remove the navidrome download directory
|
||
|
|
ansible.builtin.file:
|
||
|
|
path: "{{ navidrome_tmp.path }}"
|
||
|
|
state: absent
|
||
|
|
when: navidrome_needs_install | bool
|
||
|
|
check_mode: no
|
||
|
|
|
||
|
|
# Check mode skips the three tasks above, so without this a dry run is silent
|
||
|
|
# about the single most important thing it would do.
|
||
|
|
- name: Report what a real run would install
|
||
|
|
ansible.builtin.debug:
|
||
|
|
msg: >-
|
||
|
|
Would install navidrome {{ navidrome_version }} to {{ navidrome_bin_path }}
|
||
|
|
(currently: {{ navidrome_installed_version.stdout | default('not installed') | trim }})
|
||
|
|
when: navidrome_needs_install | bool and ansible_check_mode
|