Hi,

I'm in the middle of this ongoing saga to get audio/navidrome to be startable
at boot time via an rc script. Despite the moaning below, I do like it as a
music player/streamer.

The problem: navidrome doesn't behave like a daemon:

 - it doesn't setsid(2)
 - it doesn't background itself
 - it doesn't log to syslog: it logs to stdout
 - it dies when sent SIGHUP

This is an unfortunate thing to want to run from an rc script at boot time, as
what seems to happen is:

 - rc(8) forks off a navidrome, navidrome starts
 - when rc is done starting everything, it exits, taking the controlling
   terminal away with it.
 - any child that didn't setsid(2) is sent SIGHUP as a result
 - navidrome didn't, it dies - amsuingly they bother to catch SIGHUP, but just
   exit anyway.

This kind of "daemon" appears to be a trend fuelled by things like systemd,
which are happy to host such services.

Navidrome upstream pointed be at this design principle document they are
following, which AFAICS, is in conflict with traditional daemonisation (it
proposes to run in the foreground and only ever logging to stdout):
https://12factor.net/

I suspect (but have not confirmed) that this same problem that people are
having with node.js daemons:
https://marc.info/?l=openbsd-ports&m=169583837426245&w=2

Whether we like it or not, if that's the kind of thing third-party software
wants to do, then what can we do? We can either patch everything that does this
(which is laborious for us), or use a hack like FreeBSD's daemon(8) tool to
first setsid(2) and then exec(3) the software in question:

https://man.freebsd.org/cgi/man.cgi?query=daemon&apropos=0&sektion=0&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html

There's also this similar (but seemingly unmaintained) "daemonize" tool:
https://linux.die.net/man/1/daemonize

I'm therefore exploring whether we want to try to use a daemon-a-like tool to
help daemonise unwilling programs.

Disclaimer: Nothing you are going to see below is production ready. I'm just
hacking quickly and experimenting to see what works and what doesn't.

After reviewing FreeBSD daemon(8) and daemonize(1), I decided they are too
complicated, and we don't need more than half of their features. I very quickly
put together my own minimal `daemon` program:
https://github.com/vext01/daemon

It just does what sanitisation we can, calls daemon(3) (with `noclose=1` for
now) and execs the program you asked for. A quickly hacked together port is
attached.

Then with the diff below, navidrome can be started at boot time.

With this hack though, for some reason you can't use `daemon_logger` to have
the logs go to syslog. If you try, then the navidrome starts, but `rcctl start`
reports a timeout.

I suspect something clever needs to be done with `pexp` to have `rc_check()`
match when logger(1) is in the mix. I burned a couple of hours trying to figure
this out yesterday and eventually gave up. If someone knowledgeable about rc.d
could help, I'd be most grateful.

But Even without syslog support, at least now you can start the damned thing at
boot!

(If we are fine with the general approach, and if this is something that we are
going to need to do for other ports, perhaps it would be better for rc.d to
have some kind of built-in support for using a daemon-wrapper? I don't know)

What do people think about all of this? Dead end, or worthwhile?

Thanks


Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/navidrome/Makefile,v
diff -u -p -r1.16 Makefile
--- Makefile    4 Dec 2023 21:06:03 -0000       1.16
+++ Makefile    9 Dec 2023 12:08:46 -0000
@@ -2,6 +2,7 @@ COMMENT =       modern music server and stream
 
 MODGO_MODNAME =        github.com/navidrome/navidrome
 MODGO_VERSION =        v0.50.1
+REVISION =     0
 
 DISTNAME =     navidrome-${MODGO_VERSION}
 
@@ -27,7 +28,8 @@ WANTLIB += ${COMPILER_LIBCXX} pthread z 
 
 LIB_DEPENDS =          audio/taglib
 
-RUN_DEPENDS =          graphics/ffmpeg
+RUN_DEPENDS =          graphics/ffmpeg \
+                       sysutils/daemon
 
 MODULES =              lang/go
 
Index: pkg/navidrome.rc
===================================================================
RCS file: /cvs/ports/audio/navidrome/pkg/navidrome.rc,v
diff -u -p -r1.3 navidrome.rc
--- pkg/navidrome.rc    30 Nov 2023 14:04:10 -0000      1.3
+++ pkg/navidrome.rc    9 Dec 2023 12:08:25 -0000
@@ -1,12 +1,12 @@
 #!/bin/ksh
 
-daemon="${TRUEPREFIX}/bin/navidrome"
+daemon="${LOCALBASE}/sbin/daemon"
 daemon_user="_navidrome"
-daemon_flags="-c ${SYSCONFDIR}/navidrome.toml"
+daemon_flags="${TRUEPREFIX}/bin/navidrome -c ${SYSCONFDIR}/navidrome.toml"
 
 . /etc/rc.d/rc.subr
 
-rc_bg=YES
+pexp="${daemon_flags}"
 rc_reload=NO
 
 rc_cmd $1

-- 
Best Regards
Edd Barrett

https://www.theunixzoo.co.uk

Attachment: daemon.tgz
Description: application/tar-gz

Reply via email to