75 lines
3.4 KiB
YAML
75 lines
3.4 KiB
YAML
---
|
|
# Converges one stack (one loop iteration of `stack` from playbooks/unraid.yml)
|
|
# to the state its host_vars entry asks for.
|
|
#
|
|
# `state: present` (the default) deploys; `state: absent` tears down. Removal
|
|
# has to be asked for explicitly because Ansible keeps no record of what it
|
|
# deployed last run — deleting a stack from a host's `stacks:` list only stops
|
|
# the loop visiting it, leaving the containers running and unmanaged on the
|
|
# host forever. So the entry stays put as a tombstone, with `state: absent`,
|
|
# until the teardown has actually been applied.
|
|
#
|
|
# Unraid-only by design. Proxmox guests install apps natively rather than as
|
|
# Compose stacks — see the `lxc_app` role.
|
|
|
|
- name: Set stack facts
|
|
ansible.builtin.set_fact:
|
|
stack_local_dir: "{{ repo_root }}/src/{{ stack.src }}"
|
|
stack_remote_dir: "{{ compose_projects_root }}/{{ stack.name }}"
|
|
stack_state: "{{ stack.state | default('present') }}"
|
|
|
|
- name: Validate requested stack state
|
|
ansible.builtin.assert:
|
|
that: stack_state in ['present', 'absent']
|
|
fail_msg: >-
|
|
Stack '{{ stack.name }}' has state '{{ stack_state }}'; expected
|
|
'present' or 'absent'.
|
|
quiet: true
|
|
|
|
# Which icons this stack ships, worked out from the repo checkout on the
|
|
# controller rather than from anything on the host — `is exists` and the
|
|
# `fileglob` lookup both evaluate locally. Computed here rather than in
|
|
# deploy.yml because both branches need it: deploy copies these files out,
|
|
# remove deletes them again.
|
|
#
|
|
# Two naming conventions, because Unraid has two icon consumers (see
|
|
# deploy.yml for the full explanation):
|
|
#
|
|
# icon.png the stack — Compose Manager's project row, plus the
|
|
# `net.unraid.docker.icon` label of whichever service
|
|
# interpolates ${STACK_ICON}.
|
|
# icon-<service>.png one container — becomes ${STACK_ICON_<SERVICE>}, so a
|
|
# multi-container stack can label each of its services
|
|
# with its own image instead of sharing the stack's.
|
|
#
|
|
# `<service>` is the compose service name; the variable is it uppercased with
|
|
# `-` folded to `_` (icon-shelfarr-libation.png → STACK_ICON_SHELFARR_LIBATION).
|
|
- name: Set stack icon facts
|
|
ansible.builtin.set_fact:
|
|
# Empty when the stack ships no icon.png — an empty label is what the
|
|
# webgui already assumes, so it falls back to the placeholder as before.
|
|
stack_icon_dest: >-
|
|
{{ ((stack_local_dir ~ '/ansible/unraid/icon.png') is exists)
|
|
| ternary(unraid_icons_root ~ '/' ~ stack.name ~ '.png', '') }}
|
|
stack_service_icon_names: "{{ _service_icon_names }}"
|
|
stack_service_icons: >-
|
|
{{ dict(_service_icon_names
|
|
| map('upper') | map('replace', '-', '_')
|
|
| map('regex_replace', '^(.+)$', 'STACK_ICON_\1')
|
|
| zip(_service_icon_names
|
|
| map('regex_replace', '^(.+)$',
|
|
unraid_icons_root ~ '/' ~ stack.name ~ '-\1.png'))) }}
|
|
vars:
|
|
_service_icon_names: >-
|
|
{{ query('fileglob', stack_local_dir ~ '/ansible/unraid/icon-*.png')
|
|
| map('basename')
|
|
| map('regex_replace', '^icon-(.+)\.png$', '\1')
|
|
| map('lower') | list }}
|
|
|
|
- name: Deploy stack
|
|
ansible.builtin.include_tasks: deploy.yml
|
|
when: stack_state == 'present'
|
|
|
|
- name: Remove stack
|
|
ansible.builtin.include_tasks: remove.yml
|
|
when: stack_state == 'absent'
|