Running runit on Amazon Linux AMI
Unfortunately, runit supervisor is not so popular in RadHat-based distrubutions.
If you like runit simplicity and don’t want to give it up and use complex run scripts or write obscure upstart jobs, read ahead.
The trick is to use busybox: little all-in-one utility, used mostly as a rescue kit, during boot stage or in embedded environments.
Luckily, Amazon Linux AMI has busybox package in its base repositories, so you need to install it first:
# yum install busybox
Once installed, you can find it in /sbin/busybox
. This little binary has great powers hidden inside: call busybox --list
and you will get full list of supported commands. Each command can be called as busybox commandName
, or via commandname symlink: you can create symlink called commandName
to /sbin/busybox
and call this symlink directly like a separate binary. We won’t need all of them to get runit up and running though, only these are sufficient:
# busybox --list | awk '/runsv|chpst|svlog|^sv$/'
chpst
runsv
runsvdir
sv
svlogd
Create symlinks:
# busybox --list | awk '/runsv|chpst|svlog|^sv$/' | \
xargs -I{} ln -sv /sbin/busybox /sbin/{}
Now you have to run runsvdir. In debian-based distributions, runsvdir is traditionally started with SysV init /sbin/init
process, as runsv package adds runsvdir to /etc/inittab
. Amazon Linux AMI is a different story: it uses upstart as its init system, so we have to create upstart job to start runsvdir.
Let’s create service directories first:
mkdir -p /etc/sv /etc/service
The first one would contain actual service directories, enabled services would be symlinked to the second directory, which has to be tracked by runsvdir process.
Create upstart service for runsvdir:
<<EOF cat > /etc/init/runsvdir.conf
start on runlevel [2345]
stop on runlevel [S016]
respawn
exec /sbin/runsvdir -P /etc/service
EOF
Now check you have runsvdir up and running:
# status runsvdir
runsvdir start/running, process 1508
Running test service to check runit
Let’s create a basic service to check whether runit works ok.
Service directory:
mkdir -p /etc/sv/sleeper/log
Create service run script:
<<EOF cat > /etc/sv/sleeper/run
#!/bin/sh -eu
exec 2>&1
env
exec sleep 360
EOF
Create log service run script:
<<EOF cat > /etc/sv/sleeper/log/run
#!/bin/sh -eu
exec 2>&1
LOGDIR=/var/log/sleeper
test -d $LOGDIR || mkdir -p $LOGDIR
exec /sbin/svlogd -tt $LOGDIR
EOF
Make scripts executable:
find /etc/sv/sleeper -name run -exec chmod +x \{\} \+
Create symlink to service:
ln -sv ../sv/sleeper /etc/service
Now runsvdir should have automatically started your service, you can check it with sv
command:
# sv s /etc/service/sleeper
run: /etc/service/sleeper: (pid 1619) 53s; run: log: (pid 1522) 1493s
Or look at process tree with ps fax
:
1508 ? Ss 0:00 /sbin/runsvdir -P /etc/service
1521 ? Ss 0:00 \_ runsv sleeper
1522 ? S 0:00 \_ /sbin/svlogd -tt /var/log/sleeper
1619 ? S 0:00 \_ sleep 360
If you don’t like to put /etc/service
before service name each time you call sv
, you can use SVDIR
environment variable:
# export SVDIR=/etc/service
# sv s sleeper
run: sleeper: (pid 1653) 283s; run: log: (pid 1522) 2443s