Adding systemd unit files in OpenStack packages
Ansgar Burchardt
ansgar at debian.org
Mon Jul 7 12:21:58 BST 2014
Hi,
I'm mostly a systemd user myself, but have read through a reasonable
part of the documentation. So hopefully I can answer some of your questions.
On 07/06/2014 15:33, Thomas Goirand wrote:
> Let's take an example with keystone. Currently, there's the following
> init.d sysv-rc script LSB header:
>
> # Required-Start: $network $local_fs $remote_fs
> # Required-Stop: $remote_fs
Except for $network, these dependencies should be included in default
dependencies, i.e. you don't need to do anything for them.
The replacement for $network depends on what exactly is needed and I'm
not entirely sure myself of the semantics. Maybe someone else could
explain this part.
> # Should-Start: mysql postgresql slapd rabbitmq-server ntp
> # Should-Stop: mysql postgresql slapd rabbitmq-server ntp
>
> How does this translate into a systemd unit? Especially, it'd be nice to
> have mysql socket activation, but the service may be remote, so it
> shouldn't be forced, but just be there if mysqld is local.
For service with socket activation, there should be no need for an
explicit dependency.
For other dependencies, I believe that Should-Start: foo translates to
After=foo.service. The Should-Stop is then implied.
> Then another example. With nova-compute, I have the following:
>
> [ -r /etc/default/openstack ] && . /etc/default/openstack
> [ -r /etc/default/$NAME ] && . /etc/default/$NAME
>
> [ "x$USE_SYSLOG" = "xyes" ] && DAEMON_ARGS="$DAEMON_ARGS --use-syslog"
> [ "x$USE_LOGFILE" != "xno" ] && DAEMON_ARGS="$DAEMON_ARGS \
> --log-file /var/log/nova/$NAME.log"
>
> The idea is that, by default, nova-compute only logs to a file. That is,
> unless someone configures /etc/default/nova-compute. It is also possible
> configure it globally in /etc/default/openstack (with the same
> directives). How do I do this in a systemd unit file?
I think they probably should log to the journal by default. If the admin
wants to change this, he can override the ExecStart= option to pass
different options to the executable.
Just let the daemon write to stdout/stderr and set
StandardOutput=journal if it has no built-in support for logging the the
journal itself.
systemd can do variable substitution, but logic like "if USE_SYSLOG=yes,
then append --use-syslog to startup options" isn't directly supported.
It is however considered better style not to rely on these features.
> The daemon currently are started with start-stop-daemon. I do:
>
> NAME=nova-compute
> DAEMON=/usr/bin/$NAME
> DAEMON_ARGS="--config-file=/etc/nova/nova.conf"
> PIDFILE=/var/run/$NAME.pid
>
> [...]
>
> do_start() {
> start-stop-daemon --start --background --quiet --chuid \
> ${NOVA_USER}:nova --make-pidfile --pidfile $PIDFILE \
> --startas $DAEMON --test > /dev/null \
> || return 1
>
> As per above, the daemon doesn't fork by itself. Should I also do a PID
> file with systemd, or is there a better way, with supervision?
systemd can track the daemon and any child processes without a PID file.
> How do I do the restart on crash?
Restart=on-failure will restart the service if it exists with non-zero
in addition to the on-abort conditions. Restart=on-abort will restart
the process only when it exists due to an uncaught signal (one can
whitelist signals). Finally, Restart=always will always restart the
service if the daemon exits for any reason.
The detailed semantics are described in systemd.service(5).
> Is there a way to send an email to root upon
> crash of the daemon, or is this still not implemented in systemd?
I don't think systemd can do this and believe it might not be its role
either. But one can probably obtain this information for the journal.
> How do I implement waiting for libvirtd socket, so that compute starts
> after that?
Hmm, ideally use socket activation for that as well? Otherwise
After=libvirt-bin.service
A full .service file for nova might look like this:
+---
| [Unit]
| Description=Nova Compute server
| Documentation=man:nova-compute(8) http://example.com/nova.html
| After=libvirt-bin.service keystone.service
|
| [Service]
| ExecStart=/usr/bin/nova-compute --config-file=/etc/nova/nova.conf
| Restart=always
| User=nova
| Group=nova (defaults to default group of the user)
| StandardOutput=journal
| StandardError=inherit (actually the default)
|
| [Install]
| WantedBy=multi-user.target
+---
The Unit and Install sections are documented in systemd.unit(5), the
Service section in systemd.service(5), with the options related to
execution in systemd.exec(5).
You can install the .service file with dh-systemd which will also take
care of the necessary bits in the maintainer scripts.
I noticed that the init script for nova-compute also sets up a directory
for locks. In systemd this is handled by systemd-tmpfiles:
+---
| d /run/lock/nova 0755 nova nova
+---[ debian/nova-compute.tmpfile ]
dh-systemd will then install the file to
/usr/lib/tmpfiles.d/nova-compute.conf. Note that I changed
/var/lock/nova to /run/lock/nova. See tmpfiles.d(5) for details on the
syntax.
Ansgar
More information about the Pkg-systemd-maintainers
mailing list