                                                              -*- org -*-
#+TITLE: GNU Shepherd NEWS — history of user-visible changes
#+STARTUP: content hidestars

Copyright © 2002, 2003 Wolfgang Jährling
Copyright © 2013-2014, 2016, 2018-2020, 2022-2025 Ludovic Courtès <ludo@gnu.org>

  Copying and distribution of this file, with or without modification,
  are permitted in any medium without royalty provided the copyright
  notice and this notice are preserved.

Please send Shepherd bug reports to bug-guix@gnu.org.

* Changes in 1.0.6


** ‘shepherd’ reacts to deletion of its listening socket
   (<https://issues.guix.gnu.org/76998>)

If the listening socket of ‘shepherd’ is deleted, it becomes impossible to
control it.  Thus, upon deletion, ‘shepherd’ tries to reopen it (when running
as PID 1) or stops itself (when running as an unprivileged user).

The latter behavior is useful when the listening socket is under /run/user/UID
(the default) since that directory is usually deleted as soon as the user
session terminates.

** ‘shepherd’ and ‘herd’ honor the ‘SHEPHERD_SOCKET’ environment variable
   (<https://codeberg.org/shepherd/shepherd/issues/11>)

Both ‘shepherd’ and ‘herd’ now honor the new ‘SHEPHERD_SOCKET’ environment
variable, which specifies the socket file to listen to or to connect to when
the ‘--socket’ option is omitted.  The ‘reboot’ and ‘halt’ commands do not
honor it as this usually makes little sense.

** ‘herd status’ shows clearer information for timers
   (<https://codeberg.org/shepherd/shepherd/issues/6>)

Previously, the output of ‘herd status TIMER’ would start with “It is running
since…”, as is the case with other services.  This message could be
misinterpreted as meaning that the timer’s action is currently running, when
it in fact referred to the fact that the timer was “active”, possibly just
awaiting the next alarm.

** New Fish completion

This version comes with completion of the ‘herd’ command for the Fish shell.

** Translations

This version is fully translated in German, Romanian, Swedish, and Ukrainian;
it is partially translated in several other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 1.0.5

** ‘herd status system-log’ now displays the socket and kernel log file

When using the ‘system-log’ service, ‘herd status system-log’ now shows the
socket(s) it is listening to and the kernel log file it is reading (if any).

** ‘system-log’ starts even if #:kernel-log-file is inaccessible
   (<https://issues.guix.gnu.org/77578>)

It used to be that ‘system-log’ would fail to start if the file specified as
#:kernel-log-file was inaccessible.  This was unwise because that would then
typically prevent most system services from starting; also, on Linux, the
default #:kernel-log-file is /proc/kmsg, and that is inaccessible within
containers.

Failure to open #:kernel-log-file is now logged but is non-fatal.

** ‘system-log’ service reads /dev/klog on the Hurd
   (<https://issues.guix.gnu.org/77634>)

The ‘system-log’ service would unconditionally read kernel messages from
/proc/kmsg, which is Linux-specific and nonexistent on the Hurd.  It now reads
from /dev/klog on the Hurd.

** Fix bug that would cause a system-log test failure on the Hurd
   (<https://issues.guix.gnu.org/77634>)

A bug would cause ‘system-log’ to keep polling the file passed as
#:kernel-log-file after it has reached end-of-file; this would significantly
slow down ‘shepherd’ on the Hurd, leading ‘tests/service/system-log.sh’ to
fail.  This bug had no impact in real use where #:kernel-log-file points to an
“endless” file such as /proc/kmsg.

** Fix possible deadlock with timers hitting #:max-duration
   (<https://codeberg.org/shepherd/shepherd/issues/2>)

A deadlock could occur when using a timer with #:max-duration that would
result in shepherd being unable to handle process creation and termination.
The bug could happen only when #:max-duration is specified for the timer, the
timer’s process exceeds #:max-duration, and the timer’s process does not
terminate within 5 seconds after being sent SIGTERM by shepherd.

** Adjust ‘tests/pid-file.sh’ for systems where unlink(2) returns EROFS on /
   (<https://issues.guix.gnu.org/77548>)

This test used to assume that removing a nonexistent file on the root file
system would return ENOENT, which is not the case on Linux when it is mounted
read-only.  Adjust to cope with that.

** Translations

This version is fully translated in French, German, Romanian, Serbian, Slovak,
Swedish, and Ukrainian; it is partially translated in several other languages.
Check out https://translationproject.org/domain/shepherd.html to help
translate it into your language!

* Changes in 1.0.4

** ‘herd status’ displays the command of socket-activated and inetd services

When a systemd-style or inetd-style service is started and not yet spawned,
‘herd status SERVICE’ now displays its command in addition to the endpoint(s)
it is listening on.

** ‘restart’ action passes extra arguments to the service’s constructor
   (<https://issues.guix.gnu.org/77109>)

Until now, extra arguments passed to the ‘restart’ action would be ignored.
Thus, “herd restart SERVICE a b c” would restart SERVICE but silently ignore
the arguments “a b c”.  The behavior is now to pass those extra arguments to
the ‘start’ method of the service.

Incidentally, this also means that mistakenly running “herd restart SERVICE1
SERVICE2” now results in an error because SERVICE2 is interpreted as an
argument to SERVICE1 and not as a second service to restart.

** Starting a one-shot service concurrently no longer reports failure
   (<https://issues.guix.gnu.org/77274>)

It used to be that, when trying to start a one-shot service that was already
starting, ‘herd start’ would wrongfully report failure to start.  This is no
longer the case.

** Fix potential deadlock with built-in service logger
   (<https://issues.guix.gnu.org/77373>)

The built-in service logger (the one used when constructors are not given a
#:log-file argument) could deadlock under some conditions when the service it
was logging has just stopped.  The problem was known to manifest in some cases
on Guix System upon ‘herd stop nginx’.  This is now fixed.

** ‘log-rotation’ does not compressed already-compressed log files

Programs such as nginx can compress log files as they write them.  The
‘log-rotation’ service no longer re-compresses such log files.

** Timers correctly handle winter-to-summer DST change
   (<https://issues.guix.gnu.org/77401>)

This is a followup to an incomplete fix in
<https://issues.guix.gnu.org/75622>: during the summer-to-winter daylight
saving time (DST) change, for example from CET (UTC+1) to CEST (UTC+2) on 30
March 2025 in Western Europe, the interval between consecutive calendar events
would be incorrectly calculated when the event would fall between 02:00am and
03:00am, leading the timer to trigger many times in a row, unless it had
#:wait-for-termination? #true.  This is now fixed; next year will be better!

** System log no longer crashes on some Unicode input
   (<https://issues.guix.gnu.org/77283>)

Due to a bug in Guile’s (ice-9 regex) module, the ‘system-log’ service could
crash on certain inputs containing non-ASCII Unicode characters, when
‘shepherd’ is running in a non-Unicode capable locale (which is usually the
case for PID 1).  This is now fixed by sidestepping the regexp bug entirely.

** ‘make-systemd-constructor’ no longer passes O_NONBLOCK sockets
   (<https://issues.guix.gnu.org/77610>)

The ‘make-systemd-constructor’ procedure used to pass sockets marked as
non-blocking (O_NONBLOCK) to the process it spawns, except when using
#:lazy-start? #f.  It now systematically passes blocking sockets.

This bug would manifest on GNU/Hurd where accept(2) in this child process
would return EAGAIN, which some daemons did not correctly handle.

** ‘system*’ and ‘system’ replacements honor current directory
   (<https://issues.guix.gnu.org/77707>)

The ‘system*’ and ‘system’ replacements in the ‘shepherd’ process now run the
given command in the current directory rather than under
(default-service-directory).

** Refuse to start when another shepherd is listening on the socket
   (<https://issues.guix.gnu.org/76998>)

Starting an additional ‘shepherd’ as a user used to lead it to take control of
the socket (by default /run/user/UID/shepherd/socket) even though another
instance was already running and listening to that socket.  Since that
behavior is undesirable, ‘shepherd’ now refuses to start in this situation.

** Fixed a couple of test suite failures on the Hurd
   (<https://issues.guix.gnu.org/77634>)

A couple of tests that used to fail on GNU/Hurd (i586-gnu) have been fixed.

** Translations

This version is fully translated in German, Romanian, Swedish, and Ukrainian;
it is partially translated in eight other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 1.0.3

** ‘spawn-command’ now honors #:log-file

The ‘spawn-command’ procedure now accepts a #:log-file argument, just like
‘fork+exec-command’.

** New ‘--syslog’ option of ‘shepherd’

This option forces shepherd to write its output to syslog (the /dev/log socket
by default).  This is already the case when shepherd runs as root so this
option only makes sense for non-root shepherd instances, and its primary
purpose is testing.

** Always decode client commands as UTF-8
   (<https://issues.guix.gnu.org/76244>)

Previously client commands send by ‘herd’ would be decoded according to the
locale encoding of the ‘shepherd’ process, which could be ASCII; now they’re
always decoded as UTF-8, as intended.

** Internal logging is always UTF-8
   (<https://issues.guix.gnu.org/76244>)

The so-called “service output port”, where internal logging from shepherd
itself goes, is now always UTF-8-encoded (instead of following locale
encoding).

** Log output missing a newline is preserved
   (<https://issues.guix.gnu.org/76243>)

It used to be that service output missing a final newline would not be logged,
for example when running “herd spawn transient -- echo -n aaaaa”.  This is now
fixed.

** Default generated configuration file updated to match current interface
   (<https://issues.guix.gnu.org/76403>)

The ~/.config/shepherd/init.scm generated when it doesn’t already exist would
use deprecated and removed interfaces.  This is now fixed.

** Inhibit service respawn during shutdown
   (<https://issues.guix.gnu.org/76338>)

Until now, the ability to respawn services remained functional during shutdown
(with ‘herd stop root’, ‘reboot’, etc.).  This caused troubles on Guix System
where the ‘user-processes’ service terminates all processes when it is stopped
and which, as a consequence, could lead shepherd to respawn services, even
though it was being shut down.

** Tolerate slight delays when waiting for a timer event
   (<https://issues.guix.gnu.org/76516>)

Previously, timers could occasionally get slightly more than a 2-second delay,
which would lead them to skip their deadline (with a message saying “resuming
from sleep state?”).  Delay tolerance has been increased.

** Silence warning about ‘environ’ when using Guile 3.0.10
   (<https://issues.guix.gnu.org/76343>)

When using Guile 3.0.10, commands such as ‘shepherd --help’ would print an
erroneous warning about ‘environ’ being called from a multi-threaded context.
This is now fixed.

** Correctly report the exit status of processes terminated early
   (<https://issues.guix.gnu.org/76790>)

For services using ‘fork+exec-command’, there used to be a small window after
creating the process and before monitoring it during which process termination
would be mishandled: ‘herd status SERVICE’ would report that the process
exited successfully, whether or not this was the case.  This is now fixed.

** Several flaky tests have been made more robust

Several tests were “flaky”: they would fail randomly, typically when run on
loaded or slow machines.  The underlying race conditions were identified and
fixed.

** Translations

This version is fully translated in German, Romanian, Slovak, Swedish, and
Ukrainian; it is partially translated in seven other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 1.0.2

** ‘daemonize’ action preserves replacement bindings for ‘sleep’ etc.
   (<https://issues.guix.gnu.org/75460>)

The shepherd process replaces bindings for ‘sleep’, ‘system*’, ‘system’, and
other core Guile procedures with cooperative variants thereof—for instance, it
replaces ‘sleep’ with Fibers’ own ‘sleep’ procedure, which does not block.

Previously, the ‘daemonize’ action would remove those binding replacements,
which could lead to blocking in shepherd, with symptoms such as ‘herd status’
not responding.  This is now fixed.

** Gracefully handle failure to create a service’s log file
   (<https://issues.guix.gnu.org/76130>)

If the file passed as #:log-file to ‘make-forkexec-constructor’ & co. could
not be created, ‘herd status’ and similar commands would hang.  This is now
fixed in two ways: by attempting to create the parent directory of the log
file if it does not exist, and by reporting the failure and keeping the
service ‘stopped’ in other cases.

** Timers honor daylight saving time (DST) changes
   (<https://issues.guix.gnu.org/75622>)

Previously, timers would always sleep a fixed amount of time between two
consecutive calendar events—e.g., 24h between two occurrences of a daily
event—regardless of whether both events occur in the same timezone or DST
setting.  Timers now correctly honor DST changes—e.g., sleeping for 25h
between two daily events if the first one occurs on CEST (Central European
Summer Time, or UTC+2) and the second one occurs on CET (Central European
Time, or UTC+1).

** ‘cron-string->calendar-event’ can now interpret things like “*/2”
   (<https://issues.guix.gnu.org/75843>)

Until now, ‘cron-string->calendar-event’ would fail to interpret
specifications like "0 */2 * * *" (meaning: every two hours).  This is now
fixed.

** ‘cron-string->calendar-event’ properly interprets stars for hours
   (<https://issues.guix.gnu.org/75836>)

Previously, using a star for the hours in a cron specification such as
"* * * * *" (meaning: every minute) would lead ‘cron-string->calendar-event’
to erroneously report an error.  This is now fixed.

** ‘timer-service’ and ‘transient-service’ now honor #:requirement

Previously they would both ignore it, returning a service that depends on
nothing but the root service (which is probably acceptable most of the time).

** ‘default-message-destination-procedure’ is now exported

That procedure of (shepherd service system-log) was documented but not
exported.  This is now fixed.

** Translations

This version is fully translated in German, Romanian, Slovak, Swedish, and
Ukranian; it is partially translated in seven other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 1.0.1

** ‘reboot --kexec’ aborts early on if no kexec image was loaded

Previously, ‘reboot --kexec’ would proceed to reboot and just hang after
stopping all the services if no kernel image had been loaded (with ‘kexec -l’
or similar) or if kexec is unsupported (in particular on kernels other than
Linux).  It now checks for system support and for a pre-loaded kernel image
and does nothing if these two conditions are not meant.

** ‘log-rotation’ service explicitly skips non-regular files

Previously, the log rotation service would attempt to rotate non-regular files
with a reported size greater than the threshold; in practice that could
potentially happen when specifying a directory as an external log file, and
only if the threshold is set below 4096 bytes.  Non-regular files are now
explicitly skipped.

** ‘log-rotation’ no longer crashes with timers having a #:log-file

When a timer service is given a specific #:log-file, the log rotation service
could cause that service’s control fiber to crash when asking it to rotate its
log file.  This is now fixed.

** ‘log-rotation’ removes uncompressed file when using zstd

Previously, when setting #:compression 'zstd, the log rotation service would
leave uncompressed log files, in addition to the .zstd files.  This is now
fixed, using the ‘--rm’ flag of the ‘zstd’ command.

** Translations

This version is fully translated in German, Romanian, Serbian, Swedish, and
Ukranian; it is partially translated in seven other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 1.0.0

** ‘herd status SERVICE’ shows high-level info about services

In previous version, ‘herd status SERVICE’ would print the “running value” of
SERVICE: an integer denoting the PID of its main process, or a socket for
inetd or systemd services.

The output is now clearer, showing the “main PID”, listening endpoints, and so
on.

** ‘herd status SERVICE’ shows recently logged messages and log files

The command now lists recently-logged messages (choose the number of messages
shown with the ‘-n’ option) as well as the file(s) it is logged to, if any.

** ‘herd status SERVICE’ shows custom actions

When a service defines custom actions, these actions are now shown directly in
‘herd status SERVICE’, making it easier to discover them.

** ‘herd status SERVICE’ shows whether a replacement is available

When a replacement is available for a service, this is now shown in the output
of ‘herd status SERVICE’.  Run ‘herd restart SERVICE’ to upgrade it and
install the replacement in its stead.

** ‘herd status root’ shows information about the ‘root’ service itself

It used to be that ‘herd status’ was synonymous with ‘herd status root’ and
both would show the status of all registered services.  This is no longer the
case: ‘herd status root’ now shows information about the ‘root’ service
itself, including recently-logged messages.

** Support for timed services

The new ‘make-timer-constructor’ procedure lets you define a service that runs
periodically—e.g., every day at noon, every Sunday at 10PM.  The resulting
service can be started, stopped, and triggered; it has its output logged like
any other service.  It is comparable to the venerable cron and its variants
but hopefully much more convenient to use.  See “Timers” in the manual.

** New log rotation service

The ‘log-rotation’ service defined in (shepherd service log-rotation) defines
a simple log rotation service, similar to the venerable rottlog and logrotate
programs, which periodically compresses, moves around, and eventually deletes
old log files.  See “Log Rotation Service” in the manual for details.

** New system log service

The ‘system-log’ service is a substitute for good’ol ‘syslogd’: it listens for
messages written by applications on the /dev/log Unix-domain socket and
dispatches them to log files according to administrator-provided rules.
See “System Log” in the manual.

** New timer service

The venerable ‘at’ command, to request the delayed execution of a command,
also got a replacement in the form of the ‘timer’ service.  See “Timers” in
the manual.

** New transient service maker

The new service called ‘transient’ lets you run commands in the background,
and it does so by wrapping them in transient services.  It is similar in
spirit to ‘systemd-run’.  See “Transient Service Maker” in the manual.

** Linux kexec support

On GNU/Linux, the ‘root’ service has a new ‘kexec’ action that can be invoked
with the ‘reboot -k’ command; it reboots straight into a new kernel previously
loaded with the ‘kexec -l IMAGE’ command.  See “Invoking reboot” in the
manual.

** ‘shepherd’ honors ‘--silent’

Previously the ‘--silent’ option of ‘shepherd’ was, well, silently ignored.
This is no longer the case.

** ‘shepherd’ now logs deprecation warnings

Using deprecated interfaces leads to warnings that are now logged by shepherd
and visible in its log file.

** GOOPS

The GOOPS programming interface of shepherd, which was deprecated in 0.10.x,
is now gone.  See “Legacy GOOPS Interface” for more information.

** Reproducible source tarball

The ‘shepherd-1.0.0.tar.gz’ file distributed at ftp.gnu.org is now bit-for-bit
reproducible from the corresponding Git tag.  This was prompted by
vulnerabilities that propped up in the XZ package in April 2024
(CVE-2024-3094); code itself borrows from what Janneke Nieuwenhuizen did for
Guix.

** Updated requirements: Guile, gzip, zstd

Guile 2.2 is no longer supported; Guile 3.0.x is required.

The log rotation service can use the ‘gzip’ and ‘zstd’ commands.  Use the
‘--with-gzip’ and ‘--with-zstd’ configure options to specify the file name of
the commands to use.

** Translations

This version is fully translated in German, Romanian, Swedish, and Ukranian;
it is partially translated in eight other languages.  Check out
https://translationproject.org/domain/shepherd.html to help translate it into
your language!

* Changes in 0.10.5

** ‘herd unload root SERVICE’ no longer hangs when there’s a replacement
   (<https://issues.guix.gnu.org/71478>)

It used to be that, for a running service S that has a replacement registered,
‘herd unload root S’ would hang shepherd, making it totally unresponsive—‘herd
status’, ‘halt’, etc. would hang forever, and inetd-style services would no
longer start, etc.  This is now fixed.

* Changes in 0.10.4

** ‘herd unload root all’ stops services before unregistering them

Previously, since version 0.10.0, ‘herd unload root all’ would unregister all
services without first stopping them, leaving the system in a bogus state.

** ‘shepherd’ no longer bails out when reboot(2) returns ENOSYS

In runc environments (among others), reboot(RB_DISABLE_CAD) returns ENOSYS,
which would lead shepherd to fail to start.  This would prevent the use of
shepherd in some containerized environments such as those of GitLab-CI.

** REPL service no longer attempts to enter debugger upon error

The REPL service would spawn a regular REPL that enters a debugger (or
“recursive prompt”) by default.  While this is a great feature, it could
easily render the shepherd REPL unusable because the continuation of the
debugger prompt could not always be suspended—see the thread at
https://lists.gnu.org/archive/html/guix-devel/2024-01/msg00064.html.  To avoid
that, the REPL now simply displays a backtrace upon error.

* Changes in 0.10.3

** Fix a bug that could lead shepherd to hang after loading replacements
   (<https://issues.guix.gnu.org/67839>)

After loading replacements with ‘herd load’ or ‘guix system reconfigure’,
shepherd could eventually hang.  Specifically, the replaced service would no
longer respond to messages, so it would be impossible to start it, to stop it,
or to unload it.  This is now fixed.

** Fix ownership and permissions on Unix-domain sockets
   (<https://issues.guix.gnu.org/67867>)

When using an AF_UNIX endpoint with systemd- and inetd-style services, the
socket file itself would remain owned by root (when shepherd is running as
root) with permissions 755.  This is now fixed, with ownership set according
to #:socket-owner and #:socket-group of the endpoint, and permissions on the
socket set to 666.

Likewise, #:socket-directory-permissions was previously ignored when the
socket’s directory already existed prior to creating the endpoint, potentially
leading to unexpectedly wide access to the socket.  This is now fixed.

** New #:respawn-delay parameter to ‘service’
   (<https://issues.guix.gnu.org/64665>)

This specifies a delay before a service is respawned.  Its default value is
given by ‘default-respawn-delay’ and defaults to 100ms.  Until now, services
were respawned immediately.

** Non-blocking ‘sleep’ replacement provided

Until now, user code could call (@ (guile) sleep), the core Guile binding for
‘sleep’, instead of ‘sleep’ as provided by (fibers).  The former would have
caused ‘shepherd’ to actually sleep for that time, instead of performing other
on-going tasks.  ‘sleep’ is now replaced by (@ (fibers) sleep) to avoid that.

** Ensure termination of services that failed to produce a PID file

When a service started with the #:pid-file argument of
‘make-forkexec-constructor’ or similar would fail to produce its PID file, the
process that was spawned would be sent SIGTERM.  Now, it is additionally sent
SIGKILL after ‘default-process-termination-grace-period’ has expired, as is
the case when using ‘make-kill-destructor’.

** Do not accidentally wait for Linux kernel thread completion
   (<https://issues.guix.gnu.org/67132>)

In cases a PID file contained a bogus PID or one that’s only valid in a
separate PID namespace, shepherd could end up waiting for the termination of
what’s actually a Linux kernel thread, such as PID 2 (“kthreadd”).  This
situation is now recognized and avoided.

** Fix portability issues to GNU/Hurd

Previous versions in the 0.10.x and 0.9.x series did not work on GNU/Hurd.
This is now fixed, although some features are still implemented in a
suboptimal way.

** Fix cross-compilation to non-Linux operating systems

Since 0.10.2, when cross-compiling to systems such as GNU/Hurd, the value of
‘SFD_CLOEXEC’ and ‘SFD_NONBLOCK’ in (shepherd system) would be left undefined,
leading to a type error when starting shepherd.  This is now fixed.

** Updated translations: de, ro, sr, sv, uk

This release is fully translated to German, Romanian, Swedish, and Ukrainian;
partial translations are available for a dozen of languages.  To help make the
Shepherd speak your language, check out the Translation Project:

  https://translationproject.org/domain/shepherd.html

* Changes in 0.10.2

** ‘shepherd’ loads configuration file asynchronously

Up to 0.10.1, ‘shepherd’ would load the user-provided configuration file
synchronously: it would write its PID file and start listening for incoming
connections only after the configuration file has been loaded.  The
configuration file is now loaded in the background, letting users interact
with shepherd (using the ‘herd’ command) early on.

** ‘shepherd’ keeps going upon configuration file errors
   (<https://issues.guix.gnu.org/63982>)

Up to 0.10.1, ‘shepherd’ would abruptly exit when an error would occur while
loading the configuration file—service startup failure, uncaught exception,
etc.  It now reports the error but keeps going, again letting users fix any
problems dynamically.

** New #:respawn-limit parameter to ‘service’

The ‘service’ form supports a new #:respawn-limit parameter to specify
per-service respawn limits.

** Disabled services are truly disabled
   (<https://issues.guix.gnu.org/64008>)

Previously, manually running ‘herd disable SERVICE’ would not prevent SERVICE
from being respawned or even from being started.  This is now fixed.

** Disabled flag is preserved when replacing a service
   (<https://issues.guix.gnu.org/63869>)

When replacing a service, for instance by running ‘herd load root conf.scm’ or
by running ‘guix system reconfigure’, the service replacement starts as
disabled if the original service was disabled.

** Signals are properly handled after ‘daemonize’
   (<https://issues.guix.gnu.org/63982>)

Starting with version 0.9.0, calling the ‘daemonize’ action on the ‘root’
service would cause shepherd to miss signals; in particular, it would miss
SIGCHLD signals, making it hardly usable.  This is now fixed.

** New ‘unregister-services’ procedure
   (<https://issues.guix.gnu.org/64365>)

The (shepherd service) module now exports ‘unregister-services’.

** New Bash completion

A Bash completion file is now installed, providing tab completion for the
‘herd’ command.

** ‘herd’ shows a hint when the service and action are likely swapped

The hint is printed for instance when typing ‘herd foobar start’.

** Updated translations: de, ro, sv, uk

This release is fully translated to German, Romanian, Swedish, and Ukrainian;
partial translations are available for a dozen of languages.  To help make the
Shepherd speak your language, check out the Translation Project:

  https://translationproject.org/domain/shepherd.html

* Changes in 0.10.1

** Configurable number of ‘bind’ attempts for endpoints

The ‘endpoint’ procedure takes a new ‘#:bind-attempts’ parameter.  Its default
value is (default-bind-attempts), itself a new SRFI-39 parameter.

** New ‘default-respawn-limit’ parameter

This SRFI-39 parameter lets users configure the respawn limit for respawnable
services.  See “Service De- and Constructors” in the manual.

** ‘herd restart SERVICE’ starts the replacement, not the original service
   <https://issues.guix.gnu.org/63717>

In 0.10.0, when a service had received a replacement (for instance via ‘guix
system reconfigure’), using ‘herd restart’ would invoke the ‘start’ method of
the original service while installing its replacement in the registry.

This would lead to an inconsistency where the registry would show the new
service (typically failing to start) while the original service would still be
running “in the shadows” (responding to SIGCHLD or to incoming connections,
and so on).

** ‘herd restart SERVICE’ does not restart transient services

In 0.10.0, ‘herd restart’ could end up attempt to restart transient services,
which is bound to fail and could even lead to a deadlock since the service has
been terminated.

* Changes in 0.10.0

** Distinguish ‘starting’ and ‘stopping’ intermediate service statuses

In previous version, a service would be either “running” or “stopped”.  The
intermediate states “starting” and “stopping” are now properly captured and
you can see them when running ‘herd status’.

** ‘start’ and ‘stop’ block when service is already being started/stopped
  <https://issues.guix.gnu.org/54786#4>

With previous version, a client running ‘herd start SERVICE’ while SERVICE is
already being started would cause shepherd to attempt to start a second
instance of that service, ultimately resulting in confusion, disappointment,
and frustration.

This is no longer the case: when a service is already being started/stopped,
additional invocation of ‘herd start’ or ‘herd stop’ now block until the
service is running/stopped.

** ‘shepherd’ starts services in parallel

Services started with ‘start-in-the-background’ and more generally service
dependencies get started in parallel.  This can reduce startup times in case
of a “wide” service dependency graph with some services that take a while to
start.

** ‘shepherd’ keeps track of failures and status change times

For each service, shepherd maintains an event log including the time of recent
status changes as well as the time of startup failures, if any.  The ‘herd
status SERVICE’ command now shows the time when the service entered its
current status and whether it failed to start; ‘herd status’ also prominently
lists services that failed to start.

** New ‘herd log’ command

Related to the previous item, the new ‘herd log’ command displays an aggregate
of the service event logs, showing the time at which each service changed
statuses.

** New ‘herd graph’ command

The new ‘herd graph’ command emits a Graphviz/Dot representation of the
service dependency graph, which can be viewed for example with ‘xdot’:

  herd graph | xdot -

Guix System users get similar information with ‘guix system shepherd-graph’
(and likewise for Guix Home).  The difference here is that this reflects the
current system status, showing transient services, services that failed to
start, and so on.

** ‘herd’ output is colorized

At long last!  We hope you’ll enjoy a little bit of coloring to highlight
important bits in the output of various commands.

** New services shipped: ‘monitoring’ and ‘repl’

The Shepherd now ships with optional services—see “Service Collection” in the
manual.  The ‘monitoring’ service logs resource usage of the ‘shepherd’
process itself.  The ‘repl’ service runs a read-eval-print loop (REPL) in the
‘shepherd’ so you can hack it live—enjoy it, but handle it with care!

** Socket-actived, systemd-style services can now be started eagerly

The ‘make-systemd-constructor’ procedure has a new #:lazy-start? parameter.
It defaults to #true, meaning that the process is started lazily, on the first
connection to one of its sockets, as was the case in 0.9.x.  Passing
#:lazy-start? #false instructs shepherd to instead start the process eagerly,
as soon as the listening sockets are ready.

This is useful for services that require socket activation as a startup
synchronization mechanism, yet are expected to run as soon as possible.  An
example is ‘guix publish --advertise’: it should be started eagerly so it can
start advertising itself via Avahi.

** Each registered name maps to exactly one service

There used to be a fuzzy notion of “conflicting services”, when a given
service name could potentially refer to more than one service.  This has
proved to be confusing more than anything else; now, each registered service
name refers to exactly one service.  The interface related to that feature,
such as the ‘conflicts-with’ method, is done.

** For systemd and inetd services, retry ‘bind’ upon EADDRINUSE
   <https://issues.guix.gnu.org/58485#13>

Services started with ‘make-systemd-constructor’ and ‘make-inetd-constructor’
will now retry several times when ‘bind’ returns EADDRINUSE (“Address already
in use”) for their listening socket(s).

** ‘system’ and ‘make-system-constructor’ are now non-blocking
   <https://issues.guix.gnu.org/61803>

In versions up to 0.9.3, calling Guile’s ‘system’ procedure (which is what
‘make-system-constructor’ does) would block the ‘shepherd’ process until the
shell spawned by ‘system’ has terminated.  This is no longer the case.

** GOOPS interface is deprecated

When it was created in 2002, the Shepherd (née dmd) embraced GOOPS, Guile’s
object-oriented programming system, then a brand new and promising approach
for 21st century programs.  In hindsight, while there were a couple of classes
and a bunch of methods, the code base was not really making much use of GOOPS.
The current maintainer deemed it unnecessary and encouraging a programming
style at odds with the shiny horizon of purely functional, actor-style
programming.

The GOOPS interface is still available in 0.10.0; for example, you can still
write ~(make <service> #:provides …)~ in your configuration file.  However,
GOOPS support will be removed in the next major series, most likely labeled
1.0.

A new interface has been defined.  Check out the “Legacy GOOPS Interface”
section of the manual for more information, and email guix-devel@gnu.org if
you have any questions or concerns.

** Interfaces removed and changed

Several obscure or undocumented interfaces were removed:

  - support for the ‘unknown’ service;
  - support for “persistency” (sic);
  - the ‘cd’ action of the ‘root’ service;
  - the ‘launch-service’ procedure of (shepherd service).

New deprecations:

  - ‘make-actions’ is deprecated in favor of ‘actions’;
  - calling ‘register-services’ with an arbitrary number of arguments is now
    deprecated; you should now call it with a single argument, the list of
    services to register.

** Major internal overhaul

As you can guess from the list of user-visible changes above, the Shepherd has
undergone a major internal overhaul.  The 0.9.x series introduced the use of
Fibers, Guile’s lightweight concurrent facility; shepherd took advantage of it
notably with the introduction of systemd-style and inetd-style services.  This
new stable series takes it further.

In particular, each <service> record has an associated fiber called the
“service controller”.  Following the actor model, each of these fibers reacts
to messages it receives, be they event notification—e.g., process
termination—or user requests—e.g., querying the service status, requesting
that the service be stopped.  Other noteworthy actors include the “process
monitor” and the “service registry”.

This has allowed us to address a number of race conditions while also leading
to clearer code with linear flows that one can more easily reason about.
Overall, it makes the code base much more pleasant to work with and certainly
easier to hack than other implementations mired in the “callback hell”.

Documentation has been overhauled as well to reflect all these changes.  Check
out the new subsections under “Services” for more information.

** Updated translations: de, ro, uk

The Shepherd is fully translated in German, Romanian, and Ukrainian; partial
translations are available for a dozen of languages.  To help make the
Shepherd speak your language, check out the Translation Project:

  https://translationproject.org/domain/shepherd.html

* Changes in version 0.9.3

** Service ‘stop’ is now synchronous
   <https://issues.guix.gnu.org/58485>

Previously, ‘herd stop SERVICE’ would send SIGTERM to the service’s process
and immediately move on without waiting for the process to actually terminate.
This could cause problems for example when running ‘herd restart SERVICE’:
there was a possibility that a new instance of the service would be spawned
before the previous one had terminated.

This is now fixed: ‘stop’ only returns once the process has actually
terminated.  Furthermore, the destructor returned by ‘make-kill-destructor’
sends SIGKILL after some grace period has expired if the process is still
around; this is configurable with #:grace-period and
‘default-process-termination-grace-period’.

** Non-blocking replacement for ‘system*’
   <https://issues.guix.gnu.org/56674>.

Service code can now call ‘system*’ lightheartedly: shepherd installs a
cooperative, non-blocking replacement for Guile’s ‘system*’ procedure.
Concretely, it means that it’s OK to use ‘system*’, say, in the ‘start’ method
of a service: it won’t block shepherd, one can still interact with it with
‘herd’.

** Fewer continuation barriers

The ‘stop’ method of services, and ‘eval’ and ‘load’ actions of the ‘root’
service, and a few other points acted as “continuation barriers”, meaning that
user code would not be allowed to suspend the current fiber for example by
calling the ‘sleep’ procedure from (fiber).  These limitations have been
lifted.

** Reduced memory consumption while logging

Service output logging allocates less memory than before.

** Updated translations: ro, sr

* Changes in version 0.9.2
** File descriptors used internally are now all marked as close-on-exec

Previously, services started indirectly with ‘exec-command’ (which is usually
the case) would not inherit any file descriptor from shepherd because
‘exec-command’ would explicitly close all of them.  However, services started
with ‘make-system-constructor’ and processes created by some other means, such
as calling ‘system*’, would inherit some of those descriptors, giving them
more authority than intended.

The change here consists in marking all internally-used file descriptors as
“close-on-exec” (O_CLOEXEC), a feature that’s been available on GNU/Linux and
GNU/Hurd for years but that so far wasn’t used consistently in shepherd.  This
is now fixed.  As a side-effect, the file-descriptor-closing loop in
‘exec-command’ is now gone.

** Client connections with ‘herd’ are non-blocking

Previously, a misbehaving client could send an incomplete command
(s-expression), causing shepherd to hang while waiting for completion.  (Note
that said client is required to run with the same UID as shepherd, so this was
not a security issue.)

** Directory of log file is created if it doesn’t exist

When a service constructor is passed ‘#:log-file "/var/log/foo/bar.log"’,
shepherd now created /var/log/foo if it doesn’t exist; previously it would
fail gracelessly.

* Changes in version 0.9.1
** ‘make-inetd-constructor’ now accepts a list of endpoints

In 0.9.0, ‘make-inetd-constructor’ would take a single address as returned by
‘make-socket-address’.  This was insufficiently flexible since it didn’t let
you have an inetd service with multiple endpoints.  ‘make-inetd-constructor’
now takes a list of endpoints, similar to what ‘make-systemd-constructor’
already did.

For compatibility with 0.9.0, if the second argument to
‘make-systemd-constructor’ is an address, it is automatically converted to a
list of endpoints.  This behavior will be preserved for at least the whole
0.9.x series.

** ‘AF_INET6’ endpoints are now interpreted as IPv6-only

In 0.9.0, using an ‘AF_INET6’ endpoint for ‘make-systemd-constructor’ would
usually have the effect of making the service available on both IPv6 and IPv4.
This is due to the default behavior of Linux, which is to bind IPv6 addresses
as IPv4 as well (the default behavior can be changed by running
‘sysctl net.ipv6.bindv6only 1’).

‘AF_INET6’ endpoints are now interpreted as IPv6-only.  Thus, if a service is
to be made available both as IPv6 and IPv4, two endpoints must be used.

** ‘shepherd’ reports whether a service is transient
** ‘herd status’ shows whether a service is transient
** Fix possible file descriptor leak in ‘make-inetd-constructor’
   (<https://issues.guix.gnu.org/55223>)
** Fix value of ‘LISTEN_FDNAMES’ variable set by ‘make-systemd-constructor’
** Fix crash when logging IPv6 addresses
** ‘start-in-the-background’ returns *unspecified* instead of zero values

* Changes in version 0.9.0
** The Shepherd now depends on Fibers 1.1.0 or later
** ‘shepherd’ no longer blocks when waiting for PID files, etc.
** Services without #:log-file have their output written to syslog
** Services with #:log-file have their output timestamped
** New ‘make-inetd-constructor’ procedure for inetd-style services
** New ‘make-systemd-constructor’ for systemd-style “socket activation”
** New ‘start-in-the-background’ procedure
** Services can now be “transient” (see the manual for details)
** New #:supplementary-groups parameter for ‘make-forkexec-constructor’
** New #:create-session? parameter for ‘make-forkexec-constructor’
** New #:resource-limits parameter for ‘make-forkexec-constructor’
** Log file of unprivileged ‘shepherd’ is now under $XDG_DATA_DIR
** Do not reboot upon ‘quit’ when running as root but not PID 1
** Improved documentation and examples
** The Shepherd can no longer be built with Guile 2.0
** Work around Guile 3.0.[5-7] compiler bug
   (<https://bugs.gnu.org/47172>)
** Updated translations: da, de, sv, uk

* Changes in version 0.8.1
** Fix race condition that could lead shepherd to stop itself
   (<https://bugs.gnu.org/40981>)
** Use ‘signalfd’ on GNU/Linux to improve efficiency and simplify code
** Outdated bits have been removed from the manual
** Updated translation: sv

* Changes in version 0.8.0
** Kill the whole process group when the PID file doesn’t show up
   (<https://bugs.gnu.org/40672>)
** ‘make-kill-destructor’ kills the process group
** New ‘default-pid-file-timeout’ SRFI-39 parameter
** New #:file-creation-mask parameter for ‘make-forkexec-constructor’
** ‘make-forkexec-constructor’ creates log files as #o640
   (<https://bugs.gnu.org/40405>)
** Improve documentation and examples
** Ensure man pages are up to date
   (<https://bugs.gnu.org/39694>)
** Fix compilation on systems without ‘prctl’ such as GNU/Hurd
** Remove kludge that would send SIGALRM every second
** Address “error in finalization thread” warning
** ‘make-forkexec-constructor’ no longer supports old calling convention

The first argument must be a list of strings.  Passing several strings has
been deprecated since 0.1.

* Changes in version 0.7.0
** New crash handler allows shepherd as PID 1 to dump core on GNU/Linux
** (shepherd service) now exports ‘default-environment-variables’
** ‘make-forkexec-constructor’ no longer removes log file
** Disable reboot on ctrl-alt-del before loading the config file
   (<https://bugs.gnu.org/35996>)
** Exception handling adjusted for Guile 3.0.0
* Changes in version 0.6.1
** ‘herd status’ distinguishes between “stopped” and “one-shot” services
** ‘read-pid-file’ gracefully handles PID files not created atomically
   (<https://bugs.gnu.org/35550>)
** ‘shepherd’ no longer crashes when asked to load files with syntax errors
   (<https://bugs.gnu.org/35631>)
** New translations: de, sk
** Updated translations: da, es, fr, pt_BR
* Changes in version 0.6.0
** Services can now be “one-shot” (see the manual for details)
** ‘shepherd’ deletes its socket file upon termination
** ‘herd stop S’ is no longer an error when S is already stopped
** ‘herd’ exits with non-zero when executing an action that fails
** ‘shepherd’ ignores reboot(2) errors when running in a container
** Translation of error messages has been fixed
** New translation: ta (Tamil)
** Updated translations: da, es, fr, pt_BR, sv, ta, uk, zh_CN
* Changes in version 0.5.0
** Services now have a ‘replacement’ slot
** Restarting a service now restarts its dependent services as well
** Gracefully halt upon ctrl-alt-del when running as PID 1 on GNU/Linux
** Actions can now be invoked on services not currently running
** Guile >= 2.0.13 is now required; Guile 3.0 is supported
** Unused runlevel code has been removed
** Updated translations: es, fr, pt_BR, sv
* Changes in version 0.4.0
** When running as non-root, keep track of forked processes
** When running as root, log to /dev/log (syslogd) or /dev/kmsg by default
** ‘exec-command’ opens log file in append mode
** Add native language support (5 languages currently supported)
** ‘log-output-port’ is now a SRFI-39 parameter
** New ‘make-shepherd-output-port’ in lieu of ‘shepherd-output-port’
** Fix non-deterministic test suite issues

* Changes in version 0.3.2
** ‘herd status’ displays a bullet list
** No longer crash when ‘enable’ & co. are passed a wrong argument number
   (<http://bugs.gnu.org/24684>)
** ‘make-forkexec-constructor’ has a new #:pid-file-timeout parameter
** Processes that failed to create their PID file are now killed
** .go files are now installed in LIBDIR/guile/2.X/site-ccache
** Build system supports compilation with Guile 2.2

* Changes in version 0.3.1
** Process respawn limit is honored again (regression introduced in 0.3)
** ‘herd status SERVICE’ displays the last respawn time, if any
** (shepherd service) exports ‘&action-runtime-error’ and related bindings
** ‘mkdir-p’ adjusted to cope with GNU/Hurd file system behavior

* Changes in version 0.3

** GNU dmd becomes the GNU Shepherd

The GNU Shepherd herds your daemons!
See http://www.gnu.org/software/shepherd/#history for details.
As a side effect, many incompatible changes were made:

  - The ‘dmd’ command was renamed to ‘shepherd’.
  - The ‘deco’ command was renamed to ‘herd’.
  - The default system-wide config file is now /etc/shepherd.scm.
  - The default per-user config file is now ~/.config/shepherd/init.scm.
  - The special ‘dmd’ service is now called ‘root’ and ‘shepherd’.  Thus,
    instead of:
       deco load dmd foo.scm
    you would now type:
       herd load root foo.scm
  - Guile modules now live in the (shepherd …) name space.

** ‘herd status’ and ‘herd detailed-status’ assumes the ‘root’ service

That is, ‘herd status’ is equivalent to ‘herd status root’.

** ‘herd help’ returns a meaningful help message
** ‘shepherd’ stops itself when it receives SIGINT

This is what happens when ‘shepherd’ is running as PID 1 on GNU/Linux and
ctrl-alt-del is pressed (see ctrlaltdel(8)).

** ‘halt’ and ‘reboot’ connect to the system socket unconditionally
** ‘herd’ uses a non-zero exit code upon errors
** The ‘root’ service has a new ‘eval’ action
** Basic man pages are now provided
** ‘make-forkexec-constructor’ has new #:group and #:user parameters
** ‘make-forkexec-constructor’ has a new #:pid-file parameter
** (shepherd services) now exports ‘make-actions’ and ‘provided-by’
** ‘shepherd --pid=FILE’ writes FILE atomically
** The communication protocol is now entirely sexp-based (see the manual)
** ‘shepherd’ is more robust to misbehaving clients
** Cross-compilation is now supported
** The build system uses “silent rules” by default
** Internally, the coding style of various parts has been improved

* Changes in version 0.2

** Non-root configuration file is now ~/.dmd.d/init.scm.

For unprivileged uses of dmd, the configuration file used to be
~/.dmdconf.scm.  It is now ~/.dmd.d/init.scm

** Generate template configuration file when none is found.

A ~/.dmd.d/init.scm template configuration file is now generated when
dmd is started and no such file exists.

** The 'dmd' service has new 'unload' and 'reload' actions.

The 'unload' action allows a service to be stopped and its definition to
be unloaded; 'reload' allows a service to be unloaded, and a new
redefinition to be reloaded, atomically.  See the manual for details.

** 'make-forkexec-constructor' has a new calling convention.

In particular, the procedure now has #:environment-variables
and #:directory arguments.  See the manual for details.

** New 'exec-command' and 'fork+exec-command' convenience procedures.
** The 'status' action displays the running value of services (the PID.)
** 'dmd' has a new '--pid' option.
** Failures to connect to dmd are gracefully handled.
** Data is always appended to the log file.
** Assorted bug fixes and documentation improvements.

* Changes in version 0.1
** A single socket is used for communication with dmd, with a new protocol.

The new communication protocol between 'dmd' and 'deco' is simpler,
versioned, and extensible.

** The default socket name is now independent of the calling user.
** The socket directory is now created under $(localstatedir).
** The 'dmd' service has new actions 'power-off' and 'halt'; 'stop' reboots

When dmd is running as root, as is the case when it is used as a
PID-one init system, these actions allow 'root' to cleanly reboot or
halt the machine.

** New 'reboot' and 'halt' commands.
** 'dmd' only write to stdout when no client is connected.
** The configuration file is loaded in a fresh module.
** 'make-forkexec-constructor' closes all file descriptors after forking.
** License upgraded to GPL version 3 or later.
** Manual license upgraded to FDL version 1.3 or later.
** Many bug fixes, documentation improvements, etc.

* Changes in version -0.4
** Awaken from a 10-year nap.
** Ported to Guile 2.0.
** Modules are modules instead of being loaded.
** Build system fixes, cleanups, and upgrades.

* Changes in version -0.5
** dmd: `--socket=-' instead of `--socket=none'.
** Renamed `extra-action' to plain `action'.
** The result of user-defined stop code is ignored now.
** New action for all services: `dmd-status'.
** Distribution contains file `QUESTIONS'.
** Improved the `unknown' service implementation in `examples/'.
** Number of args given to actions is verified.
** Made docstrings for actions optional.
** Renamed `{en,dis}able-persistency' to `{,no-}persistency'.
** Can pass file name to dmd action `persistency'.

* Changes in version -0.6
** New action `doc' for displaying documentation.
** `list-actions' is a sub-action of `doc' now.
** New action `cd' for dmd, useful with `--socket=none'.
** Distribution contains example for an `unknown' service.
** At configure time, dmd checks for a Guile installation.
** Enable readline on `--socket=none' and non-dumb terminal.
** Startup time finally became completely unacceptable. :-)

* Changes in version -0.7
** Can fork into background via dmd extra-action `daemonize'.
** New action for all services: list-actions.
** New options for dmd: --logfile (-l), and --silent/--quiet
** Standard option --usage works for both dmd and deco.
** You can pass relative file names to deco.
** Never send respawn-output to deco by accident.
** Better handling of terminals and similar services.
** Documented evolution of runlevels.
** Service groups can be used to start/stop services at once.
** Persistency (i.e. safe state on exit and restore next time).
** Invoke actions of service `unknown' (if defined) as fallback.
** Read commands from standard input if socket file name is `none'.

* Changes in version -0.8
** Show output in deco, not only in dmd.
** New options in deco: --insecure (-I) and --result-socket (-r)
** --help displays the options for both dmd and deco.
** Disable services which are respawning too fast.
** New actions for all services: enable, disable and enforce.
** Default extra actions work even when the service is stopped.
** Documented some internals of dmd.

* Changes in version -0.9
** Example configuration added.
** New option for deco: --socket (-s).
** New option for dmd: --insecure (-I).
** Added tutorial and completed documentation.
** Create default socket dir on startup if desired.
** Added a real build system.

* Changes in Version -0.9.6
** Controlling dmd completely with deco is now possible.
** A few bugfixes for service handling.
** Long options can be abbreviated, short ones also work.
** Respawning of services works.

* Changes in version -0.9.7
** User-defined code is always protected with a `catch'.
** New options: --config and --socket.
** The new deco program can be used to send commands to dmd.

* Changes in version -0.9.8
** Starting and stopping of services by symbol works better.
** Performing extra actions on services possible.
** Improved documentation.
** More detailed output.

* Version -0.9.9
** Initial release.
