From eb0a72430908429308c283494406582b7e433abf Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Sun, 4 May 2025 23:05:15 +0200 Subject: [PATCH 01/19] bank: Changes required for RevBank 10.0 --- roles/bank/tasks/revbank.yaml | 36 ++++++----------------------------- roles/bank/templates/git.cron | 2 +- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index ec283d1..73e770a 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -11,40 +11,16 @@ dest: /home/{{ bank_user }}/revbank.git accept_hostkey: yes -- name: Create data files - ansible.builtin.command: cp /home/{{ bank_user }}/revbank.git/{{ item }} /home/{{ bank_user }}/{{ item }} - args: - creates: /home/{{ bank_user }}/{{ item }} - with_items: - - revbank.accounts - - revbank.market - - revbank.products - -- name: Ensure data file permissions - ansible.builtin.file: - path: /home/{{ bank_user }}/{{ item }} - state: touch - owner: "{{ bank_user }}" - group: "{{ bank_user }}" - mode: 0644 - with_items: - - revbank.accounts - - revbank.market - - revbank.products - - name: Link plugins ansible.builtin.file: state: link - path: /home/{{ bank_user }}/{{ item }} - src: /home/{{ bank_user }}/revbank.git/{{ item }} + src: "{{ item.src }}" + path: "{{ item.dest }}" with_items: - - plugins - - revbank.plugins - -- name: Create git data dir - ansible.builtin.file: - path: /home/{{ bank_user }}/data.git - state: directory + - src: /home/{{ bank_user }}/revbank.git/plugins + dest: /home/{{ bank_user }}/plugins + - src: /home/{{ bank_user }}/revbank.git/data/plugins + dest: /home/{{ bank_user }}/.revbank/plugins - name: Install git cronjob ansible.builtin.template: diff --git a/roles/bank/templates/git.cron b/roles/bank/templates/git.cron index b334260..32308cf 100644 --- a/roles/bank/templates/git.cron +++ b/roles/bank/templates/git.cron @@ -1,4 +1,4 @@ SHELL=/bin/bash #m h dom mon dow user command - */10 * * * * {{ bank_user }} (cd /home/{{ bank_user }}/data.git && git pull -r && git push && git gc --auto && cp revbank.products ../revbank.products) + */10 * * * * {{ bank_user }} git -C ~/.revbank pull -r && git -C ~/.revbank push From a5930bb1aa8a39cf7aea847309c7fab0068c5837 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Sun, 4 May 2025 23:12:44 +0200 Subject: [PATCH 02/19] bank: qrencode is no longer needed --- roles/bank/tasks/revbank.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index 73e770a..5a0cf6c 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -1,7 +1,7 @@ --- - name: Install dependencies ansible.builtin.apt: - name: [ git, libterm-readline-gnu-perl, libcurses-ui-perl, qrencode ] + name: [ git, libterm-readline-gnu-perl, libcurses-ui-perl ] state: present - name: Clone revbank source From e65ffd5dc73fea19df70c43a1e2472156a84ae2e Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Mon, 5 May 2025 22:59:52 +0200 Subject: [PATCH 03/19] services/discord_bot: Some tweaks --- roles/services/tasks/discord_bot.yaml | 19 ++++++++----------- roles/services/templates/discord-bot.service | 3 ++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/roles/services/tasks/discord_bot.yaml b/roles/services/tasks/discord_bot.yaml index 19a659f..4d742f6 100644 --- a/roles/services/tasks/discord_bot.yaml +++ b/roles/services/tasks/discord_bot.yaml @@ -2,23 +2,14 @@ - name: Install dependencies ansible.builtin.apt: - name: - - python3-paho-mqtt - - python3-tz - - virtualenv + name: virtualenv - name: Create virtualenv ansible.builtin.command: - cmd: virtualenv /opt/miflora_exporter/.venv + cmd: virtualenv /var/lib/discord-bot/.venv args: creates: /var/lib/discord-bot/.venv -- name: Install Python dependencies - ansible.builtin.shell: - cmd: . .venv/bin/activate && pip install -r requirements.txt - args: - chdir: /var/lib/discord-bot - - name: Clone source ansible.builtin.git: repo: https://git.bitlair.nl/bitlair/discord-bot.git @@ -28,6 +19,12 @@ notify: Restart discord-bot ignore_errors: true +- name: Install Python dependencies + ansible.builtin.shell: + cmd: . .venv/bin/activate && pip install -r requirements.txt + args: + chdir: /var/lib/discord-bot + - name: Install service file ansible.builtin.template: src: discord-bot.service diff --git a/roles/services/templates/discord-bot.service b/roles/services/templates/discord-bot.service index 2c73d05..ccac806 100644 --- a/roles/services/templates/discord-bot.service +++ b/roles/services/templates/discord-bot.service @@ -1,4 +1,4 @@ -# Managed by Ansible +# {{ ansible_managed }} [Unit] Description=HobbyBot @@ -13,6 +13,7 @@ DynamicUser=true Environment="MQTT_HOST={{ mqtt_internal_host }}" Environment="DISCORD_WEBHOOK_URL={{ lookup('passwordstore', 'services/discord', subkey='webhook_url') }}" Environment="DISCORD_TOKEN={{ lookup('passwordstore', 'services/discord', subkey='token') }}" +Environment="BOTTLECLIP_GIT_TOKEN={{ lookup('passwordstore', 'services/discord', subkey='bottleclip_git_token') }}" [Install] WantedBy=multi-user.target From 2f9ca22e90d3f1ad558daafcd9e8be19162949d7 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Tue, 6 May 2025 18:25:31 +0200 Subject: [PATCH 04/19] bank: Use new REVBANK_PLUGINS env var --- roles/bank/tasks/login.yaml | 12 ++++++++++-- roles/bank/tasks/revbank.yaml | 13 +------------ roles/bank/templates/login.sh | 6 ++++++ 3 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 roles/bank/templates/login.sh diff --git a/roles/bank/tasks/login.yaml b/roles/bank/tasks/login.yaml index 7ed568e..24fe3e0 100644 --- a/roles/bank/tasks/login.yaml +++ b/roles/bank/tasks/login.yaml @@ -1,10 +1,18 @@ --- +- name: Install revbank login shell + ansible.builtin.template: + src: login.sh + dest: /usr/local/bin/revbank-login + owner: root + group: root + mode: "0755" + - name: Add user ansible.builtin.user: name: bank password: $6$idklol$QrOE/21LDR0vhZBAXwgA7AvnmR6Ju4ZqzAzgeazC08i2yw9kyQjgwu.uuV692iL/cyE7AteDYUxCpcorONXom. # "bank" home: /home/{{ bank_user }} - shell: /home/{{ bank_user }}/revbank.git/revbank + shell: /usr/local/bin/revbank-login update_password: always - name: Allow password auth for bank user @@ -13,7 +21,7 @@ insertafter: EOF validate: "/usr/sbin/sshd -t -f %s" block: |- - Match User bank + Match User {{ bank_user }} PasswordAuthentication yes notify: reload sshd diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index 5a0cf6c..1870ff1 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -8,20 +8,9 @@ ansible.builtin.git: repo: "{{ bank_revbank_git }}" version: master - dest: /home/{{ bank_user }}/revbank.git + dest: /usr/local/share/revbank accept_hostkey: yes -- name: Link plugins - ansible.builtin.file: - state: link - src: "{{ item.src }}" - path: "{{ item.dest }}" - with_items: - - src: /home/{{ bank_user }}/revbank.git/plugins - dest: /home/{{ bank_user }}/plugins - - src: /home/{{ bank_user }}/revbank.git/data/plugins - dest: /home/{{ bank_user }}/.revbank/plugins - - name: Install git cronjob ansible.builtin.template: src: git.cron diff --git a/roles/bank/templates/login.sh b/roles/bank/templates/login.sh new file mode 100644 index 0000000..6deaf2b --- /dev/null +++ b/roles/bank/templates/login.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export REVBANK_DIR=/usr/local/share/revbank +export REVBANK_PLUGINS="$(cat $REVBANK_DIR/data/plugins | sed 's/ *#.*$//g' | sed '/^$/d' | tr '\n' ' ')" + +$REVBANK_DIR/revbank From b9be1729b31ae22f3c96254893febf721002655a Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 7 May 2025 00:47:00 +0200 Subject: [PATCH 05/19] bank: RevBank 10.2 --- roles/bank/tasks/login.yaml | 10 +--------- roles/bank/tasks/revbank.yaml | 7 +++++++ roles/bank/templates/login.sh | 6 ------ 3 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 roles/bank/templates/login.sh diff --git a/roles/bank/tasks/login.yaml b/roles/bank/tasks/login.yaml index 24fe3e0..f54bbfd 100644 --- a/roles/bank/tasks/login.yaml +++ b/roles/bank/tasks/login.yaml @@ -1,18 +1,10 @@ --- -- name: Install revbank login shell - ansible.builtin.template: - src: login.sh - dest: /usr/local/bin/revbank-login - owner: root - group: root - mode: "0755" - - name: Add user ansible.builtin.user: name: bank password: $6$idklol$QrOE/21LDR0vhZBAXwgA7AvnmR6Ju4ZqzAzgeazC08i2yw9kyQjgwu.uuV692iL/cyE7AteDYUxCpcorONXom. # "bank" home: /home/{{ bank_user }} - shell: /usr/local/bin/revbank-login + shell: /usr/local/share/revbank/revbank update_password: always - name: Allow password auth for bank user diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index 1870ff1..e87f849 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -11,6 +11,13 @@ dest: /usr/local/share/revbank accept_hostkey: yes +- name: Clone revbank-plugin source + ansible.builtin.git: + repo: https://git.bitlair.nl/bitlair-bestuur/revbank-plugins.git + version: main + dest: /usr/local/share/revbank-plugins + accept_hostkey: yes + - name: Install git cronjob ansible.builtin.template: src: git.cron diff --git a/roles/bank/templates/login.sh b/roles/bank/templates/login.sh deleted file mode 100644 index 6deaf2b..0000000 --- a/roles/bank/templates/login.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -export REVBANK_DIR=/usr/local/share/revbank -export REVBANK_PLUGINS="$(cat $REVBANK_DIR/data/plugins | sed 's/ *#.*$//g' | sed '/^$/d' | tr '\n' ' ')" - -$REVBANK_DIR/revbank From 1b04d0f5c398627a53be6c1bdf7d73c4a8d9c0b1 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 7 May 2025 01:00:01 +0200 Subject: [PATCH 06/19] bank: RevBank 10.3 --- roles/bank/defaults/main.yaml | 2 +- roles/bank/tasks/revbank.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/bank/defaults/main.yaml b/roles/bank/defaults/main.yaml index b0fea92..d0a5ca6 100644 --- a/roles/bank/defaults/main.yaml +++ b/roles/bank/defaults/main.yaml @@ -1,3 +1,3 @@ bank_user: bank -bank_revbank_git: https://git.bitlair.nl/bitlair/revbank.git bank_local_tty: no +bank_revbank_version: "10.3.0" diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index e87f849..9f3f84c 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -6,8 +6,8 @@ - name: Clone revbank source ansible.builtin.git: - repo: "{{ bank_revbank_git }}" - version: master + repo: https://github.com/revspace/revbank.git + version: "v{{ bank_revbank_version }}" dest: /usr/local/share/revbank accept_hostkey: yes From 4f6025849f8215822c7e2be60cd3743126c71a49 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 7 May 2025 14:30:45 +0200 Subject: [PATCH 07/19] Update bitlair-plugin git upstream --- roles/bank/tasks/revbank.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/bank/tasks/revbank.yaml b/roles/bank/tasks/revbank.yaml index 9f3f84c..3b2ec65 100644 --- a/roles/bank/tasks/revbank.yaml +++ b/roles/bank/tasks/revbank.yaml @@ -13,7 +13,7 @@ - name: Clone revbank-plugin source ansible.builtin.git: - repo: https://git.bitlair.nl/bitlair-bestuur/revbank-plugins.git + repo: https://git.bitlair.nl/bitlair/revbank-plugins.git version: main dest: /usr/local/share/revbank-plugins accept_hostkey: yes From 3a0071abfa921de398aa751b9cabedefe2915b2d Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Fri, 9 May 2025 14:34:44 +0200 Subject: [PATCH 08/19] services/siahsd: Install from Debian package --- bitlair.yaml | 1 + group_vars/all.yaml | 2 ++ roles/services/tasks/siahsd.yaml | 19 ++++--------------- roles/services/templates/siahsd.conf | 25 ++----------------------- roles/services/templates/siahsd.service | 17 ----------------- services.yaml | 1 + 6 files changed, 10 insertions(+), 55 deletions(-) delete mode 100644 roles/services/templates/siahsd.service diff --git a/bitlair.yaml b/bitlair.yaml index b463ff7..950d555 100644 --- a/bitlair.yaml +++ b/bitlair.yaml @@ -58,6 +58,7 @@ - hosts: services roles: + - { role: "deb_forgejo", tags: [ "deb_forgejo" ] } - { role: "services", tags: ["services"] } - hosts: wiki diff --git a/group_vars/all.yaml b/group_vars/all.yaml index 39de4c0..0169ce1 100644 --- a/group_vars/all.yaml +++ b/group_vars/all.yaml @@ -37,5 +37,7 @@ debian_repourl: "http://deb.debian.org/debian/" debian_securityurl: "http://security.debian.org/debian-security" deb_forgejo_repos: + - host: git.bitlair.nl + owner: bitlair - host: git.polyfloyd.net owner: polyfloyd diff --git a/roles/services/tasks/siahsd.yaml b/roles/services/tasks/siahsd.yaml index c7c3b0b..fc7fef5 100644 --- a/roles/services/tasks/siahsd.yaml +++ b/roles/services/tasks/siahsd.yaml @@ -1,16 +1,15 @@ --- -# TODO: Install and build +- name: Install siahsd + apt: + name: siahsd - name: Create directories ansible.builtin.file: - path: "{{ item }}" + path: /var/log/siahsd state: directory owner: siahsd group: nogroup mode: "0750" - with_items: - - /var/log/siahsd - - /var/lib/siahsd - name: Install config file ansible.builtin.template: @@ -21,19 +20,9 @@ mode: "0644" notify: Restart siahsd -- name: Install service file - ansible.builtin.template: - src: siahsd.service - dest: /etc/systemd/system/siahsd.service - owner: root - group: root - mode: "0644" - notify: Restart siahsd - - name: Start siahsd ansible.builtin.systemd: name: siahsd state: started enabled: true daemon_reload: true - diff --git a/roles/services/templates/siahsd.conf b/roles/services/templates/siahsd.conf index 5d8e94f..ee18220 100644 --- a/roles/services/templates/siahsd.conf +++ b/roles/services/templates/siahsd.conf @@ -1,3 +1,5 @@ +# {{ ansible_managed }} + [siahsd] pid file = /var/lib/siahsd/siahsd.pid log file = /var/log/siahsd/siahsd.log @@ -5,13 +7,6 @@ log level = 3 foreground = 0 event handlers = script -#[database] -#driver = mysql -#host = localhost -#name = siahsd -#username = siahsd -#password = MysbJxAaawmwKPqD - [siahs] port = 4000 @@ -19,21 +14,5 @@ port = 4000 port = 9000 rsa key file = something.sexp -#[jsonbot] -#address = 192.168.88.15 -#port = 5500 -#aes key = blablablablablaz -#password = mekker -#privmsg to = #bitlair - -#[spacestate] -#driver = mysql -#host = localhost -#name = bitwifi -#username = bitwifi -#password = aGWERQpLEQPUaXJV -#open script = /opt/alarm/disarmed.sh -#close script = /opt/alarm/armed.sh - [script] path = /opt/alarm/siahsd_handler.sh diff --git a/roles/services/templates/siahsd.service b/roles/services/templates/siahsd.service deleted file mode 100644 index 479324c..0000000 --- a/roles/services/templates/siahsd.service +++ /dev/null @@ -1,17 +0,0 @@ -# Managed by Ansible - -[Unit] -Description=Siahsd -After=network.target - -[Service] -Type=forking -PIDFile=/var/lib/siahsd/siahsd.pid -Restart=always -RestartSec=10s -ExecStartPre=-/bin/rm /var/lib/siahsd/siahsd.pid -ExecStart=/usr/local/src/siahsd/build/siahsd -User=siahsd - -[Install] -WantedBy=multi-user.target diff --git a/services.yaml b/services.yaml index e66fc11..52103e0 100644 --- a/services.yaml +++ b/services.yaml @@ -3,4 +3,5 @@ - hosts: services roles: - { role: "common", tags: [ "common" ] } + - { role: "deb_forgejo", tags: [ "deb_forgejo" ] } - { role: "services", tags: [ "services" ] } From 1d8e07bf0468a7440d4c2d26a5e68020983ea9d8 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Fri, 9 May 2025 17:40:10 +0200 Subject: [PATCH 09/19] services/discord_bot: New bottle-clip implementation --- roles/services/tasks/discord_bot.yaml | 15 ++++++++++++--- roles/services/templates/discord-bot.service | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/roles/services/tasks/discord_bot.yaml b/roles/services/tasks/discord_bot.yaml index 4d742f6..3ce4308 100644 --- a/roles/services/tasks/discord_bot.yaml +++ b/roles/services/tasks/discord_bot.yaml @@ -2,7 +2,9 @@ - name: Install dependencies ansible.builtin.apt: - name: virtualenv + name: + - openscad + - virtualenv - name: Create virtualenv ansible.builtin.command: @@ -10,14 +12,21 @@ args: creates: /var/lib/discord-bot/.venv -- name: Clone source +- name: Clone bottleclip source + ansible.builtin.git: + repo: https://git.bitlair.nl/bitlair/bottle-clip.git + version: main + dest: /var/lib/bottle-clip + accept_hostkey: yes + notify: Restart discord-bot + +- name: Clone discord-bot source ansible.builtin.git: repo: https://git.bitlair.nl/bitlair/discord-bot.git version: main dest: /var/lib/discord-bot accept_hostkey: yes notify: Restart discord-bot - ignore_errors: true - name: Install Python dependencies ansible.builtin.shell: diff --git a/roles/services/templates/discord-bot.service b/roles/services/templates/discord-bot.service index ccac806..7522fd9 100644 --- a/roles/services/templates/discord-bot.service +++ b/roles/services/templates/discord-bot.service @@ -13,7 +13,7 @@ DynamicUser=true Environment="MQTT_HOST={{ mqtt_internal_host }}" Environment="DISCORD_WEBHOOK_URL={{ lookup('passwordstore', 'services/discord', subkey='webhook_url') }}" Environment="DISCORD_TOKEN={{ lookup('passwordstore', 'services/discord', subkey='token') }}" -Environment="BOTTLECLIP_GIT_TOKEN={{ lookup('passwordstore', 'services/discord', subkey='bottleclip_git_token') }}" +Environment="BOTTLECLIP_RESOURCES=/var/lib/bottle-clip" [Install] WantedBy=multi-user.target From 301529271dfdf6ab4be82a5c2d8d2788e1acbc13 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 17:40:30 +0200 Subject: [PATCH 10/19] music: Use nginx role --- group_vars/music.yaml | 4 ++ music.yaml | 2 +- roles/music/tasks/main.yaml | 9 ---- roles/music/templates/nginx-site.conf | 70 --------------------------- snippets/music-nginx.j2 | 49 +++++++++++++++++++ 5 files changed, 54 insertions(+), 80 deletions(-) delete mode 100644 roles/music/templates/nginx-site.conf create mode 100644 snippets/music-nginx.j2 diff --git a/group_vars/music.yaml b/group_vars/music.yaml index 8f0cc7c..457597a 100644 --- a/group_vars/music.yaml +++ b/group_vars/music.yaml @@ -11,6 +11,10 @@ root_access: - polyfloyd nginx_client_max_body_size: 512M +nginx_sites: + - server_name: "music.bitlair.nl" + snippets: + - "music-nginx.j2" music_domain: music.bitlair.nl acme_san_domains: diff --git a/music.yaml b/music.yaml index 17666f3..015c769 100644 --- a/music.yaml +++ b/music.yaml @@ -6,5 +6,5 @@ - { role: "acme", tags: [ "acme" ] } - { role: "deb_forgejo", tags: [ "deb_forgejo" ] } - { role: "go", tags: [ "go" ] } -# - { role: "nginx", tags: [ "nginx" ] } + - { role: "nginx", tags: [ "nginx" ] } - { role: "music", tags: [ "music" ] } diff --git a/roles/music/tasks/main.yaml b/roles/music/tasks/main.yaml index e8a751c..537746a 100644 --- a/roles/music/tasks/main.yaml +++ b/roles/music/tasks/main.yaml @@ -23,12 +23,3 @@ file: soundboard.yaml tags: - music_soundboard - -- name: Install nginx config - ansible.builtin.template: - src: nginx-site.conf - dest: /etc/nginx/sites-enabled/trollibox - owner: root - group: root - mode: 0644 - notify: Reload nginx diff --git a/roles/music/templates/nginx-site.conf b/roles/music/templates/nginx-site.conf deleted file mode 100644 index 185d689..0000000 --- a/roles/music/templates/nginx-site.conf +++ /dev/null @@ -1,70 +0,0 @@ -# {{ ansible_managed }} - -server { - listen 80 default_server; - listen [::]:80 default_server; - listen 443 ssl default_server; - listen [::]:443 ssl default_server; - - server_name {{ music_domain }}; - - {% if acme_bootstrap_certs %} - include "snippets/snakeoil.conf"; - {% else %} - ssl_certificate "/var/lib/dehydrated/certs/{{ music_domain }}/fullchain.pem"; - ssl_certificate_key "/var/lib/dehydrated/certs/{{ music_domain }}/privkey.pem"; - {% endif %} - - {% for range in trusted_ranges %} - allow {{ range.cidr }}; - {% endfor %} - deny all; - - location / { - rewrite ^/(.*) https://{{ music_domain }}/trollibox/player/space?; - } - - location /trollibox/ { - proxy_pass http://[::1]:3000/; - client_max_body_size 512M; - include proxy_params; - } - - location ~ ^/trollibox/(.+/events)$ { - proxy_pass http://[::1]:3000/$1; - include proxy_params; - proxy_http_version 1.1; - chunked_transfer_encoding off; - add_header X-Test "123"; - proxy_set_header Connection ''; - proxy_buffering off; - proxy_read_timeout 7d; - } - - location ~ ^/trollibox/(.+/listen)$ { - proxy_pass http://[::1]:3000/$1; - include proxy_params; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_read_timeout 7d; - } - - location /bobdsp/ { - proxy_pass http://[::1]:8081/; - include proxy_params; - } - - location /vis/ { - allow all; - proxy_pass http://[::1]:13378/; - include proxy_params; - } - - location = /vis/ { - rewrite ^(.*)$ /vis/index.html; - include proxy_params; - } - - include "snippets/acme.conf"; -} diff --git a/snippets/music-nginx.j2 b/snippets/music-nginx.j2 new file mode 100644 index 0000000..d179b23 --- /dev/null +++ b/snippets/music-nginx.j2 @@ -0,0 +1,49 @@ +{% for range in trusted_ranges %} +allow {{ range.cidr }}; +{% endfor %} +deny all; + +location / { + rewrite ^/(.*) https://{{ music_domain }}/trollibox/player/space?; +} + +location /trollibox/ { + proxy_pass http://[::1]:3000/; + include proxy_params; +} + +location ~ ^/trollibox/(.+/events)$ { + proxy_pass http://[::1]:3000/$1; + include proxy_params; + proxy_http_version 1.1; + chunked_transfer_encoding off; + add_header X-Test "123"; + proxy_set_header Connection ''; + proxy_buffering off; + proxy_read_timeout 7d; +} + +location ~ ^/trollibox/(.+/listen)$ { + proxy_pass http://[::1]:3000/$1; + include proxy_params; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 7d; +} + +location /bobdsp/ { + proxy_pass http://[::1]:8081/; + include proxy_params; +} + +location /vis/ { + allow all; + proxy_pass http://[::1]:13378/; + include proxy_params; +} + +location = /vis/ { + rewrite ^(.*)$ /vis/index.html; + include proxy_params; +} From e082523484c1a4752ddc531d0088337144e53593 Mon Sep 17 00:00:00 2001 From: Mark Janssen -- Sig-I/O Automatisering Date: Wed, 14 May 2025 20:03:42 +0200 Subject: [PATCH 11/19] 389-ldap --- group_vars/ldap.yaml | 4 ++++ roles/389-ldap/tasks/main.yaml | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 group_vars/ldap.yaml create mode 100644 roles/389-ldap/tasks/main.yaml diff --git a/group_vars/ldap.yaml b/group_vars/ldap.yaml new file mode 100644 index 0000000..53187b1 --- /dev/null +++ b/group_vars/ldap.yaml @@ -0,0 +1,4 @@ +--- + +group_nft_input: + - "tcp dport { ldap, ldaps } accept # Allow LDAP traffic" diff --git a/roles/389-ldap/tasks/main.yaml b/roles/389-ldap/tasks/main.yaml new file mode 100644 index 0000000..eaf4383 --- /dev/null +++ b/roles/389-ldap/tasks/main.yaml @@ -0,0 +1,9 @@ +--- + +- name: Install packages + ansible.builtin.apt: + state: present + pkg: + - 389-ds-base + - shelldap + From 43075d27fea1a786ff04bbd8f0cc6ab84d5d7f88 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 19:57:30 +0200 Subject: [PATCH 12/19] music/librespot: Various tweaks * Use pulseaudio backend * Run as separate librespot user * Use linear volume mixer --- roles/music/defaults/main.yaml | 3 +++ roles/music/handlers/main.yaml | 6 +++--- roles/music/tasks/librespot.yaml | 19 ++++++++++++------- roles/music/templates/librespot.service | 9 ++++----- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/roles/music/defaults/main.yaml b/roles/music/defaults/main.yaml index fa95b47..5db2f4c 100644 --- a/roles/music/defaults/main.yaml +++ b/roles/music/defaults/main.yaml @@ -1,2 +1,5 @@ music_audio_user: audio +music_audio_group: audio +music_librespot_user: librespot + music_mqtt_mpd_volume: bitlair/music/space/volume diff --git a/roles/music/handlers/main.yaml b/roles/music/handlers/main.yaml index 2d77dbb..faf76f9 100644 --- a/roles/music/handlers/main.yaml +++ b/roles/music/handlers/main.yaml @@ -8,13 +8,13 @@ state: restarted daemon_reload: true -- name: Rebuild librespot +- name: rebuild librespot ansible.builtin.command: - cmd: /root/.cargo/bin/cargo build --release --features jackaudio-backend + cmd: /root/.cargo/bin/cargo build --release --features pulseaudio-backend args: chdir: /opt/librespot -- name: Restart librespot +- name: restart librespot ansible.builtin.systemd: name: librespot state: restarted diff --git a/roles/music/tasks/librespot.yaml b/roles/music/tasks/librespot.yaml index 2a8d19b..9d062ce 100644 --- a/roles/music/tasks/librespot.yaml +++ b/roles/music/tasks/librespot.yaml @@ -1,8 +1,11 @@ --- -- name: Install dependencies - ansible.builtin.apt: - name: libjack-jackd2-dev - state: present +- name: Create librespot user + user: + name: "{{ music_librespot_user }}" + system: true + home: /var/lib/librespot + groups: + - "{{ music_audio_group }}" - name: Clone librespot source ansible.builtin.git: @@ -11,8 +14,8 @@ dest: /opt/librespot accept_hostkey: yes notify: - - Rebuild librespot - - Restart librespot + - rebuild librespot + - restart librespot - name: Install service file ansible.builtin.template: @@ -21,7 +24,7 @@ owner: root group: root mode: 0644 - notify: Restart librespot + notify: restart librespot - name: Enable Librespot ansible.builtin.systemd: @@ -29,3 +32,5 @@ state: started enabled: true daemon_reload: true + +- meta: flush_handlers diff --git a/roles/music/templates/librespot.service b/roles/music/templates/librespot.service index 8d3b683..c6d8c4a 100644 --- a/roles/music/templates/librespot.service +++ b/roles/music/templates/librespot.service @@ -3,16 +3,15 @@ [Unit] Description=Spotify through Librespot After=network.target -Requires=jackd.service [Service] Type=simple Restart=always RestartSec=2s -ExecStart=/opt/librespot/target/release/librespot --name Trollibox --backend jackaudio -User={{ music_audio_user }} -Group={{ music_audio_user }} -AmbientCapabilities=CAP_IPC_LOCK,CAP_SYS_NICE +ExecStart=/opt/librespot/target/release/librespot --name Trollibox --backend pulseaudio --volume-ctrl linear +Environment="PULSE_SERVER=/tmp/pipewire-pulse-socket" +Environment="XDG_RUNTIME_DIR=/run/user/0" +User={{ music_librespot_user }} [Install] WantedBy=multi-user.target From 7cd44bbe53622c6569eda33aeee8b1dde356ea3f Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 21:26:36 +0200 Subject: [PATCH 13/19] music: Add MPD --- roles/music/handlers/main.yaml | 6 +++++ roles/music/tasks/mpd.yaml | 37 +++++++++++++++++++++++----- roles/music/templates/mpd.conf | 40 +++++++++++++++++++++++++++++++ roles/music/templates/mpd.service | 21 ++++++++++++++++ roles/music/templates/mpd_state | 17 +++++++++++++ 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 roles/music/templates/mpd.conf create mode 100644 roles/music/templates/mpd.service create mode 100644 roles/music/templates/mpd_state diff --git a/roles/music/handlers/main.yaml b/roles/music/handlers/main.yaml index faf76f9..19193d6 100644 --- a/roles/music/handlers/main.yaml +++ b/roles/music/handlers/main.yaml @@ -2,6 +2,12 @@ - ansible.builtin.import_tasks: file: ../../common/handlers/main.yaml +- name: restart mpd + ansible.builtin.systemd: + name: mpd + state: restarted + daemon_reload: true + - name: Restart trollibox ansible.builtin.systemd: name: trollibox diff --git a/roles/music/tasks/mpd.yaml b/roles/music/tasks/mpd.yaml index eb88133..317df4e 100644 --- a/roles/music/tasks/mpd.yaml +++ b/roles/music/tasks/mpd.yaml @@ -1,14 +1,32 @@ --- - - name: Install MPD ansible.builtin.apt: - name: - - jackd - - mpd - - python3-mpd - - python3-serial + name: mpd state: present +- name: Add mpd user to the {{ music_audio_group }} group + user: + name: mpd + groups: + - "{{ music_audio_group }}" + notify: restart mpd + +- name: Install mpd file + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + notify: restart mpd + with_items: + - src: mpd.conf + dest: /etc/mpd.conf + - src: mpd.service + dest: /etc/systemd/system/mpd.service + - src: mpd_state + dest: /var/lib/mpd/state.default + - name: Install mpd-volume-to-mqtt script ansible.builtin.template: src: mpd-volume-to-mqtt.sh @@ -34,6 +52,13 @@ enabled: true daemon_reload: true +- name: Install skipbutton depedencies + ansible.builtin.apt: + name: + - python3-mpd + - python3-serial + state: present + - name: Clone skipbutton source ansible.builtin.git: repo: https://github.com/bitlair/skipbutton.git diff --git a/roles/music/templates/mpd.conf b/roles/music/templates/mpd.conf new file mode 100644 index 0000000..efa28f7 --- /dev/null +++ b/roles/music/templates/mpd.conf @@ -0,0 +1,40 @@ +# {{ ansible_managed }} + +user "mpd" +group "{{ music_audio_group }}" + +bind_to_address "any" +port "6600" +max_connections "20" + +zeroconf_enabled "yes" +zeroconf_name "MPD @ %h" + +music_directory "/srv/media/music" +auto_update "yes" +filesystem_charset "UTF-8" + +playlist_directory "/var/lib/mpd/playlists" +db_file "/var/lib/mpd/tag_cache" +state_file "/var/lib/mpd/state" +sticker_file "/var/lib/mpd/sticker.sql" + +input { + plugin "curl" # Required for web streams. +} + +decoder { + plugin "hybrid_dsd" + enabled "no" +} + +decoder { + plugin "wildmidi" + enabled "no" +} + +audio_output { + type "pulse" + name "Pulse" + server "/tmp/pipewire-pulse-socket" +} diff --git a/roles/music/templates/mpd.service b/roles/music/templates/mpd.service new file mode 100644 index 0000000..fb9808d --- /dev/null +++ b/roles/music/templates/mpd.service @@ -0,0 +1,21 @@ +# {{ ansible_managed }} + +[Unit] +Description=Music Player Daemon +After=network.target + +[Service] +Type=simple +ExecStartPre=/bin/mkdir -p /run/mpd +ExecStartPre=/bin/chown -R mpd:nogroup /run/mpd +ExecStartPre=/bin/touch /var/log/mpd.log +ExecStartPre=/bin/chown mpd:nogroup /var/log/mpd.log +ExecStartPre=/usr/bin/cp /var/lib/mpd/state.default /var/lib/mpd/state +ExecStart=/usr/bin/mpd --no-daemon /etc/mpd.conf +# MDP will fork itself to the user defined in its config +User=root +LimitMEMLOCK=infinity +LimitRTPRIO=99 + +[Install] +WantedBy=multi-user.target diff --git a/roles/music/templates/mpd_state b/roles/music/templates/mpd_state new file mode 100644 index 0000000..27b059b --- /dev/null +++ b/roles/music/templates/mpd_state @@ -0,0 +1,17 @@ +sw_volume: 20 +audio_device_state:1:Pulse +state: play +current: 0 +time: 0 +random: 0 +repeat: 0 +single: 0 +consume: 0 +crossfade: 0 +mixrampdb: 0.000000 +mixrampdelay: -1.000000 +playlist_begin +song_begin: http://ice4.somafm.com/groovesalad-256-mp3 +Name: SomaFM Groove Salad +song_end +playlist_end From 69278069729972162dd8a58a33a2f4dd3062ca53 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 23:45:03 +0200 Subject: [PATCH 14/19] music: Add the base audio server --- roles/music/defaults/main.yaml | 2 ++ roles/music/tasks/base.yaml | 42 +++++++++++++++++++++++++ roles/music/tasks/main.yaml | 5 +++ roles/music/templates/librespot.service | 3 +- roles/music/templates/mpd.conf | 2 +- 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 roles/music/tasks/base.yaml diff --git a/roles/music/defaults/main.yaml b/roles/music/defaults/main.yaml index 5db2f4c..40cc34e 100644 --- a/roles/music/defaults/main.yaml +++ b/roles/music/defaults/main.yaml @@ -2,4 +2,6 @@ music_audio_user: audio music_audio_group: audio music_librespot_user: librespot +music_pulse_server: /tmp/pipewire-pulse-socket + music_mqtt_mpd_volume: bitlair/music/space/volume diff --git a/roles/music/tasks/base.yaml b/roles/music/tasks/base.yaml new file mode 100644 index 0000000..a17d7d3 --- /dev/null +++ b/roles/music/tasks/base.yaml @@ -0,0 +1,42 @@ +--- +- name: Install pipewire + apt: + name: + - pipewire + - pipewire-jack + - pipewire-pulse + - pulseaudio-utils + - pulsemixer + state: present + +- name: Add audio group + group: + name: audio + system: true + +- name: Set PULSE_SERVER env var for all shells + copy: + dest: /etc/profile.d/pulse-server.sh + content: |+ + # Ansible managed + export PULSE_SERVER={{ music_pulse_server }} + +- name: Create pipewire-pulse config dir + file: + path: /etc/pipewire/pipewire-pulse.conf.d/ + state: directory + +- name: Configure system socket + ansible.builtin.copy: + dest: /etc/pipewire/pipewire-pulse.conf.d/system-socket.conf + content: |+ + # Ansible managed + context.exec = [ + { path = "/bin/chgrp" args = "{{ music_audio_group }} {{ music_pulse_server }}" } + { path = "/bin/chmod" args = "g+rwx,o-rwx {{ music_pulse_server }}" } + ] + pulse.properties = { + server.address = [ + "unix:{{ music_pulse_server }}" + ] + } diff --git a/roles/music/tasks/main.yaml b/roles/music/tasks/main.yaml index 537746a..e8105ee 100644 --- a/roles/music/tasks/main.yaml +++ b/roles/music/tasks/main.yaml @@ -1,4 +1,9 @@ --- +- name: Import base + ansible.builtin.import_tasks: + file: base.yaml + tags: + - music_base - name: Import mpd ansible.builtin.import_tasks: diff --git a/roles/music/templates/librespot.service b/roles/music/templates/librespot.service index c6d8c4a..e90c3cb 100644 --- a/roles/music/templates/librespot.service +++ b/roles/music/templates/librespot.service @@ -9,8 +9,7 @@ Type=simple Restart=always RestartSec=2s ExecStart=/opt/librespot/target/release/librespot --name Trollibox --backend pulseaudio --volume-ctrl linear -Environment="PULSE_SERVER=/tmp/pipewire-pulse-socket" -Environment="XDG_RUNTIME_DIR=/run/user/0" +Environment="PULSE_SERVER={{ music_pulse_server }}" User={{ music_librespot_user }} [Install] diff --git a/roles/music/templates/mpd.conf b/roles/music/templates/mpd.conf index efa28f7..6906e54 100644 --- a/roles/music/templates/mpd.conf +++ b/roles/music/templates/mpd.conf @@ -36,5 +36,5 @@ decoder { audio_output { type "pulse" name "Pulse" - server "/tmp/pipewire-pulse-socket" + server "{{ music_pulse_server }}" } From 64ffeeb5128f02115871aab53603e65db4844646 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 23:52:52 +0200 Subject: [PATCH 15/19] music: Remove skipbutton service --- roles/music/tasks/mpd.yaml | 31 ------------------------ roles/music/templates/skipbutton.service | 17 ------------- 2 files changed, 48 deletions(-) delete mode 100644 roles/music/templates/skipbutton.service diff --git a/roles/music/tasks/mpd.yaml b/roles/music/tasks/mpd.yaml index 317df4e..ebf2406 100644 --- a/roles/music/tasks/mpd.yaml +++ b/roles/music/tasks/mpd.yaml @@ -51,34 +51,3 @@ state: started enabled: true daemon_reload: true - -- name: Install skipbutton depedencies - ansible.builtin.apt: - name: - - python3-mpd - - python3-serial - state: present - -- name: Clone skipbutton source - ansible.builtin.git: - repo: https://github.com/bitlair/skipbutton.git - version: master - dest: /opt/skipbutton - accept_hostkey: yes - notify: Restart skipbutton - -- name: Install skipbutton service - ansible.builtin.template: - src: skipbutton.service - dest: /etc/systemd/system/skipbutton.service - owner: root - group: root - mode: 0644 - notify: Restart skipbutton - -- name: Enable skipbutton - ansible.builtin.systemd: - name: skipbutton - state: started - enabled: true - daemon_reload: true diff --git a/roles/music/templates/skipbutton.service b/roles/music/templates/skipbutton.service deleted file mode 100644 index f2a5d6f..0000000 --- a/roles/music/templates/skipbutton.service +++ /dev/null @@ -1,17 +0,0 @@ -# {{ ansible_managed }} - -[Unit] -Description=MPD Skipbutton -After=network.target -Requires=mpd.service - -[Service] -Type=simple -Restart=always -RestartSec=10s -ExecStart=/opt/skipbutton/skipbutton.py /dev/ttyS0 -DynamicUser=true -Group=dialout - -[Install] -WantedBy=multi-user.target From 949cdbe7bcd623f5065f0774d06c13dd76732361 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 23:53:22 +0200 Subject: [PATCH 16/19] music: Install wireplumber --- roles/music/tasks/base.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/music/tasks/base.yaml b/roles/music/tasks/base.yaml index a17d7d3..7961b70 100644 --- a/roles/music/tasks/base.yaml +++ b/roles/music/tasks/base.yaml @@ -7,6 +7,7 @@ - pipewire-pulse - pulseaudio-utils - pulsemixer + - wireplumber state: present - name: Add audio group From e9f31417b7903463fea97657fde725bcb7812639 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Wed, 14 May 2025 23:53:40 +0200 Subject: [PATCH 17/19] music: Fix mpd-volume-to-mqtt --- roles/music/templates/mpd-volume-to-mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/music/templates/mpd-volume-to-mqtt.sh b/roles/music/templates/mpd-volume-to-mqtt.sh index ac3230b..5f89374 100644 --- a/roles/music/templates/mpd-volume-to-mqtt.sh +++ b/roles/music/templates/mpd-volume-to-mqtt.sh @@ -14,7 +14,7 @@ prev_volume=x if [ $event = "mixer" ]; then volume=`mpc volume | sed -nr 's/^volume: ([0-9]+)%$/\1/p'` if [ "$prev_volume" != "$volume" ]; then - mqtt-simple -h {{ mqtt_internal_host }} -p '{{ music_mqtt_mpd_volume }} -r' -m "$volume" + mqtt-simple -h {{ mqtt_internal_host }} -p '{{ music_mqtt_mpd_volume }}' -r -m "$volume" fi prev_volume=$volume fi From 8e5b9f6b30955d536612de12b28700aa1ffadd24 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Fri, 16 May 2025 17:35:47 +0200 Subject: [PATCH 18/19] music/trollibox: Run as a distinct user --- roles/music/defaults/main.yaml | 1 + roles/music/handlers/main.yaml | 2 +- roles/music/tasks/trollibox.yaml | 30 ++++++++++++++++--------- roles/music/templates/trollibox.service | 3 +-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/roles/music/defaults/main.yaml b/roles/music/defaults/main.yaml index 40cc34e..d08ae0b 100644 --- a/roles/music/defaults/main.yaml +++ b/roles/music/defaults/main.yaml @@ -1,6 +1,7 @@ music_audio_user: audio music_audio_group: audio music_librespot_user: librespot +music_trollibox_user: trollibox music_pulse_server: /tmp/pipewire-pulse-socket diff --git a/roles/music/handlers/main.yaml b/roles/music/handlers/main.yaml index 19193d6..d4465ab 100644 --- a/roles/music/handlers/main.yaml +++ b/roles/music/handlers/main.yaml @@ -8,7 +8,7 @@ state: restarted daemon_reload: true -- name: Restart trollibox +- name: restart trollibox ansible.builtin.systemd: name: trollibox state: restarted diff --git a/roles/music/tasks/trollibox.yaml b/roles/music/tasks/trollibox.yaml index 0b20b4a..34b3df2 100644 --- a/roles/music/tasks/trollibox.yaml +++ b/roles/music/tasks/trollibox.yaml @@ -1,4 +1,10 @@ --- +- name: Create trollibox user + user: + name: "{{ music_trollibox_user }}" + system: true + home: /var/lib/trollibox + - name: Install Trollibox config ansible.builtin.template: src: trollibox.yaml @@ -6,27 +12,29 @@ owner: root group: root mode: "0644" - notify: Restart trollibox + notify: restart trollibox - name: Get latest Trollibox version from Github API - ansible.builtin.get_url: + uri: url: "https://api.github.com/repos/polyfloyd/trollibox/releases/latest" - dest: "/tmp/_ansible_trollibox_latest_release.json" + return_content: true + register: response + changed_when: false + check_mode: false + failed_when: "response is failed or 'json' not in response" -- name: Get download url - ansible.builtin.shell: - cmd: cat /tmp/_ansible_trollibox_latest_release.json | jq .assets[] | select(.name - | contains("linux-amd64")) | .browser_download_url -r - register: "trollibox_download_url" +- name: Format trollibox latest version + set_fact: + trollibox_version: "{{ response['json']['tag_name'] | trim('v') }}" - name: Download Trollibox ansible.builtin.unarchive: - src: "{{ trollibox_download_url.stdout }}" + src: "https://github.com/polyfloyd/trollibox/releases/download/v{{ trollibox_version }}/trollibox-x86_64-unknown-linux-gnu.tar.gz" remote_src: yes dest: /usr/local/bin include: [ trollibox ] mode: "0755" - notify: Restart trollibox + notify: restart trollibox - name: Install service file ansible.builtin.template: @@ -35,7 +43,7 @@ owner: root group: root mode: "0644" - notify: Restart trollibox + notify: restart trollibox - name: Enable Trollibox ansible.builtin.systemd: diff --git a/roles/music/templates/trollibox.service b/roles/music/templates/trollibox.service index ddddd2f..66d581d 100644 --- a/roles/music/templates/trollibox.service +++ b/roles/music/templates/trollibox.service @@ -10,8 +10,7 @@ Type=simple Restart=always RestartSec=2s ExecStart=/usr/local/bin/trollibox -conf /etc/trollibox.yaml -User={{ music_audio_user }} -Group={{ music_audio_user }} +User={{ music_trollibox_user }} [Install] WantedBy=multi-user.target From 82739c1ff071fb6a16df972024c70c082cb52224 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Fri, 16 May 2025 17:40:51 +0200 Subject: [PATCH 19/19] music: Remove go --- bitlair.yaml | 1 - music.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/bitlair.yaml b/bitlair.yaml index 950d555..f4ece91 100644 --- a/bitlair.yaml +++ b/bitlair.yaml @@ -47,7 +47,6 @@ - hosts: music roles: - { role: "acme", tags: ["acme"] } - - { role: "go", tags: ["go"] } - { role: "music", tags: ["music"] } - hosts: pad diff --git a/music.yaml b/music.yaml index 015c769..cc04425 100644 --- a/music.yaml +++ b/music.yaml @@ -5,6 +5,5 @@ - { role: "common", tags: [ "common" ] } - { role: "acme", tags: [ "acme" ] } - { role: "deb_forgejo", tags: [ "deb_forgejo" ] } - - { role: "go", tags: [ "go" ] } - { role: "nginx", tags: [ "nginx" ] } - { role: "music", tags: [ "music" ] }