From b6cedd2bce6c49fa24b76a59621353c0b91c52f1 Mon Sep 17 00:00:00 2001 From: Sophie Schiller Date: Wed, 16 Apr 2025 17:36:45 +0200 Subject: [PATCH 1/5] navidrome: initial bundle --- bundles/navidrome/files/navidrome.service | 44 +++++++++++++ bundles/navidrome/items.py | 45 +++++++++++++ bundles/navidrome/metadata.py | 77 +++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 bundles/navidrome/files/navidrome.service create mode 100644 bundles/navidrome/items.py create mode 100644 bundles/navidrome/metadata.py diff --git a/bundles/navidrome/files/navidrome.service b/bundles/navidrome/files/navidrome.service new file mode 100644 index 0000000..90a1816 --- /dev/null +++ b/bundles/navidrome/files/navidrome.service @@ -0,0 +1,44 @@ +[Unit] +Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic +After=remote-fs.target network.target +AssertPathExists=/var/opt/navidrome + +[Install] +WantedBy=multi-user.target + +[Service] +User=navidrome +Group=navidrome +Type=simple +ExecStart=/opt/navidrome/navidrome --configfile "/opt/navidrome/config.toml" +WorkingDirectory=/var/opt/navidrome +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +# See https://www.freedesktop.org/software/systemd/man/systemd.exec.html +DevicePolicy=closed +NoNewPrivileges=yes +PrivateTmp=yes +PrivateUsers=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap +ReadWritePaths=/var/opt/navidrome + +# You can uncomment the following line if you're not using the jukebox This +# will prevent navidrome from accessing any real (physical) devices +PrivateDevices=yes + +# You can change the following line to `strict` instead of `full` if you don't +# want navidrome to be able to write anything on your filesystem outside of +# /var/lib/navidrome. +ProtectSystem=full + +# You can uncomment the following line if you don't have any media in /home/*. +# This will prevent navidrome from ever reading/writing anything there. +ProtectHome=true diff --git a/bundles/navidrome/items.py b/bundles/navidrome/items.py new file mode 100644 index 0000000..84e4e29 --- /dev/null +++ b/bundles/navidrome/items.py @@ -0,0 +1,45 @@ +users = { + 'navidrome': { + 'home': '/opt/navidrome', + }, +} + +directories = { + '/opt/navidrome': {}, + '/var/opt/navidrome': { + 'owner': 'navidrome', + }, +} +svc_systemd = { + 'navidrome': { + 'needs': { + 'file:/etc/systemd/system/navidrome.service', + 'file:/opt/navidrome/config.toml', + 'file:/opt/navidrome/navidrome', + }, + }, +} + +files = { + '/opt/navidrome/config.toml': { + 'content': repo.libs.faults.dict_as_toml(node.metadata.get('navidrome/config')), + 'triggers': { + 'svc_systemd:navidrome:restart', + }, + }, + '/etc/systemd/system/navidrome.service': { + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:navidrome:restart', + }, + }, + '/opt/navidrome/navidrome': { + 'content_hash': node.metadata.get('navidrome/sha1', None), + 'content_type': 'download', + 'mode': '0755', + 'source': f'https://github.com/navidrome/navidrome/releases/download/v{node.metadata.get('navidrome/version')}/navidrome_{node.metadata.get('navidrome/version')}_linux_amd64.tar.gz', + 'triggers': { + 'svc_systemd:navidrome:restart', + }, + }, +} diff --git a/bundles/navidrome/metadata.py b/bundles/navidrome/metadata.py new file mode 100644 index 0000000..4eeebb5 --- /dev/null +++ b/bundles/navidrome/metadata.py @@ -0,0 +1,77 @@ +defaults = { + 'apt': { + 'packages': { + 'ffmpeg': {}, + 'mpv': {}, + + }, + }, + 'navidrome': { + 'config': { + 'DataFolder': '/var/opt/navidrome', + 'Address': '127.0.0.1', + 'MusicFolder': '/mnt/music', + 'EnableExternalServices': False, + 'LastFM.Enabled': False, + 'ListenBrainz.Enabled': False, + 'PasswordEncryptionKey': repo.vault.password_for('{} encryption navidrome'.format(node.name)), + 'Scanner.Schedule': '@every 72h', + 'Port': 4533, + }, + }, + 'zfs': { + 'datasets': { + 'tank/navidrome': {}, + 'tank/navidrome/install': { + 'mountpoint': '/opt/navidrome', + 'needed_by': { + 'directory:/opt/navidrome', + }, + }, + 'tank/navidrome/home': { + 'mountpoint': '/var/opt/navidrome', + 'needed_by': { + 'directory:/var/opt/navidrome', + }, + }, + }, + }, +} + + +@metadata_reactor.provides( + 'navidrome/config/baseurl', +) +def baseurl(metadata): + return { + 'navidrome': { + 'config': { + 'BaseUrl': f'https://{metadata.get('navidrome/domain')}', + }, + }, + } + + +@metadata_reactor.provides( + 'nginx/vhosts/navidrome', +) +def nginx(metadata): + if not node.has_bundle('nginx'): + raise DoNotRunAgain + + return { + 'nginx': { + 'vhosts': { + 'navidrome': { + 'domain': metadata.get('navidrome/domain'), + 'locations': { + '/': { + 'target': f'http://127.0.0.1:{metadata.get('navidrome/config/port')}', + }, + }, + 'website_check_path': '/user/login', + 'website_check_string': 'Sign in', + }, + }, + }, + } -- 2.39.5 From 3fa4e780fd1b3c2804bbc87ef2c9034038de23e1 Mon Sep 17 00:00:00 2001 From: Sophie Schiller Date: Wed, 16 Apr 2025 17:37:11 +0200 Subject: [PATCH 2/5] sophie.navidrome: initial nodefile --- nodes/sophie/sophie.navidrome.toml | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 nodes/sophie/sophie.navidrome.toml diff --git a/nodes/sophie/sophie.navidrome.toml b/nodes/sophie/sophie.navidrome.toml new file mode 100644 index 0000000..93df587 --- /dev/null +++ b/nodes/sophie/sophie.navidrome.toml @@ -0,0 +1,44 @@ +hostname = "172.19.164.5" +bundles = [ + 'navidrome', + 'nginx', + 'nfs-client', +] +groups = [ + "debian-bookworm", +] + +[metadata.interfaces.enp7s0] +ips = [ + "172.19.164.5/24", +] +gateway4 = "172.19.164.1" +ipv6_accept_ra = true + +[metadata.vm] +cpu = 2 +ram = 4 + +[metadata.navidrome] +domain = 'navidrome.home.sophies-kitchen.eu' +version = '0.55.2' +sha1 = '97661ab81438a521d2b149a417a7282a9bf4c2dc79c5148c4fa32a102e416940' + +[metadata.navidrome.config] +MusicFolder = "/mnt/media/Musik" + +[metadata.nfs-client.mounts.media] +mountpoint = '/mnt/media' +serverpath = '172.19.164.2:/srv/nas' +mount_options =[ + 'retry=0', + 'ro', +] + +[metadata.nginx] +restrict-to = [ + '172.19.164.0/22', +] + +[metadata.nginx.vhosts.navidrome] +ssl = '_.home.sophies-kitchen.eu' -- 2.39.5 From 53c658c5d8dfc2b01549a38f753820cc95e6f0ff Mon Sep 17 00:00:00 2001 From: Sophie Schiller Date: Wed, 16 Apr 2025 18:10:26 +0200 Subject: [PATCH 3/5] navidrome: unpack action --- bundles/navidrome/items.py | 18 ++++++++++++++++-- bundles/navidrome/metadata.py | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/bundles/navidrome/items.py b/bundles/navidrome/items.py index 84e4e29..60e4c04 100644 --- a/bundles/navidrome/items.py +++ b/bundles/navidrome/items.py @@ -15,11 +15,24 @@ svc_systemd = { 'needs': { 'file:/etc/systemd/system/navidrome.service', 'file:/opt/navidrome/config.toml', - 'file:/opt/navidrome/navidrome', + 'action:navidrome_install', }, }, } +actions['navidrome_install'] = { + 'command': ' && '.join([ + 'tar -C /opt/navidrome -xf /opt/navidrome/navidrome.tar.gz', + ]), + 'after': { + 'pkg_apt:', + }, + 'triggered': True, + 'triggers': { + 'svc_systemd:navidrome:restart', + }, +} + files = { '/opt/navidrome/config.toml': { 'content': repo.libs.faults.dict_as_toml(node.metadata.get('navidrome/config')), @@ -33,12 +46,13 @@ files = { 'svc_systemd:navidrome:restart', }, }, - '/opt/navidrome/navidrome': { + '/opt/navidrome/navidrome.tar.gz': { 'content_hash': node.metadata.get('navidrome/sha1', None), 'content_type': 'download', 'mode': '0755', 'source': f'https://github.com/navidrome/navidrome/releases/download/v{node.metadata.get('navidrome/version')}/navidrome_{node.metadata.get('navidrome/version')}_linux_amd64.tar.gz', 'triggers': { + 'action:navidrome_install', 'svc_systemd:navidrome:restart', }, }, diff --git a/bundles/navidrome/metadata.py b/bundles/navidrome/metadata.py index 4eeebb5..4151c51 100644 --- a/bundles/navidrome/metadata.py +++ b/bundles/navidrome/metadata.py @@ -66,7 +66,7 @@ def nginx(metadata): 'domain': metadata.get('navidrome/domain'), 'locations': { '/': { - 'target': f'http://127.0.0.1:{metadata.get('navidrome/config/port')}', + 'target': f'http://127.0.0.1:{metadata.get('navidrome/config/Port')}', }, }, 'website_check_path': '/user/login', -- 2.39.5 From 0c52fe7dd89a366f33fd9cf179f2c55e4075e58e Mon Sep 17 00:00:00 2001 From: Sophie Schiller Date: Wed, 16 Apr 2025 18:10:41 +0200 Subject: [PATCH 4/5] sophie.navidrome: use correct hash --- nodes/sophie/sophie.navidrome.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes/sophie/sophie.navidrome.toml b/nodes/sophie/sophie.navidrome.toml index 93df587..e7d0315 100644 --- a/nodes/sophie/sophie.navidrome.toml +++ b/nodes/sophie/sophie.navidrome.toml @@ -8,7 +8,7 @@ groups = [ "debian-bookworm", ] -[metadata.interfaces.enp7s0] +[metadata.interfaces.enp1s0] ips = [ "172.19.164.5/24", ] @@ -22,7 +22,7 @@ ram = 4 [metadata.navidrome] domain = 'navidrome.home.sophies-kitchen.eu' version = '0.55.2' -sha1 = '97661ab81438a521d2b149a417a7282a9bf4c2dc79c5148c4fa32a102e416940' +sha1 = 'c5e513fb830f40bea33537ef0c649a3621bd443c' [metadata.navidrome.config] MusicFolder = "/mnt/media/Musik" -- 2.39.5 From 63c3e35e79e27b581c76a4eb2dab8118ed90180b Mon Sep 17 00:00:00 2001 From: Sophie Schiller Date: Thu, 17 Apr 2025 21:53:40 +0200 Subject: [PATCH 5/5] sophie.home additional routes --- nodes/sophie/sophie.homeassistant.toml | 2 ++ nodes/sophie/sophie.navidrome.toml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/nodes/sophie/sophie.homeassistant.toml b/nodes/sophie/sophie.homeassistant.toml index 42e25d0..8e2c4da 100644 --- a/nodes/sophie/sophie.homeassistant.toml +++ b/nodes/sophie/sophie.homeassistant.toml @@ -14,6 +14,8 @@ ips = [ ] gateway4 = "172.19.164.1" ipv6_accept_ra = true +[metadata.interfaces.enp7s0.routes."172.19.165.0/24"] +via = "172.19.164.2" [metadata.vm] cpu = 2 diff --git a/nodes/sophie/sophie.navidrome.toml b/nodes/sophie/sophie.navidrome.toml index e7d0315..d1df8eb 100644 --- a/nodes/sophie/sophie.navidrome.toml +++ b/nodes/sophie/sophie.navidrome.toml @@ -14,6 +14,8 @@ ips = [ ] gateway4 = "172.19.164.1" ipv6_accept_ra = true +[metadata.interfaces.enp1s0.routes."172.19.165.0/24"] +via = "172.19.164.2" [metadata.vm] cpu = 2 -- 2.39.5