New bundle: navidrome music server #75
5 changed files with 228 additions and 0 deletions
44
bundles/navidrome/files/navidrome.service
Normal file
44
bundles/navidrome/files/navidrome.service
Normal file
|
@ -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
|
59
bundles/navidrome/items.py
Normal file
59
bundles/navidrome/items.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
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',
|
||||||
|
'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')),
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:navidrome:restart',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/etc/systemd/system/navidrome.service': {
|
||||||
|
'triggers': {
|
||||||
|
'action:systemd-reload',
|
||||||
|
'svc_systemd:navidrome:restart',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
77
bundles/navidrome/metadata.py
Normal file
77
bundles/navidrome/metadata.py
Normal file
|
@ -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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ ips = [
|
||||||
]
|
]
|
||||||
gateway4 = "172.19.164.1"
|
gateway4 = "172.19.164.1"
|
||||||
ipv6_accept_ra = true
|
ipv6_accept_ra = true
|
||||||
|
[metadata.interfaces.enp7s0.routes."172.19.165.0/24"]
|
||||||
|
via = "172.19.164.2"
|
||||||
|
|
||||||
[metadata.vm]
|
[metadata.vm]
|
||||||
cpu = 2
|
cpu = 2
|
||||||
|
|
46
nodes/sophie/sophie.navidrome.toml
Normal file
46
nodes/sophie/sophie.navidrome.toml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
hostname = "172.19.164.5"
|
||||||
|
bundles = [
|
||||||
|
'navidrome',
|
||||||
|
'nginx',
|
||||||
|
'nfs-client',
|
||||||
|
]
|
||||||
|
groups = [
|
||||||
|
"debian-bookworm",
|
||||||
|
]
|
||||||
|
|
||||||
|
[metadata.interfaces.enp1s0]
|
||||||
|
ips = [
|
||||||
|
"172.19.164.5/24",
|
||||||
|
]
|
||||||
|
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
|
||||||
|
ram = 4
|
||||||
|
|
||||||
|
[metadata.navidrome]
|
||||||
|
domain = 'navidrome.home.sophies-kitchen.eu'
|
||||||
|
version = '0.55.2'
|
||||||
|
sha1 = 'c5e513fb830f40bea33537ef0c649a3621bd443c'
|
||||||
|
|
||||||
|
[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'
|
Loading…
Add table
Reference in a new issue