Split incus role from playbook
This commit is contained in:
parent
0f8822e632
commit
eaaa35de25
11 changed files with 531 additions and 318 deletions
|
|
@ -1,324 +1,23 @@
|
||||||
---
|
---
|
||||||
- name: Update system
|
- name: Prepare incus server host
|
||||||
hosts: all
|
hosts: incus_server
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure aptitude installed
|
- name: Prepare system
|
||||||
apt:
|
ansible.builtin.import_role:
|
||||||
name: "aptitude"
|
name: system
|
||||||
state: present
|
tags: system
|
||||||
tags:
|
|
||||||
- apt
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Ensure OS upgraded
|
# FIXME: Role needs much fixup before it can run
|
||||||
apt:
|
# - name: Prepare incus
|
||||||
upgrade: dist
|
# ansible.builtin.import_role:
|
||||||
tags:
|
# name: incus-install
|
||||||
- apt
|
# tags: incus
|
||||||
- update
|
|
||||||
- os
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Check if reboot is necessary
|
|
||||||
register: reboot_required_file
|
|
||||||
stat:
|
|
||||||
path: /var/run/reboot-required
|
|
||||||
get_checksum: false
|
|
||||||
tags:
|
|
||||||
- os
|
|
||||||
- reboot
|
|
||||||
notify: reboot host
|
|
||||||
|
|
||||||
- name: All packages updated
|
- name: Prepare all docker hosted containers
|
||||||
apt:
|
hosts: docker_instance
|
||||||
name: "*"
|
|
||||||
state: latest # noqa 403
|
|
||||||
tags:
|
|
||||||
- apt
|
|
||||||
- update
|
|
||||||
- packages
|
|
||||||
become: true
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: Reboot host
|
|
||||||
reboot:
|
|
||||||
msg: "Reboot initiated by Ansible"
|
|
||||||
connect_timeout: 5
|
|
||||||
reboot_timeout: 600
|
|
||||||
pre_reboot_delay: 0
|
|
||||||
post_reboot_delay: 30
|
|
||||||
test_command: whoami
|
|
||||||
become: true
|
|
||||||
when: reboot_required_file.stat.exists
|
|
||||||
|
|
||||||
- name: Incus - Add package repository (apt)
|
|
||||||
hosts: all
|
|
||||||
gather_facts: true
|
|
||||||
gather_subset:
|
|
||||||
- "distribution_release"
|
|
||||||
vars:
|
|
||||||
task_release: "{{ incus_release | default('stable') }}"
|
|
||||||
task_roles: "{{ incus_roles | default(['standalone', 'ui']) }}"
|
|
||||||
any_errors_fatal: true
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Check if distribution is supported
|
- name: Set up Arr stack
|
||||||
meta: end_play
|
ansible.builtin.import_role:
|
||||||
when: 'ansible_distribution not in ("Ubuntu", "Debian")'
|
name: arr
|
||||||
|
tags: arr
|
||||||
- name: Create apt keyring path
|
|
||||||
file:
|
|
||||||
path: /etc/apt/keyrings/
|
|
||||||
mode: 0755
|
|
||||||
state: directory
|
|
||||||
when: 'task_roles|length > 0 and task_release != "distro"'
|
|
||||||
|
|
||||||
- name: Add Zabbly repository key
|
|
||||||
copy:
|
|
||||||
src: files/zabbly-key.asc
|
|
||||||
dest: /etc/apt/keyrings/ansible-zabbly.asc
|
|
||||||
notify: Update apt
|
|
||||||
become: true
|
|
||||||
when: 'task_roles|length > 0 and task_release != "distro"'
|
|
||||||
|
|
||||||
- name: Get DPKG architecture
|
|
||||||
shell: dpkg --print-architecture
|
|
||||||
register: dpkg_architecture
|
|
||||||
changed_when: false
|
|
||||||
check_mode: no
|
|
||||||
when: 'task_roles|length > 0 and task_release != "distro"'
|
|
||||||
|
|
||||||
- name: Add Zabbly package source
|
|
||||||
template:
|
|
||||||
src: files/incus.sources.tpl
|
|
||||||
dest: /etc/apt/sources.list.d/ansible-zabbly-incus-{{ task_release }}.sources
|
|
||||||
notify: Update apt
|
|
||||||
become: true
|
|
||||||
when: 'task_roles|length > 0 and task_release != "distro"'
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: Update apt
|
|
||||||
apt:
|
|
||||||
force_apt_get: yes
|
|
||||||
update_cache: yes
|
|
||||||
cache_valid_time: 0
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Incus - Install packages and bootstrap
|
|
||||||
hosts: all
|
|
||||||
gather_facts: true
|
|
||||||
gather_subset:
|
|
||||||
- "default_ipv4"
|
|
||||||
- "default_ipv6"
|
|
||||||
- "distribution_release"
|
|
||||||
vars:
|
|
||||||
task_init: "{{ incus_init | default('{}') }}"
|
|
||||||
task_ip_address: "{{ incus_ip_address | default(ansible_default_ipv6['address'] | default(ansible_default_ipv4['address'])) }}"
|
|
||||||
task_name: "{{ incus_name | default('') }}"
|
|
||||||
task_roles: "{{ incus_roles | default(['ui', 'standalone']) }}"
|
|
||||||
|
|
||||||
task_ovn_northbound: "{{ lookup('template', '../files/ovn/ovn-central.servers.tpl') | from_yaml | map('regex_replace', '^(.*)$', 'ssl:[\\1]:6641') | join(',') }}"
|
|
||||||
task_servers: "{{ lookup('template', 'files/incus.servers.tpl') | from_yaml | sort }}"
|
|
||||||
any_errors_fatal: true
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Install the Incus package (deb)
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- incus
|
|
||||||
install_recommends: no
|
|
||||||
state: present
|
|
||||||
register: install_deb
|
|
||||||
when: 'ansible_distribution in ("Debian", "Ubuntu") and task_roles | length > 0'
|
|
||||||
|
|
||||||
- name: Install the Incus package (rpm)
|
|
||||||
ansible.builtin.package:
|
|
||||||
name:
|
|
||||||
- incus
|
|
||||||
state: present
|
|
||||||
register: install_rpm
|
|
||||||
when: 'ansible_distribution == "CentOS" and task_roles | length > 0'
|
|
||||||
|
|
||||||
- name: Install the Incus UI package (deb)
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- incus-ui-canonical
|
|
||||||
install_recommends: no
|
|
||||||
state: present
|
|
||||||
when: 'ansible_distribution in ("Debian", "Ubuntu") and "ui" in task_roles'
|
|
||||||
|
|
||||||
# - name: Install btrfs tools
|
|
||||||
# ansible.builtin.package:
|
|
||||||
# name:
|
|
||||||
# - btrfs-progs
|
|
||||||
# state: present
|
|
||||||
# when: "task_roles | length > 0 and 'btrfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
|
||||||
#
|
|
||||||
# - name: Install ceph tools
|
|
||||||
# ansible.builtin.package:
|
|
||||||
# name:
|
|
||||||
# - ceph-common
|
|
||||||
# state: present
|
|
||||||
# when: "task_roles | length > 0 and 'ceph' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
|
||||||
#
|
|
||||||
# - name: Install LVM tools
|
|
||||||
# ansible.builtin.package:
|
|
||||||
# name:
|
|
||||||
# - lvm2
|
|
||||||
# state: present
|
|
||||||
# when: "task_roles | length > 0 and 'lvm' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
|
||||||
#
|
|
||||||
# - name: Install ZFS dependencies
|
|
||||||
# ansible.builtin.package:
|
|
||||||
# name:
|
|
||||||
# - zfs-dkms
|
|
||||||
# state: present
|
|
||||||
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver') and ansible_distribution == 'Debian'"
|
|
||||||
#
|
|
||||||
# - name: Install ZFS tools
|
|
||||||
# ansible.builtin.package:
|
|
||||||
# name:
|
|
||||||
# - zfsutils-linux
|
|
||||||
# state: present
|
|
||||||
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
|
||||||
|
|
||||||
- name: Set uid allocation
|
|
||||||
shell:
|
|
||||||
cmd: "usermod root --add-subuids 10000000-1009999999"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
|
|
||||||
|
|
||||||
- name: Set gid allocation
|
|
||||||
shell:
|
|
||||||
cmd: "usermod root --add-subgids 10000000-1009999999"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
|
|
||||||
|
|
||||||
- name: Enable incus socket unit
|
|
||||||
systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus.socket
|
|
||||||
state: started
|
|
||||||
when: 'install_deb.changed or install_rpm.changed'
|
|
||||||
|
|
||||||
- name: Enable incus service unit
|
|
||||||
systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus.service
|
|
||||||
state: started
|
|
||||||
when: 'install_deb.changed or install_rpm.changed'
|
|
||||||
|
|
||||||
- name: Enable incus startup unit
|
|
||||||
systemd:
|
|
||||||
enabled: true
|
|
||||||
name: incus-startup.service
|
|
||||||
state: started
|
|
||||||
when: 'install_deb.changed or install_rpm.changed'
|
|
||||||
|
|
||||||
- name: Set client listen address
|
|
||||||
shell:
|
|
||||||
cmd: "incus --force-local config set core.https_address {{ task_ip_address }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Set cluster listen address
|
|
||||||
shell:
|
|
||||||
cmd: "incus --force-local config set cluster.https_address {{ task_ip_address }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
|
|
||||||
|
|
||||||
# - name: Set OVN NorthBound database
|
|
||||||
# shell:
|
|
||||||
# cmd: "incus --force-local config set network.ovn.northbound_connection={{ task_ovn_northbound }} network.ovn.client_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.crt') }}\" network.ovn.client_key=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.key') }}\" network.ovn.ca_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/ca.crt') }}\""
|
|
||||||
# notify: Restart Incus
|
|
||||||
# when: '(install_deb.changed or install_rpm.changed) and task_ovn_northbound and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Add networks
|
|
||||||
shell:
|
|
||||||
cmd: "incus network create {{ item.key }} --type={{ item.value.type }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
|
|
||||||
loop: "{{ task_init['network'] | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Set network description
|
|
||||||
shell:
|
|
||||||
cmd: "incus network set --property {{ item.key }} description=\"{{ item.value.description }}\""
|
|
||||||
loop: "{{ task_init['network'] | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
|
|
||||||
|
|
||||||
- name: Add storage pools
|
|
||||||
shell:
|
|
||||||
cmd: "incus storage create {{ item.key }} {{ item.value.driver }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
|
|
||||||
loop: "{{ task_init['storage'] | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Set storage pool description
|
|
||||||
shell:
|
|
||||||
cmd: "incus storage set --property {{ item.key }} description=\"{{ item.value.description }}\""
|
|
||||||
loop: "{{ task_init['storage'] | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
|
|
||||||
|
|
||||||
- name: Add storage pool to default profile
|
|
||||||
shell:
|
|
||||||
cmd: "incus profile device add default root disk path=/ pool={{ item }}"
|
|
||||||
loop: "{{ task_init['storage'] | dict2items | json_query('[?value.default].key') }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Add network to default profile
|
|
||||||
shell:
|
|
||||||
cmd: "incus profile device add default eth0 nic network={{ item }} name=eth0"
|
|
||||||
loop: "{{ task_init['network'] | dict2items | json_query('[?value.default].key') }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Bootstrap the cluster
|
|
||||||
shell:
|
|
||||||
cmd: "incus --force-local cluster enable {{ inventory_hostname }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
|
|
||||||
|
|
||||||
- name: Create join tokens
|
|
||||||
delegate_to: "{{ task_servers[0] }}"
|
|
||||||
shell:
|
|
||||||
cmd: "incus --force-local --quiet cluster add {{ inventory_hostname }}"
|
|
||||||
register: cluster_add
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] != inventory_hostname'
|
|
||||||
|
|
||||||
- name: Wait 5s to avoid token use before valid
|
|
||||||
ansible.builtin.wait_for:
|
|
||||||
timeout: 5
|
|
||||||
delegate_to: localhost
|
|
||||||
when: 'cluster_add.changed'
|
|
||||||
|
|
||||||
- name: Join the cluster
|
|
||||||
throttle: 1
|
|
||||||
shell:
|
|
||||||
cmd: "incus --force-local admin init --preseed"
|
|
||||||
stdin: |-
|
|
||||||
cluster:
|
|
||||||
enabled: true
|
|
||||||
cluster_address: "{{ task_ip_address }}"
|
|
||||||
cluster_token: "{{ cluster_add.stdout }}"
|
|
||||||
server_address: "{{ task_ip_address }}"
|
|
||||||
member_config: {% for pool in task_init.storage %}{% for key in task_init.storage[pool].local_config | default([]) %}
|
|
||||||
|
|
||||||
- entity: storage-pool
|
|
||||||
name: {{ pool }}
|
|
||||||
key: {{ key }}
|
|
||||||
value: {{ task_init.storage[pool].local_config[key] }}{% endfor %}{% endfor %}{% for network in task_init.network %}{% for key in task_init.network[network].local_config | default([]) %}
|
|
||||||
|
|
||||||
- entity: network
|
|
||||||
name: {{ network }}
|
|
||||||
key: {{ key }}
|
|
||||||
value: {{ task_init.network[network].local_config[key] }}{% endfor %}{% endfor %}
|
|
||||||
when: 'cluster_add.changed'
|
|
||||||
|
|
||||||
- name: Apply additional configuration
|
|
||||||
shell:
|
|
||||||
cmd: "incus config set {{ item.key }}=\"{{ item.value }}\""
|
|
||||||
loop: "{{ task_init['config'] | default({}) | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
|
|
||||||
- name: Load client certificates
|
|
||||||
shell:
|
|
||||||
cmd: "incus config trust add-certificate --name \"{{ item.key }}\" --type={{ item.value.type | default('client') }} -"
|
|
||||||
stdin: "{{ item.value.certificate }}"
|
|
||||||
loop: "{{ task_init['clients'] | default({}) | dict2items }}"
|
|
||||||
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
|
||||||
handlers:
|
|
||||||
- name: Restart Incus
|
|
||||||
systemd:
|
|
||||||
name: incus.service
|
|
||||||
state: restarted
|
|
||||||
|
|
|
||||||
11
ansible/roles/arr/tasks/main.yaml
Normal file
11
ansible/roles/arr/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Deploy wallabag to swarm
|
||||||
|
community.general.docker_stack:
|
||||||
|
name: arr
|
||||||
|
state: present
|
||||||
|
prune: true
|
||||||
|
compose:
|
||||||
|
- "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}"
|
||||||
|
become: true
|
||||||
|
tags:
|
||||||
|
- docker-swarm
|
||||||
171
ansible/roles/arr/templates/arr.yml
Normal file
171
ansible/roles/arr/templates/arr.yml
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
services:
|
||||||
|
sonarr:
|
||||||
|
container_name: sonarr
|
||||||
|
image: lscr.io/linuxserver/sonarr:latest
|
||||||
|
ports:
|
||||||
|
- 8989:8989
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/sonarr:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
||||||
|
restart: unless-stopped
|
||||||
|
radarr:
|
||||||
|
container_name: radarr
|
||||||
|
image: lscr.io/linuxserver/radarr:latest
|
||||||
|
ports:
|
||||||
|
- 7878:7878
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/radarr:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
||||||
|
restart: unless-stopped
|
||||||
|
lidarr:
|
||||||
|
container_name: lidarr
|
||||||
|
image: lscr.io/linuxserver/lidarr:latest
|
||||||
|
ports:
|
||||||
|
- 8686:8686
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
- DOCKER_MODS=linuxserver/mods:universal-docker
|
||||||
|
volumes:
|
||||||
|
- "./config/lidarr:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
restart: unless-stopped
|
||||||
|
readarr:
|
||||||
|
container_name: readarr
|
||||||
|
image: lscr.io/linuxserver/readarr:develop
|
||||||
|
ports:
|
||||||
|
- 8787:8787
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/readarr:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
||||||
|
restart: unless-stopped
|
||||||
|
prowlarr:
|
||||||
|
container_name: prowlarr
|
||||||
|
image: lscr.io/linuxserver/prowlarr:develop
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/prowlarr:/config"
|
||||||
|
ports:
|
||||||
|
- 9696:9696
|
||||||
|
restart: unless-stopped
|
||||||
|
sabnzbd:
|
||||||
|
container_name: sabnzbd
|
||||||
|
image: lscr.io/linuxserver/sabnzbd:latest
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/sabnzbd:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/usenet:/data/usenet:rw"
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
restart: unless-stopped
|
||||||
|
pia-qbittorrent:
|
||||||
|
image: j4ym0/pia-qbittorrent
|
||||||
|
container_name: pia-qbittorrent
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
environment:
|
||||||
|
- UID=${PUID}
|
||||||
|
- GID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- REGION=Netherlands
|
||||||
|
- USER=${PIA_USER}
|
||||||
|
- PASSWORD=${PIA_PASS}
|
||||||
|
volumes:
|
||||||
|
- "./config/piaqbit:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/torrent:/downloads:rw"
|
||||||
|
ports:
|
||||||
|
- "8888:8888"
|
||||||
|
restart: unless-stopped
|
||||||
|
jellyfin:
|
||||||
|
image: lscr.io/linuxserver/jellyfin:latest
|
||||||
|
container_name: jellyfin
|
||||||
|
environment:
|
||||||
|
- PUID={$PUID}
|
||||||
|
- PGID={$PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
#- JELLYFIN_PublishedServerUrl=192.168.0.5 #optional
|
||||||
|
volumes:
|
||||||
|
- ".config/jellyfin:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/media:/data"
|
||||||
|
ports:
|
||||||
|
- 8096:8096
|
||||||
|
- 7359:7359/udp #optional - network discovery
|
||||||
|
- 1900:1900/udp #optional - dlna discovery
|
||||||
|
restart: unless-stopped
|
||||||
|
audiobookshelf:
|
||||||
|
container_name: audiobookshelf
|
||||||
|
image: ghcr.io/advplyr/audiobookshelf:latest
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- UMASK_SET=022
|
||||||
|
- TZ=${TZ}
|
||||||
|
ports:
|
||||||
|
- 13378:80
|
||||||
|
volumes:
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/books:/audiobooks"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/podcasts:/podcasts"
|
||||||
|
- ".config/audiobookshelf:/config"
|
||||||
|
- ".metadata/audiobookshelf:/metadata"
|
||||||
|
restart: unless-stopped
|
||||||
|
jellyseerr:
|
||||||
|
image: fallenbagel/jellyseerr:latest
|
||||||
|
container_name: jellyseerr
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
ports:
|
||||||
|
- 5055:5055
|
||||||
|
volumes:
|
||||||
|
- "./config/jellyseerr:/app/config"
|
||||||
|
restart: unless-stopped
|
||||||
|
beets:
|
||||||
|
image: lscr.io/linuxserver/beets:latest
|
||||||
|
container_name: beets
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- "./config/beets:/config"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/music:/music"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/music-unsorted:/downloads"
|
||||||
|
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
||||||
|
ports:
|
||||||
|
- 8337:8337
|
||||||
|
restart: unless-stopped
|
||||||
|
homarr:
|
||||||
|
image: ghcr.io/ajnart/homarr:latest
|
||||||
|
container_name: homarr
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
|
||||||
|
- ./config/homarr/configs:/app/data/configs
|
||||||
|
- ./config/homarr/icons:/app/public/icons
|
||||||
|
- ./config/homarr/data:/data
|
||||||
|
ports:
|
||||||
|
- '80:7575'
|
||||||
|
restart: unless-stopped
|
||||||
56
ansible/roles/incus-install/tasks/add-repo.yaml
Normal file
56
ansible/roles/incus-install/tasks/add-repo.yaml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
- name: Incus - Add package repository (apt)
|
||||||
|
hosts: all
|
||||||
|
gather_facts: true
|
||||||
|
gather_subset:
|
||||||
|
- "distribution_release"
|
||||||
|
vars:
|
||||||
|
task_release: "{{ incus_release | default('stable') }}"
|
||||||
|
task_roles: "{{ incus_roles | default(['standalone', 'ui']) }}"
|
||||||
|
any_errors_fatal: true
|
||||||
|
tasks:
|
||||||
|
- name: Check if distribution is supported
|
||||||
|
ansible.builtin.meta: end_play
|
||||||
|
when: 'ansible_distribution not in ("Ubuntu", "Debian")'
|
||||||
|
|
||||||
|
- name: Create apt keyring path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/keyrings/
|
||||||
|
mode: "0755"
|
||||||
|
state: directory
|
||||||
|
when: 'task_roles | length > 0 and task_release != "distro"'
|
||||||
|
|
||||||
|
- name: Add Zabbly repository key
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: files/zabbly-key.asc
|
||||||
|
dest: /etc/apt/keyrings/ansible-zabbly.asc
|
||||||
|
mode: "0644"
|
||||||
|
notify: Update apt
|
||||||
|
become: true
|
||||||
|
when: 'task_roles | length > 0 and task_release != "distro"'
|
||||||
|
|
||||||
|
- name: Get DPKG architecture
|
||||||
|
ansible.builtin.shell: dpkg --print-architecture
|
||||||
|
register: dpkg_architecture
|
||||||
|
changed_when: false
|
||||||
|
check_mode: false
|
||||||
|
when: 'task_roles | length > 0 and task_release != "distro"'
|
||||||
|
|
||||||
|
- name: Add Zabbly package source
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: files/incus.sources.tpl
|
||||||
|
dest: /etc/apt/sources.list.d/ansible-zabbly-incus-{{ task_release }}.sources
|
||||||
|
notify: Update apt
|
||||||
|
become: true
|
||||||
|
when: 'task_roles|length > 0 and task_release != "distro"'
|
||||||
|
|
||||||
|
- name: Handle apt by flushing handlers
|
||||||
|
meta: flush_handlers
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Update apt
|
||||||
|
ansible.builtin.apt:
|
||||||
|
force_apt_get: true
|
||||||
|
update_cache: true
|
||||||
|
cache_valid_time: 0
|
||||||
|
become: true
|
||||||
220
ansible/roles/incus-install/tasks/bootstrap.yaml
Normal file
220
ansible/roles/incus-install/tasks/bootstrap.yaml
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
---
|
||||||
|
- name: Incus - Install packages and bootstrap
|
||||||
|
hosts: all
|
||||||
|
gather_facts: true
|
||||||
|
gather_subset:
|
||||||
|
- "default_ipv4"
|
||||||
|
- "default_ipv6"
|
||||||
|
- "distribution_release"
|
||||||
|
vars:
|
||||||
|
task_init: "{{ incus_init | default('{}') }}"
|
||||||
|
task_ip_address: "{{ incus_ip_address | default(ansible_default_ipv6['address'] | default(ansible_default_ipv4['address'])) }}"
|
||||||
|
task_name: "{{ incus_name | default('') }}"
|
||||||
|
task_roles: "{{ incus_roles | default(['ui', 'standalone']) }}"
|
||||||
|
|
||||||
|
task_ovn_northbound: "{{ lookup('template', '../files/ovn/ovn-central.servers.tpl') | from_yaml | map('regex_replace', '^(.*)$', 'ssl:[\\1]:6641') | join(',') }}"
|
||||||
|
task_servers: "{{ lookup('template', 'files/incus.servers.tpl') | from_yaml | sort }}"
|
||||||
|
any_errors_fatal: true
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Install the Incus package (deb)
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- incus
|
||||||
|
install_recommends: no
|
||||||
|
state: present
|
||||||
|
register: install_deb
|
||||||
|
when: 'ansible_distribution in ("Debian", "Ubuntu") and task_roles | length > 0'
|
||||||
|
|
||||||
|
- name: Install the Incus package (rpm)
|
||||||
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- incus
|
||||||
|
state: present
|
||||||
|
register: install_rpm
|
||||||
|
when: 'ansible_distribution == "CentOS" and task_roles | length > 0'
|
||||||
|
|
||||||
|
- name: Install the Incus UI package (deb)
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- incus-ui-canonical
|
||||||
|
install_recommends: no
|
||||||
|
state: present
|
||||||
|
when: 'ansible_distribution in ("Debian", "Ubuntu") and "ui" in task_roles'
|
||||||
|
|
||||||
|
# - name: Install btrfs tools
|
||||||
|
# ansible.builtin.package:
|
||||||
|
# name:
|
||||||
|
# - btrfs-progs
|
||||||
|
# state: present
|
||||||
|
# when: "task_roles | length > 0 and 'btrfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
||||||
|
#
|
||||||
|
# - name: Install ceph tools
|
||||||
|
# ansible.builtin.package:
|
||||||
|
# name:
|
||||||
|
# - ceph-common
|
||||||
|
# state: present
|
||||||
|
# when: "task_roles | length > 0 and 'ceph' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
||||||
|
#
|
||||||
|
# - name: Install LVM tools
|
||||||
|
# ansible.builtin.package:
|
||||||
|
# name:
|
||||||
|
# - lvm2
|
||||||
|
# state: present
|
||||||
|
# when: "task_roles | length > 0 and 'lvm' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
||||||
|
#
|
||||||
|
# - name: Install ZFS dependencies
|
||||||
|
# ansible.builtin.package:
|
||||||
|
# name:
|
||||||
|
# - zfs-dkms
|
||||||
|
# state: present
|
||||||
|
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver') and ansible_distribution == 'Debian'"
|
||||||
|
#
|
||||||
|
# - name: Install ZFS tools
|
||||||
|
# ansible.builtin.package:
|
||||||
|
# name:
|
||||||
|
# - zfsutils-linux
|
||||||
|
# state: present
|
||||||
|
# when: "task_roles | length > 0 and 'zfs' in task_init['storage'] | dict2items | json_query('[].value.driver')"
|
||||||
|
|
||||||
|
- name: Set uid allocation
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "usermod root --add-subuids 10000000-1009999999"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
|
||||||
|
|
||||||
|
- name: Set gid allocation
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "usermod root --add-subgids 10000000-1009999999"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ansible_distribution == "CentOS"'
|
||||||
|
|
||||||
|
- name: Enable incus socket unit
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
enabled: true
|
||||||
|
name: incus.socket
|
||||||
|
state: started
|
||||||
|
when: "install_deb.changed or install_rpm.changed"
|
||||||
|
|
||||||
|
- name: Enable incus service unit
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
enabled: true
|
||||||
|
name: incus.service
|
||||||
|
state: started
|
||||||
|
when: "install_deb.changed or install_rpm.changed"
|
||||||
|
|
||||||
|
- name: Enable incus startup unit
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
enabled: true
|
||||||
|
name: incus-startup.service
|
||||||
|
state: started
|
||||||
|
when: "install_deb.changed or install_rpm.changed"
|
||||||
|
|
||||||
|
- name: Set client listen address
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus --force-local config set core.https_address {{ task_ip_address }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Set cluster listen address
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus --force-local config set cluster.https_address {{ task_ip_address }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
|
||||||
|
|
||||||
|
# - name: Set OVN NorthBound database
|
||||||
|
# shell:
|
||||||
|
# cmd: "incus --force-local config set network.ovn.northbound_connection={{ task_ovn_northbound }} network.ovn.client_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.crt') }}\" network.ovn.client_key=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/'+inventory_hostname+'.key') }}\" network.ovn.ca_cert=\"{{ lookup('file', '../data/ovn/'+ovn_name+'/ca.crt') }}\""
|
||||||
|
# notify: Restart Incus
|
||||||
|
# when: '(install_deb.changed or install_rpm.changed) and task_ovn_northbound and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Add networks
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus network create {{ item.key }} --type={{ item.value.type }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
|
||||||
|
loop: "{{ task_init['network'] | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Set network description
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: 'incus network set --property {{ item.key }} description="{{ item.value.description }}"'
|
||||||
|
loop: "{{ task_init['network'] | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
|
||||||
|
|
||||||
|
- name: Add storage pools
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus storage create {{ item.key }} {{ item.value.driver }}{% for k in item.value.local_config | default([]) %} {{ k }}={{ item.value.local_config[k] }}{% endfor %}{% for k in item.value.config | default([]) %} {{ k }}={{ item.value.config[k] }}{% endfor %}"
|
||||||
|
loop: "{{ task_init['storage'] | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Set storage pool description
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: 'incus storage set --property {{ item.key }} description="{{ item.value.description }}"'
|
||||||
|
loop: "{{ task_init['storage'] | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname)) and item.value.description | default(None)'
|
||||||
|
|
||||||
|
- name: Add storage pool to default profile
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus profile device add default root disk path=/ pool={{ item }}"
|
||||||
|
loop: "{{ task_init['storage'] | dict2items | json_query('[?value.default].key') }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Add network to default profile
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus profile device add default eth0 nic network={{ item }} name=eth0"
|
||||||
|
loop: "{{ task_init['network'] | dict2items | json_query('[?value.default].key') }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Bootstrap the cluster
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus --force-local cluster enable {{ inventory_hostname }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] == inventory_hostname'
|
||||||
|
|
||||||
|
- name: Create join tokens
|
||||||
|
delegate_to: "{{ task_servers[0] }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus --force-local --quiet cluster add {{ inventory_hostname }}"
|
||||||
|
register: cluster_add
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and "cluster" in task_roles and task_servers[0] != inventory_hostname'
|
||||||
|
|
||||||
|
- name: Wait 5s to avoid token use before valid
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
timeout: 5
|
||||||
|
delegate_to: localhost
|
||||||
|
when: "cluster_add.changed"
|
||||||
|
|
||||||
|
- name: Join the cluster
|
||||||
|
throttle: 1
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "incus --force-local admin init --preseed"
|
||||||
|
stdin: |-
|
||||||
|
cluster:
|
||||||
|
enabled: true
|
||||||
|
cluster_address: "{{ task_ip_address }}"
|
||||||
|
cluster_token: "{{ cluster_add.stdout }}"
|
||||||
|
server_address: "{{ task_ip_address }}"
|
||||||
|
member_config: {% for pool in task_init.storage %}{% for key in task_init.storage[pool].local_config | default([]) %}
|
||||||
|
|
||||||
|
- entity: storage-pool
|
||||||
|
name: {{ pool }}
|
||||||
|
key: {{ key }}
|
||||||
|
value: {{ task_init.storage[pool].local_config[key] }}{% endfor %}{% endfor %}{% for network in task_init.network %}{% for key in task_init.network[network].local_config | default([]) %}
|
||||||
|
|
||||||
|
- entity: network
|
||||||
|
name: {{ network }}
|
||||||
|
key: {{ key }}
|
||||||
|
value: {{ task_init.network[network].local_config[key] }}{% endfor %}{% endfor %}
|
||||||
|
when: "cluster_add.changed"
|
||||||
|
|
||||||
|
- name: Apply additional configuration
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: 'incus config set {{ item.key }}="{{ item.value }}"'
|
||||||
|
loop: "{{ task_init['config'] | default({}) | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
|
||||||
|
- name: Load client certificates
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: 'incus config trust add-certificate --name "{{ item.key }}" --type={{ item.value.type | default(''client'') }} -'
|
||||||
|
stdin: "{{ item.value.certificate }}"
|
||||||
|
loop: "{{ task_init['clients'] | default({}) | dict2items }}"
|
||||||
|
when: '(install_deb.changed or install_rpm.changed) and ("standalone" in task_roles or ("cluster" in task_roles and task_servers[0] == inventory_hostname))'
|
||||||
|
handlers:
|
||||||
|
- name: Restart Incus
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: incus.service
|
||||||
|
state: restarted
|
||||||
7
ansible/roles/incus-install/tasks/main.yaml
Normal file
7
ansible/roles/incus-install/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: "Add incus repository to system"
|
||||||
|
ansible.builtin.include_tasks: add-repo.yaml
|
||||||
|
|
||||||
|
# TODO: Should presumably be split
|
||||||
|
- name: "Install and bootstrap incus"
|
||||||
|
ansible.builtin.include_tasks: bootstrap.yaml
|
||||||
11
ansible/roles/system/handlers/main.yaml
Normal file
11
ansible/roles/system/handlers/main.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Reboot host
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: "Reboot initiated by Ansible"
|
||||||
|
connect_timeout: 5
|
||||||
|
reboot_timeout: 600
|
||||||
|
pre_reboot_delay: 0
|
||||||
|
post_reboot_delay: 30
|
||||||
|
test_command: whoami
|
||||||
|
become: true
|
||||||
|
when: reboot_required_file.stat.exists
|
||||||
38
ansible/roles/system/tasks/main.yaml
Normal file
38
ansible/roles/system/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
- name: Ensure aptitude installed
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "aptitude"
|
||||||
|
state: present
|
||||||
|
tags:
|
||||||
|
- apt
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Ensure OS upgraded
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
tags:
|
||||||
|
- apt
|
||||||
|
- update
|
||||||
|
- os
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Check if reboot is necessary
|
||||||
|
register: reboot_required_file
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/run/reboot-required
|
||||||
|
get_checksum: false
|
||||||
|
tags:
|
||||||
|
- os
|
||||||
|
- reboot
|
||||||
|
notify: Reboot host
|
||||||
|
|
||||||
|
- name: All system packages updated
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "*"
|
||||||
|
state: latest # noqa package-latest
|
||||||
|
tags:
|
||||||
|
- apt
|
||||||
|
- update
|
||||||
|
- packages
|
||||||
|
become: true
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue