Each service has a start
procedure and a stop
procedure,
also referred to as its constructor and destructor
(see Services). The procedures listed below return procedures that
may be used as service constructors and destructors. They are flexible
enough to cover most use cases and carefully written to complete in a
timely fashion.
Return a procedure that forks a child process, closes all file
descriptors except the standard output and standard error descriptors,
sets the current directory to directory, sets the umask to
file-creation-mask unless it is #f
, changes the environment
to environment-variables (using the environ
procedure),
sets the current user to user the current group to group
unless they are #f
and supplementary groups to
supplementary-groups unless they are '()
, and executes
command (a list of strings.) When
create-session? is true, the child process creates a new session with
setsid
and becomes its leader. The result of the procedure will be the
<process>
record representing the child process.
Note: This will not work as expected if the process “daemonizes” (forks); in that case, you will need to pass
#:pid-file
, as explained below.
When pid-file is true, it must be the name of a PID file associated with the process being launched; the return value is the PID once that file has been created. If pid-file does not show up in less than pid-file-timeout seconds, the service is considered as failing to start.
When log-file is true, it names the file to which the service’s standard output and standard error are redirected. log-file is created if it does not exist, otherwise it is appended to.
Note: See Log Rotation Service, for a service to rotate log files specified via the
#:log-file
parameter.
Guile’s setrlimit
procedure is applied on the entries in
resource-limits. For example, a valid value would be:
'((nproc 10 100) ;number of processes (nofile 4096 4096)) ;number of open file descriptors
Return a procedure that sends signal to the process group of the PID
given as argument, where signal defaults to SIGTERM
. If the
process is still running after grace-period seconds, send it
SIGKILL
. The procedure returns once the process has terminated.
This does work together with respawning services,
because in that case the stop
method of the <service>
arranges so that the service is not respawned.
The make-forkexec-constructor
procedure builds upon the following
procedures.
Run command as the current process from directory, with
file-creation-mask if it’s true, with rlimits, and with
environment-variables (a list of strings like "PATH=/bin"
.)
File descriptors 1 and 2 are kept as is or redirected to
either log-port or log-file
if it’s true, whereas file descriptor 0
(standard input) points to input-port or /dev/null; all other file descriptors
are closed prior to yielding control to command. When
create-session? is true, call setsid
first
(see setsid
in GNU Guile Reference Manual).
By default, command is run as the current user. If the user
keyword argument is present and not false, change to user
immediately before invoking command. user may be a string,
indicating a user name, or a number, indicating a user ID. Likewise,
command will be run under the current group, unless the
group keyword argument is present and not false, and
supplementary-groups is not '()
.
fork+exec-command
does the same as exec-command
, but in
a separate process whose PID it returns.
This parameter (see Parameters in GNU Guile Reference Manual) specifies the default list of environment variables to be defined when the procedures above create a new process.
It must be a list of strings where each string has the format
name=value
. It defaults to what environ
returns when the program starts (see environ
in GNU Guile Reference Manual).
This parameter (see Parameters in GNU Guile Reference Manual)
specifies the default PID file timeout in seconds, when
#:pid-file
is used (see above). It defaults to 5 seconds.
This parameter (see Parameters in GNU Guile Reference Manual)
specifies the “grace period” (in seconds) after which a process that
has been sent SIGTERM
or some other signal to gracefully exit is
sent SIGKILL
for immediate termination. It defaults to 5
seconds.
This parameter specifies the default value of the #:respawn-delay
parameter of service
(see Defining Services). It defaults to
0.1
, meaning a 100ms delay before respawning a service.
This parameter specifies the default value of the #:respawn-limit
parameter of service
(see Defining Services).
As an example, suppose you add this line to your configuration file:
(default-respawn-limit '(3 . 10))
The effect is that services will be respawned at most 3 times over a period of 10 seconds before being disabled.
One may also define services meant to be started on demand. In that case, shepherd listens for incoming connections on behalf of the program that handles them; when it accepts an incoming connection, it starts the program to handle them. The main benefit is that such services do not consume resources until they are actually used, and they do not slow down startup.
These services are implemented following the protocol of the venerable
inetd “super server” (see inetd in GNU
Inetutils). Many network daemons can be invoked in “inetd mode”;
this is the case, for instance, of sshd
, the secure shell
server of the OpenSSH project. The Shepherd lets you define inetd-style
services, specifically those in nowait
mode where the daemon is
passed the newly-accepted socket connection while shepherd
is
in charge of listening.
Listening endpoints for such services are described as records built
using the endpoint
procedure provided by the (shepherd
endpoints)
module:
Return a new endpoint called name of address, an address as
return by make-socket-address
, with the given style and
backlog.
When address is of type AF_INET6
, the endpoint is
IPv6-only. Thus, if you want a service available both on IPv4
and IPv6, you need two endpoints. For example, below is a list of
endpoints to listen on port 4444 on all the network interfaces, both in
IPv4 and IPv6 (“0.0.0.0” for IPv4 and “::0” for IPv6):
(list (endpoint (make-socket-address AF_INET INADDR_ANY 4444)) (endpoint (make-socket-address AF_INET6 IN6ADDR_ANY 4444)))
This is the list you would pass to make-inetd-constructor
or
make-systemd-constructor
—see below.
When address is of type AF_UNIX
, socket-owner and
socket-group are strings or integers that specify its ownership and that
of its parent directory; socket-directory-permissions specifies the
permissions for its parent directory.
Upon ‘EADDRINUSE’ (“Address already in use”), up to bind-attempts
attempts will be made to bind
on address, one every second.
This parameter specifies the number of times, by default, that
shepherd
will try to bind an endpoint address if it happens to
be already in use.
The inetd service constructor takes a command and a list of such endpoints:
Return a procedure that opens sockets listening to endpoints, a list
of objects as returned by endpoint
, and accepting connections in the
background.
Upon a client connection, a transient service running command is spawned. Only up to max-connections simultaneous connections are accepted; when that threshold is reached, new connections are immediately closed.
The remaining arguments are as for make-forkexec-constructor
.
Return a procedure that terminates an inetd service.
The last type is systemd-style services. Like inetd-style services, those are started on demand when an incoming connection arrives, but using the protocol devised by the systemd service manager and referred to as socket activation. The main difference with inetd-style services is that shepherd hands over the listening socket(s) to the daemon; the daemon is then responsible for accepting incoming connections. A handful of environment variables are set in the daemon’s execution environment (see below), which usually checks them using the libsystemd or libelogind client library helper functions. The constructor and destructor for systemd-style daemons are described below.
Return a procedure that starts command, a program and list of
argument, as a systemd-style service listening on endpoints, a list of
<endpoint>
objects.
command is started on demand on the first connection attempt on one of
endpoints when lazy-start? is true; otherwise it is started as
soon as possible. It is passed the listening sockets for endpoints in
file descriptors 3 and above; as such, it is equivalent to an Accept=no
systemd
socket unit. The following environment variables are set in its environment:
LISTEN_PID
It is set to the PID of the newly spawned process.
LISTEN_FDS
It contains the number of sockets available starting from file descriptor 3—i.e., the length of endpoints.
LISTEN_FDNAMES
The colon-separated list of endpoint names.
This must be paired with make-systemd-destructor
.
Return a procedure that terminates a systemd-style service as created by
make-systemd-constructor
.
The following constructor/destructor pair is also available for your
convenience, but we recommend using make-forkexec-constructor
and
make-kill-destructor
instead (this is typically more robust than
going through the shell):
The returned procedure will execute command in a shell and
return #t
if execution was successful, otherwise #f
.
For convenience, it takes multiple arguments which will be
concatenated first.
Similar to make-system-constructor
, but returns #f
if
execution of the command was successful, #t
if not.
See Timers, for other service constructors and destructors: those for timers.