2012-10-16
Runit is a pretty lightweight process supervisor (tool-set). It can be used alongside your distro's own init scripts to build flexible service structures.
To get a short overview/introduction one could read "Init scripts considered harmful", read a blog post or take a look on at the Arch Linux wiki for some examples.
This post aims to describe the minimal steps to get a user service tree up and
running. Furthermore it documents the solution for a small problem when using
the runsvdir
command this way.
Because it can be quite convenient to have facilities to let users of a system define services on their own - and let them run as their own user - with convenient access to all process related information such as pids or log-files.
And while there is some information out there regarding user-level services using runit, I ran into an issue while trying to take down a whole user service tree. Therefore it seems useful for me to document the problem and the solution.
The installation of runit should be quite easy on most Linux distributions.
Using Debian (squeeze) it is a matter of running the following command as root:
apt-get install runit
This retrieves an archive of about 130kB in size. Extracted this take less than 400kB disk space. Nice.
From here we just need to create a service which runs the runsvdir
program
as the desired user. This is done by creating a service directory and a
corresponding run
file (still being root). Suppose we have a user named
rico
:
mkdir -p /etc/sv/user/rico
cat > /etc/sv/user/rico/run << EOF
#!/bin/sh
exec 2>&1
exec chpst -urico runsvdir -P /home/rico/service 'log:....................'
EOF
chmod u+x /etc/sv/user/rico/run
And in case you are using NIS or other services to provide the system with
the user in question you may want to use sudo within your run
file:
#!/bin/sh
exec 2>&1
exec sudo -H -u rico runsvdir -P /home/rico/service 'log:....................'
To activate the service tree we then just have to add a symlink:
ln -s /etc/sv/user/rico /etc/service/user-rico
Now the user rico
may add services by creating a ~/service
directory and
adding service directories/symlinks therein.
Take the following (useless) service for example (added as regular user rico
):
mkdir -p /home/rico/service/catrandom
cat > /home/rico/service/catrandom/run <<EOF
#!/bin/sh
exec cat /dev/random > /dev/null
EOF
chmod +x /home/rico/service/catrandom/run
Adding this directory and the run file and making it executable should fire up the service. This can be verified using ps or htop for example.
Taking down this (useless) service can be done by simply using
sv down ~/service/catrandom
. Refer to the documentation for more examples ...
There is still one thing left to do for our user service tree. We should create
a finish
script within the same directory where we put the run
script for
runsvdir
. This script will contain logic which takes down all user services
in case we decide to stop the user services service.
As root:
cat > /etc/sv/user/rico/finish <<EOF
#!/bin/sh
sv -w600 force-stop /home/rico/service/*
sv exit /home/rico/service/*
EOF
chmod u+x /etc/sv/user/rico/finish
After which we can safely issue sv down user-rico
as root to stop all
user services for rico.
This has been suggested by the author of runit himself on the mailing-list and because svwaitdown has been merged into sv we use sv there.