Next: , Previous: , Up: Services   [Contents][Index]


4.4 Service De- and Constructors

All of the procedures listed below return procedures generated from the supplied arguments. These procedures take one argument in the case of destructors and no arguments in the case of constructors.

procedure: make-system-constructor command

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.

procedure: make-system-destructor command

Similar to make-system-constructor, but returns #f if execution of the command was successful, #t if not.

procedure: make-forkexec-constructor command [#:user #f] [#:group #f] [#:supplementary-groups '()] [#:pid-file #f] [#:pid-file-timeout (default-pid-file-timeout)] [#:log-file #f] [#:directory (default-service-directory)] [#:file-creation-mask #f] [#:create-session? #t] [#:resource-limits '()] [#:environment-variables (default-environment-variables)]

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 PID of 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.

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
procedure: make-kill-destructor [signal]

Return a procedure that sends signal to the process group of the PID given as argument, where signal defaults to SIGTERM.

This does work together with respawning services, because in that case the stop method of the <service> class sets the running slot to #f before actually calling the destructor; if it would not do that, killing the process in the destructor would immediately respawn the service.

The make-forkexec-constructor procedure builds upon the following procedures.

procedure: exec-command command [#:user #f] [#:group #f] [#:supplementary-groups '()] [#:log-file #f] [#:log-port #f] [#:input-port #f] [#:directory (default-service-directory)] [#:file-creation-mask #f] [#:create-session? #t] [#:resource-limits '()] [#:environment-variables (default-environment-variables)]
procedure: fork+exec-command command [#:user #f] [#:group #f] [#:supplementary-groups '()] [#:log-file #f] [#:log-encoding "UTF-8"] [#:directory (default-service-directory)] [#:file-creation-mask #f] [#:create-session? #t] [#:resource-limits '()] [#:environment-variables (default-environment-variables)]

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.

Scheme Variable: default-environment-variables

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).

Scheme Variable: default-pid-file-timeout

This parameter (see Parameters in GNU Guile Reference Manual) specified the default PID file timeout in seconds, when #:pid-file is used (see above). It defaults to 5 seconds.

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.

procedure: make-inetd-constructor command address

[#:service-name-stem _] [#:requirements ’()]   [#:socket-style SOCK_STREAM] [#:listen-backlog 10]   [#:socket-owner (getuid)] [#:socket-group (getgid)]   [#:socket-directory-permissions #o755]   [#:max-connections (default-inetd-max-connections)]   [#:user #f]   [#:group #f]   [#:supplementary-groups ’()]   [#:directory (default-service-directory)]   [#:file-creation-mask #f] [#:create-session? #t]   [#:resource-limits ’()]   [#:environment-variables (default-environment-variables)] Return a procedure that opens a socket listening to address, an object as returned by make-socket-address, and accepting connections in the background; the listen-backlog argument is passed to accept.

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 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.

procedure: make-inetd-destructor

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.

Listening endpoints for such services are described as records built using the endpoint procedure:

procedure: endpoint address [#:name "unknown"] [#:style SOCK_STREAM] [backlog 128] [#:socket-owner (getuid)] [#:socket-group (getgid)] [#:socket-directory-permissions #o755]

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_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.

The constructor and destructor for systemd-style daemons are described below.

procedure: make-systemd-destructor command endpoints [#:user #f] [#:group #f] [#:supplementary-groups '()] [#:directory (default-service-directory)] [#:file-creation-mask #f] [#:create-session? #t] [#:resource-limits '()] [#:environment-variables (default-environment-variables)]

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. 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.

procedure: make-systemd-destructor

Return a procedure that terminates a systemd-style service as created by make-systemd-constructor.


Next: , Previous: , Up: Services   [Contents][Index]