Skip to main content
Topic: Help me write my first s6 script (Read 526 times) previous topic - next topic
0 Members and 3 Guests are viewing this topic.

Help me write my first s6 script

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?

Code: [Select]
[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


Re: Help me write my first s6 script

Reply #1
Hello.

Check this and this.

Good luck.


 

Re: Help me write my first s6 script

Reply #3
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:

Code: [Select]
#!/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 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:

Code: [Select]
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

Code: [Select]
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 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.