Hey. I'd like to test out s6, and part of it for me would be transferring crucial service files into s6's scripting language to be able to continue using these tools. I really can't find a proper explanation anywhere for how these are written, though.
Could you guys firstly point out to me where I can find some resources that can properly teach me the way s6's services work, properly? Throw me a man page if you can, I've spent a few minutes looking at it and can't figure out which holds the information I need.
And in addition to that; maybe show me a practical example? Here's the service of one of my tools, could you help me port it over?
[Unit]
Description=Neo4j Management Service
[Service]
Type=forking
User=neo4j
RuntimeDirectory=neo4j
RuntimeDirectoryMode=770
ExecStart=/usr/bin/neo4j start
ExecStop=/usr/bin/neo4j stop
ExecReload=/usr/bin/neo4j restart
RemainAfterExit=no
Restart=on-failure
PIDFile=/var/run/neo4j/neo4j.pid
LimitNOFILE=60000
TimeoutSec=600
[Install]
WantedBy=multi-user.target
Hello.
Check this (https://wiki.artixlinux.org/Main/S6#Basic_usage) and this (https://wiki.artixlinux.org/Main/LocalUserServicesOns6).
Good luck.
Excellent! That's just what I was looking for, resource-wise. I found some additional papers and man pages in the meantime too, but this'll be added to it. Thank you!
Kind of necrobumping, but I really hope this might be helpful.
This isn't the best case scenario for "my first s6 script" because of
Type=forking — s6 works best with what systemd calls
simple,
exec or
oneshot services.
Nevertheless, let's read the file line by line:
- User=neo4j: service the run should run as. This is equivalent to s6-setuidgid neo4j before the program in exec (but you need to create the neo4j user on your system; read documentation for adduser or systemd-sysusers (which, despite the name, Artix uses).
- RuntimeDirectory=neo4j and RuntimeDirectoryMode=770: for system services, this directive creates /run/neo4j owned by the given User and with permissions set to 770. We can do this with install -d -m770 -o neo4j -g neo4j /run/neo4j. Another option is to use systemd-tmpfiles (again, this is a bit of systemd functionality Artix was able to reuse).
- ExecStart=/usr/bin/neo4j start, ExecStop=/usr/bin/neo4j stop, and ExecReload=/usr/bin/neo4j restart: we'll get back to these later.
- RemainAfterExit=no, PIDFile=/var/run/neo4j/neo4j.pid: these are meaningless under s6.
- Restart=on-failure: for forking services, this is meaningless under s6.
- LimitNOFILE=60000: Limiting the number of open files/PID can be done with s6-softlimit -o 60000 before the program in exec. Many LimitXXXX options in systemd have equivalents in s6-softlimit, compare the docs for both.
- TimeoutSec=600: ...wait 5 minutes for the service to get ready? I'll just ignore it, but something isn't right here.
With what we've said so far, the script might look like this:
#!/bin/sh -e
# install -d = create a folder...
# -m770 = ...with permissions 770...
# -o neo4j -g neo4j = ...owned by user and group neo4j.
install -d -m770 -o neo4j -g neo4j /run/neo4j
# order is important! s6-setuidgid must be last thing we call.
exec s6-softlimit -o 60000 s6-setuidgid neo4j ...
Here's where it gets a bit messy. As I said, forking is not the best type for a s6 service, because they needlessly go to the background (https://jdebp.uk/FGA/unix-daemon-design-mistakes-to-avoid.html) and s6 loses track of them. The classic way to work around that is to have
s6-fghack before the final program (which will keep track of the backgrounded process instead of s6 itself), and create a
finish script with the contents of ExecStop:
run
=========
#!/bin/sh -e
install -d -m770 -o neo4j -g neo4j /run/neo4j
exec s6-softlimit -o 60000 s6-fghack s6-setuidgid neo4j /usr/bin/neo4j start
finish
=========
#!/bin/sh -e
/usr/bin/neo4j stop
The problem is, when s6-fghack is necessary,
s6-svc can only stop the process. To send any other signals, you must run
kill -s SIGNAL $(cat /var/run/neo4j.pid) manually (notice we're using the contents of the
PIDFile variable in this command.
There's a little bit of hope: with these Java programs, usually the thing that's given in unit files as a ExecStart/ExecStop is a shell script that just calls Java with arguments that make them go to background. If that's the case, you can try analyzing it and making a new script that doesn't background and does not use PID files. I wish I could analyze it and give the answer here, but the program requires registration to download the package :/.
Here's an example (http://jdebp.uk/FGA/systemd-house-of-horror/tomcat.html) where a Java program was converted from one such shell script into a
Type=simple systemd unit; in that case, you'd just copy-paste the ExecStart after s6-setuidgid, you'd not need s6-fghack and you'd have the full power of s6-svc.