User:Flexibeast/guides/OpenRC user services via s6

From Gentoo Wiki
Jump to:navigation Jump to:search

User services are not yet implemented in OpenRC (though such functionality is being worked on). This guide will demonstrate how a user service can be implemented by using s6 to provide service supervision (i.e. keeping a service running) and basic service management.

Service supervision with s6

Install sys-apps/s6 (and optionally, app-doc/s6-man-pages):

root #emerge --ask sys-apps/s6
root #emerge --ask app-doc/s6-man-pages

As an example, we'll set up an Emacs service.

Create a directory in which "servicedirs" ("service directories", documented here) will be created. We'll use ~/s6, and cd to the newly-created directory:

user $mkdir ~/s6
user $cd ~/s6

Create an emacs servicedir in that directory, and change to that directory:

user $mkdir emacs
user $cd emacs

Now use your editor to create a file called run. This file will be run by s6-supervise, and thus needs to be something executable. The lightweight execline scripting language can be used, but it's not compulsory; for the purposes of this example, we'll just use Bash:

FILE run
#!/usr/bin/bash

exec /usr/bin/emacs --fg-daemon 1>>"${HOME}/.logs/emacs.log" 2>&1

Note the use of exec on the last line of the script; this is crucial. s6 (and other daemontools-style supervisors) start the supervised program as a direct child of the supervising process, and are therefore able to directly determine the status of the service process. This means that the program must not be backgrounded, and that exec must be used to replace the run script with the program as the direct child of the s6-supervise process.

The script also sets up basic logging via redirection to a (presumed preexisting) ${HOME}/.logs/emacs.log file. A more sophisticated approach to logging is provided by s6-rc.

Set the permissions of run to 700:

user $chmod 700 run

And that's it! To start the service, run s6-supervise with the path to the servicedir:

user $s6-supervise ~/s6/emacs

With this basic setup, s6-supervise will try to ensure the service is always up: manually terminating the process, e.g. via:

user $pkill emacs

will subsequently result in a new Emacs server process being created:

user $pgrep -a emacs

When supervising a program, s6-supervise creates two directories in the servicedir: events/, a fifodir for service-related events, and supervise/, for storing internal state.

The s6-svc program can be used to manage the service. For example, to force a restart:

user $s6-svc -r ~/s6/emacs

or to stop the service:

user $s6-svc -dx ~/s6/emacs

where the -d option brings the service down, and the -x option tells the s6-supervise process to exit once the service is down.

Assuming a console-based login, the emacs service could be started at login, once the appropriate environment variables have been set up, via one of the shell's configuration files, e.g. ~/.bash_login:

FILE ~/.bash_login
s6-supervise ~/s6/emacs

Optional: Modify script to add D-Bus support

Some Emacs functionality requires the presence of a D-Bus session bus (which is distinct from the D-Bus system bus provided by the dbus service). Assuming that a D-Bus session bus has been created and its value saved somewhere, e.g. via something like:

dbus-daemon --session --fork --print-address 4 4>|"${XDG_STATE_HOME}/session-bus-address"

The run script can be modified to set the value of DBUS_SESSION_BUS_ADDRESS for the Emacs service:

FILE run
#!/usr/bin/bash

export DBUS_SESSION_BUS_ADDRESS=$(cat "${XDG_STATE_HOME}/session-bus-address" | tr -d '\n')

exec /usr/bin/emacs --fg-daemon 1>>"${HOME}/.logs/emacs.log" 2>&1