summary refs log tree commit diff
path: root/gnu/services
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-06-08 14:46:24 +0200
committerLudovic Courtès <ludo@gnu.org>2022-06-08 14:46:24 +0200
commit8c3e9da13a3c92a7db308db8c0d81cb474ad7799 (patch)
tree88d06952aa5cc3a9c4991d9c43eb7950ff174fe1 /gnu/services
parent5439c04ebdb7b6405f5ea2446b375f1d155a8d95 (diff)
parent0c5299200ffcd16370f047b7ccb187c60f30da34 (diff)
downloadguix-8c3e9da13a3c92a7db308db8c0d81cb474ad7799.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/admin.scm57
-rw-r--r--gnu/services/base.scm98
-rw-r--r--gnu/services/databases.scm17
-rw-r--r--gnu/services/desktop.scm85
-rw-r--r--gnu/services/dict.scm64
-rw-r--r--gnu/services/dns.scm186
-rw-r--r--gnu/services/games.scm33
-rw-r--r--gnu/services/guix.scm28
-rw-r--r--gnu/services/herd.scm84
-rw-r--r--gnu/services/kerberos.scm12
-rw-r--r--gnu/services/lirc.scm6
-rw-r--r--gnu/services/mail.scm15
-rw-r--r--gnu/services/messaging.scm122
-rw-r--r--gnu/services/monitoring.scm9
-rw-r--r--gnu/services/networking.scm294
-rw-r--r--gnu/services/nfs.scm24
-rw-r--r--gnu/services/shepherd.scm68
-rw-r--r--gnu/services/spice.scm5
-rw-r--r--gnu/services/ssh.scm45
-rw-r--r--gnu/services/sysctl.scm4
-rw-r--r--gnu/services/telephony.scm408
-rw-r--r--gnu/services/virtualization.scm9
-rw-r--r--gnu/services/vpn.scm13
-rw-r--r--gnu/services/web.scm15
-rw-r--r--gnu/services/xorg.scm3
25 files changed, 1126 insertions, 578 deletions
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index 043517262f..0b4ecaeb83 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
-;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -46,6 +46,13 @@
             rottlog-service
             rottlog-service-type
 
+            log-cleanup-service-type
+            log-cleanup-configuration
+            log-cleanup-configuration?
+            log-cleanup-configuration-directory
+            log-cleanup-configuration-expiry
+            log-cleanup-configuration-schedule
+
             unattended-upgrade-service-type
             unattended-upgrade-configuration
             unattended-upgrade-configuration?
@@ -95,7 +102,9 @@
                                      read)))
                           (kill pid SIGHUP))))
         (log-rotation
-         (files '("/var/log/guix-daemon.log")))))
+         (files '("/var/log/guix-daemon.log"))
+         (options '("rotate 4"                    ;don't keep too many of them
+                    "storefile @FILENAME.@COMP_EXT")))))
 
 (define (log-rotation->config rotation)
   "Return a string-valued gexp representing the rottlog configuration snippet
@@ -193,6 +202,50 @@ Old log files are removed or compressed according to the configuration.")
 
 
 ;;;
+;;; Build log removal.
+;;;
+
+(define-record-type* <log-cleanup-configuration>
+  log-cleanup-configuration make-log-cleanup-configuration
+  log-cleanup-configuration?
+  (directory log-cleanup-configuration-directory) ;string
+  (expiry    log-cleanup-configuration-expiry     ;integer (seconds)
+             (default (* 6 30 24 3600)))
+  (schedule  log-cleanup-configuration-schedule   ;string or gexp
+             (default "30 12 01,08,15,22 * *")))
+
+(define (log-cleanup-program directory expiry)
+  (program-file "delete-old-logs"
+                (with-imported-modules '((guix build utils))
+                  #~(begin
+                      (use-modules (guix build utils))
+
+                      (let* ((now  (car (gettimeofday)))
+                             (logs (find-files #$directory
+					       (lambda (file stat)
+					         (> (- now (stat:mtime stat))
+						    #$expiry)))))
+                        (format #t "deleting ~a log files from '~a'...~%"
+                                (length logs) #$directory)
+                        (for-each delete-file logs))))))
+
+(define (log-cleanup-mcron-jobs configuration)
+  (match-record configuration <log-cleanup-configuration>
+    (directory expiry schedule)
+    (list #~(job #$schedule
+                 #$(log-cleanup-program directory expiry)))))
+
+(define log-cleanup-service-type
+  (service-type
+   (name 'log-cleanup)
+   (extensions
+    (list (service-extension mcron-service-type
+                             log-cleanup-mcron-jobs)))
+   (description
+    "Periodically delete old log files.")))
+
+
+;;;
 ;;; Unattended upgrade.
 ;;;
 
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index f278cb76de..6865d03f25 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -219,8 +219,6 @@
             pam-limits-service-type
             pam-limits-service
 
-            references-file
-
             %base-services))
 
 ;;; Commentary:
@@ -1399,23 +1397,24 @@ responsible for logging system messages.")))
      # level notice or higher and anything of level err or
      # higher to the console.
      # Don't log private authentication messages!
-     *.alert;auth.notice;authpriv.none       /dev/console
+     *.alert;auth.notice;authpriv.none      -/dev/console
 
      # Log anything (except mail) of level info or higher.
      # Don't log private authentication messages!
-     *.info;mail.none;authpriv.none          /var/log/messages
+     *.info;mail.none;authpriv.none         -/var/log/messages
 
-     # Like /var/log/messages, but also including \"debug\"-level logs.
-     *.debug;mail.none;authpriv.none         /var/log/debug
+     # Log \"debug\"-level entries and nothing else.
+     *.=debug                               -/var/log/debug
 
      # Same, in a different place.
-     *.info;mail.none;authpriv.none          /dev/tty12
+     *.info;mail.none;authpriv.none         -/dev/tty12
 
      # The authpriv file has restricted access.
+     # 'fsync' the file after each line (hence the lack of a leading dash).
      authpriv.*                              /var/log/secure
 
      # Log all the mail messages in one place.
-     mail.*                                  /var/log/maillog
+     mail.*                                 -/var/log/maillog
 "))
 
 (define* (syslog-service #:optional (config (syslog-configuration)))
@@ -1440,7 +1439,8 @@ information on the configuration file syntax."
                               (module "pam_limits.so")
                               (arguments '("conf=/etc/security/limits.conf")))))
              (if (member (pam-service-name pam)
-                         '("login" "su" "slim" "gdm-password" "sddm"))
+                         '("login" "su" "slim" "gdm-password" "sddm"
+                           "sudo" "sshd"))
                  (pam-service
                   (inherit pam)
                   (session (cons pam-limits
@@ -1768,26 +1768,6 @@ proxy of 'guix-daemon'...~%")
               (substitute-key-authorization authorized-keys guix)
               #~#f))))
 
-(define* (references-file item #:optional (name "references"))
-  "Return a file that contains the list of references of ITEM."
-  (if (struct? item)                              ;lowerable object
-      (computed-file name
-                     (with-extensions (list guile-gcrypt) ;for store-copy
-                       (with-imported-modules (source-module-closure
-                                               '((guix build store-copy)))
-                         #~(begin
-                             (use-modules (guix build store-copy))
-
-                             (call-with-output-file #$output
-                               (lambda (port)
-                                 (write (map store-info-item
-                                             (call-with-input-file "graph"
-                                               read-reference-graph))
-                                        port))))))
-                     #:options `(#:local-build? #f
-                                 #:references-graphs (("graph" ,item))))
-      (plain-file name "()")))
-
 (define guix-service-type
   (service-type
    (name 'guix)
@@ -1877,13 +1857,7 @@ raise a deprecation warning if the 'compression-level' field was used."
   (match-record config <guix-publish-configuration>
     (guix port host nar-path cache workers ttl negative-ttl
           cache-bypass-threshold advertise?)
-    (list (shepherd-service
-           (provision '(guix-publish))
-           (requirement `(user-processes
-                          guix-daemon
-                          ,@(if advertise? '(avahi-daemon) '())))
-           (start #~(make-forkexec-constructor
-                     (list #$(file-append guix "/bin/guix")
+    (let ((command #~(list #$(file-append guix "/bin/guix")
                            "publish" "-u" "guix-publish"
                            "-p" #$(number->string port)
                            #$@(config->compression-options config)
@@ -1913,17 +1887,39 @@ raise a deprecation warning if the 'compression-level' field was used."
                                         "--cache-bypass-threshold="
                                         (number->string
                                          cache-bypass-threshold)))
-                                  #~()))
-
-                     ;; Make sure we run in a UTF-8 locale so we can produce
-                     ;; nars for packages that contain UTF-8 file names such
-                     ;; as 'nss-certs'.  See <https://bugs.gnu.org/26948>.
-                     #:environment-variables
-                     (list (string-append "GUIX_LOCPATH="
-                                          #$glibc-utf8-locales "/lib/locale")
-                           "LC_ALL=en_US.utf8")
-                     #:log-file "/var/log/guix-publish.log"))
-           (stop #~(make-kill-destructor))))))
+                                  #~())))
+          (options #~(#:environment-variables
+                      ;; Make sure we run in a UTF-8 locale so we can produce
+                      ;; nars for packages that contain UTF-8 file names such
+                      ;; as 'nss-certs'.  See <https://bugs.gnu.org/26948>.
+                      (list (string-append "GUIX_LOCPATH="
+                                           #$glibc-utf8-locales "/lib/locale")
+                            "LC_ALL=en_US.utf8")
+                      #:log-file "/var/log/guix-publish.log"))
+          (endpoints #~(let ((ai (false-if-exception
+                                  (getaddrinfo #$host
+                                               #$(number->string port)
+                                               AI_NUMERICSERV))))
+                         (if (pair? ai)
+                             (list (endpoint (addrinfo:addr (car ai))))
+                             '()))))
+      (list (shepherd-service
+             (provision '(guix-publish))
+             (requirement `(user-processes
+                            guix-daemon
+                            ,@(if advertise? '(avahi-daemon) '())))
+
+             ;; Use lazy socket activation unless ADVERTISE? is true: in that
+             ;; case the process should start right away to advertise itself.
+             (start #~(if (and (defined? 'make-systemd-constructor) ;> 0.9.0?
+                               #$(not advertise?))
+                          (make-systemd-constructor
+                           #$command #$endpoints #$@options)
+                          (make-forkexec-constructor #$command #$@options)))
+             (stop #~(if (and (defined? 'make-systemd-destructor)
+                              #$(not advertise?))
+                         (make-systemd-destructor)
+                         (make-kill-destructor))))))))
 
 (define %guix-publish-accounts
   (list (user-group (name "guix-publish") (system? #t))
@@ -2197,7 +2193,8 @@ instance."
                              (service-extension
                               account-service-type account-extension)
                              (service-extension
-                              udev-service-type udev-extension))))))
+                              udev-service-type udev-extension)))
+                (description "This service adds udev rules."))))
     (service type #f)))
 
 (define (swap-space->shepherd-service-name space)
@@ -2817,6 +2814,11 @@ to handle."
 
         (service rottlog-service-type)
 
+        ;; Periodically delete old build logs.
+        (service log-cleanup-service-type
+                 (log-cleanup-configuration
+                  (directory "/var/log/guix/drvs")))
+
         ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
         ;; used, so enable them by default.  The FUSE and ALSA rules are
         ;; less critical, but handy.
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 15a2036037..fb3cd3c478 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
 ;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
@@ -328,7 +328,8 @@ host	all	all	::1/128 	md5"))
            profile-service-type
            (compose list postgresql-configuration-postgresql))))
    (default-value (postgresql-configuration
-                   (postgresql postgresql-10)))))
+                   (postgresql postgresql-10)))
+   (description "Run the PostgreSQL database server.")))
 
 (define-deprecated (postgresql-service #:key (postgresql postgresql)
                                        (port 5432)
@@ -514,7 +515,10 @@ created after the PostgreSQL database is started.")))
                                           (const memcached-activation))
                        (service-extension account-service-type
                                           (const %memcached-accounts))))
-                (default-value (memcached-configuration))))
+                (default-value (memcached-configuration))
+                (description "Run @command{memcached}, a daemon that provides
+an in-memory caching service, intended for use by dynamic web
+applications.")))
 
 
 ;;;
@@ -680,7 +684,9 @@ FLUSH PRIVILEGES;
                              %mysql-activation)
           (service-extension shepherd-root-service-type
                              mysql-shepherd-services)))
-   (default-value (mysql-configuration))))
+   (default-value (mysql-configuration))
+   (description "Run the MySQL or MariaDB database server,
+@command{mysqld}.")))
 
 (define-deprecated (mysql-service #:key (config (mysql-configuration)))
   mysql-service-type
@@ -759,4 +765,5 @@ FLUSH PRIVILEGES;
                                           redis-activation)
                        (service-extension account-service-type
                                           (const %redis-accounts))))
-                (default-value (redis-configuration))))
+                (default-value (redis-configuration))
+                (description "Run Redis, a caching key/value store.")))
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index ecadb16b2f..0499071436 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014-2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
@@ -366,7 +366,11 @@ users are allowed."
                  (list (service-extension dbus-root-service-type
                                           geoclue-dbus-service)
                        (service-extension account-service-type
-                                          (const %geoclue-accounts))))))
+                                          (const %geoclue-accounts))))
+                (description "Run the @command{geoclue} location service.
+This service provides a D-Bus interface to allow applications to request
+access to a user's physical location, and optionally to add information to
+online location databases.")))
 
 (define* (geoclue-service #:key (geoclue geoclue)
                           (whitelist '())
@@ -914,7 +918,11 @@ screens and scanners.")))
 
                          ;; Profile 'udisksctl' & co. in the system profile.
                          (service-extension profile-service-type
-                                            udisks-package))))))
+                                            udisks-package)))
+                  (description "Run UDisks, a @dfn{disk management} daemon
+that provides user interfaces with notifications and ways to mount/unmount
+disks.  Programs that talk to UDisks include the @command{udisksctl} command,
+part of UDisks, and GNOME Disks."))))
 
 (define* (udisks-service #:key (udisks udisks))
   "Return a service for @uref{http://udisks.freedesktop.org/docs/latest/,
@@ -1067,10 +1075,60 @@ include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
    ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
 
 (define (elogind-dbus-service config)
-  (list (wrapped-dbus-service (elogind-package config)
-                              "libexec/elogind/elogind"
-                              `(("ELOGIND_CONF_FILE"
-                                 ,(elogind-configuration-file config))))))
+  "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to
+\"start\" elogind.  In practice though, our elogind is started when booting by
+shepherd.  Thus, the @code{Exec} line of this @file{.service} file does not
+explain how to start elogind; instead, it spawns a wrapper that waits for the
+@code{elogind} shepherd service.  This avoids a race condition where both
+@command{shepherd} and @command{dbus-daemon} would attempt to start elogind."
+  ;; For more info on the elogind startup race, see
+  ;; <https://issues.guix.gnu.org/55444>.
+
+  (define elogind
+    (elogind-package config))
+
+  (define wrapper
+    (program-file "elogind-dbus-shepherd-sync"
+                  (with-imported-modules '((gnu services herd))
+                    #~(begin
+                        (use-modules (gnu services herd)
+                                     (srfi srfi-34))
+
+                        (guard (c ((service-not-found-error? c)
+                                   (format (current-error-port)
+                                           "no elogind shepherd service~%")
+                                   (exit 1))
+                                  ((shepherd-error? c)
+                                   (format (current-error-port)
+                                           "elogind shepherd service not \
+started~%")
+                                   (exit 2)))
+                          (wait-for-service 'elogind))))))
+
+  (define build
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils)
+                       (ice-9 match))
+
+          (define service-directory
+            "/share/dbus-1/system-services")
+
+          (mkdir-p (dirname (string-append #$output service-directory)))
+          (copy-recursively (string-append #$elogind service-directory)
+                            (string-append #$output service-directory))
+          (symlink (string-append #$elogind "/etc") ;for etc/dbus-1
+                   (string-append #$output "/etc"))
+
+          ;; Replace the "Exec=" line of the 'org.freedesktop.login1.service'
+          ;; file with one that refers to WRAPPER instead of elogind.
+          (match (find-files #$output "\\.service$")
+            ((file)
+             (substitute* file
+               (("Exec[[:blank:]]*=.*" _)
+                (string-append "Exec=" #$wrapper "\n"))))))))
+
+  (list (computed-file "elogind-dbus-service-wrapper" build)))
 
 (define (pam-extension-procedure config)
   "Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM
@@ -1129,7 +1187,12 @@ seats.)"
                        ;; We need /run/user, /run/systemd, etc.
                        (service-extension file-system-service-type
                                           (const %elogind-file-systems))))
-                (default-value (elogind-configuration))))
+                (default-value (elogind-configuration))
+                (description "Run the @command{elogind} login and seat
+management service.  The @command{elogind} service integrates with PAM to
+allow other system components to know the set of logged-in users as well as
+their session types (graphical, console, remote, etc.).  It can also clean up
+after users when they log out.")))
 
 (define* (elogind-service #:key (config (elogind-configuration)))
   "Return a service that runs the @command{elogind} login and seat management
@@ -1177,7 +1240,11 @@ when they log out."
                                           (const %accountsservice-activation))
                        (service-extension dbus-root-service-type list)
                        (service-extension polkit-service-type list)))
-                (default-value accountsservice)))
+                (default-value accountsservice)
+                (description "Run AccountsService, a system service available
+over D-Bus that can list available accounts, change their passwords, and so
+on.  AccountsService integrates with PolicyKit to enable unprivileged users to
+acquire the capability to modify their system configuration.")))
 
 (define* (accountsservice-service #:key (accountsservice accountsservice))
   "Return a service that runs AccountsService, a system service that
diff --git a/gnu/services/dict.scm b/gnu/services/dict.scm
index a97ad8f608..f042219cbd 100644
--- a/gnu/services/dict.scm
+++ b/gnu/services/dict.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
-;;; Copyright © 2016, 2017, 2018, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017, 2018, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017 Huang Ying <huang.ying.caritas@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -22,12 +22,15 @@
   #:use-module (guix gexp)
   #:use-module (guix records)
   #:use-module (guix modules)
+  #:use-module (guix least-authority)
   #:use-module (gnu services)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system shadow)
   #:use-module ((gnu packages admin) #:select (shadow))
   #:use-module (gnu packages dico)
   #:use-module (gnu packages dictionaries)
+  #:autoload   (gnu build linux-container) (%namespaces)
+  #:autoload   (gnu system file-systems) (file-system-mapping)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
   #:use-module (ice-9 match)
@@ -142,27 +145,44 @@ database {
         (chown rundir (passwd:uid user) (passwd:gid user)))))
 
 (define (dicod-shepherd-service config)
-  (let ((dicod      (file-append (dicod-configuration-dico config)
-                                 "/bin/dicod"))
-        (dicod.conf (dicod-configuration-file config)))
-    (with-imported-modules (source-module-closure
-                            '((gnu build shepherd)
-                              (gnu system file-systems)))
-      (list (shepherd-service
-             (provision '(dicod))
-             (requirement '(user-processes))
-             (documentation "Run the dicod daemon.")
-             (modules '((gnu build shepherd)
-                        (gnu system file-systems)))
-             (start #~(make-forkexec-constructor/container
-                       (list #$dicod "--foreground"
-                             (string-append "--config=" #$dicod.conf))
-                       #:user "dicod" #:group "dicod"
-                       #:mappings (list (file-system-mapping
-                                         (source "/var/run/dicod")
-                                         (target source)
-                                         (writable? #t)))))
-             (stop #~(make-kill-destructor)))))))
+  (let* ((dicod.conf (dicod-configuration-file config))
+         (interfaces (dicod-configuration-interfaces config))
+         (dicod      (least-authority-wrapper
+                      (file-append (dicod-configuration-dico config)
+                                   "/bin/dicod")
+                      #:name "dicod"
+                      #:mappings (list (file-system-mapping
+                                        (source "/var/run/dicod")
+                                        (target source)
+                                        (writable? #t))
+                                       (file-system-mapping
+                                        (source "/dev/log")
+                                        (target source))
+                                       (file-system-mapping
+                                        (source dicod.conf)
+                                        (target source)))
+                      #:namespaces (delq 'net %namespaces))))
+    (list (shepherd-service
+           (provision '(dicod))
+           (requirement '(user-processes))
+           (documentation "Run the dicod daemon.")
+           (start #~(if (and (defined? 'make-inetd-constructor)
+                             #$(= 1 (length interfaces))) ;XXX
+                        (make-inetd-constructor
+                         (list #$dicod "--inetd" "--foreground"
+                               (string-append "--config=" #$dicod.conf))
+                         (addrinfo:addr
+                          (car (getaddrinfo #$(first interfaces) "dict")))
+                         #:user "dicod" #:group "dicod"
+                         #:service-name-stem "dicod")
+                        (make-forkexec-constructor
+                         (list #$dicod "--foreground"
+                               (string-append "--config=" #$dicod.conf))
+                         #:user "dicod" #:group "dicod")))
+           (stop #~(if (and (defined? 'make-inetd-destructor)
+                            #$(= 1 (length interfaces))) ;XXX
+                       (make-inetd-destructor)
+                       (make-kill-destructor)))))))
 
 (define dicod-service-type
   (service-type
diff --git a/gnu/services/dns.scm b/gnu/services/dns.scm
index 9b8603cc95..50753b7ab6 100644
--- a/gnu/services/dns.scm
+++ b/gnu/services/dns.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
 ;;; Copyright © 2020 Pierre Langlois <pierre.langlois@gmx.com>
 ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
+;;; Copyright © 2022 Remco van 't Veer <remco@remworks.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -745,6 +746,12 @@ cache.size = 100 * MB
                     (default "/etc/resolv.conf")) ;string
   (no-resolv?       dnsmasq-configuration-no-resolv?
                     (default #f))       ;boolean
+  (forward-private-reverse-lookup?
+                    dnsmasq-configuration-forward-private-reverse-lookup?
+                    (default #t))       ;boolean
+  (query-servers-in-order?
+                    dnsmasq-configuration-query-servers-in-order?
+                    (default #f))       ;boolean
   (servers          dnsmasq-configuration-servers
                     (default '()))      ;list of string
   (addresses        dnsmasq-configuration-addresses
@@ -752,7 +759,9 @@ cache.size = 100 * MB
   (cache-size       dnsmasq-configuration-cache-size
                     (default 150))      ;integer
   (negative-cache?  dnsmasq-configuration-negative-cache?
-                    (default #t))      ;boolean
+                    (default #t))       ;boolean
+  (cpe-id           dnsmasq-configuration-cpe-id
+                    (default #t))       ;string
   (tftp-enable?     dnsmasq-configuration-tftp-enable?
                     (default #f))       ;boolean
   (tftp-no-fail?    dnsmasq-configuration-tftp-no-fail?
@@ -776,86 +785,98 @@ cache.size = 100 * MB
   (tftp-unique-root dnsmasq-tftp-unique-root
                     (default #f)))      ;"" or "ip" or "mac"
 
-(define dnsmasq-shepherd-service
-  (match-lambda
-    (($ <dnsmasq-configuration> package
-                                no-hosts?
-                                port local-service? listen-addresses
-                                resolv-file no-resolv? servers
-                                addresses cache-size negative-cache?
-                                tftp-enable? tftp-no-fail?
-                                tftp-single-port? tftp-secure?
-                                tftp-max tftp-mtu tftp-no-blocksize?
-                                tftp-lowercase? tftp-port-range
-                                tftp-root tftp-unique-root)
-     (shepherd-service
-      (provision '(dnsmasq))
-      (requirement '(networking))
-      (documentation "Run the dnsmasq DNS server.")
-      (start #~(make-forkexec-constructor
-                '(#$(file-append package "/sbin/dnsmasq")
-                  "--keep-in-foreground"
-                  "--pid-file=/run/dnsmasq.pid"
-                  #$@(if no-hosts?
-                         '("--no-hosts")
-                         '())
-                  #$(format #f "--port=~a" port)
-                  #$@(if local-service?
-                         '("--local-service")
-                         '())
-                  #$@(map (cut format #f "--listen-address=~a" <>)
-                          listen-addresses)
-                  #$(format #f "--resolv-file=~a" resolv-file)
-                  #$@(if no-resolv?
-                         '("--no-resolv")
-                         '())
-                  #$@(map (cut format #f "--server=~a" <>)
-                          servers)
-                  #$@(map (cut format #f "--address=~a" <>)
-                          addresses)
-                  #$(format #f "--cache-size=~a" cache-size)
-                  #$@(if negative-cache?
-                         '()
-                         '("--no-negcache"))
-                  #$@(if tftp-enable?
-                         '("--enable-tftp")
-                         '())
-                  #$@(if tftp-no-fail?
-                         '("--tftp-no-fail")
-                         '())
-                  #$@(if tftp-single-port?
-                         '("--tftp-single-port")
-                         '())
-                  #$@(if tftp-secure?
-                         '("--tftp-secure?")
-                         '())
-                  #$@(if tftp-max
-                         (list (format #f "--tftp-max=~a" tftp-max))
-                         '())
-                  #$@(if tftp-mtu
-                         (list (format #f "--tftp-mtu=~a" tftp-mtu))
-                         '())
-                  #$@(if tftp-no-blocksize?
-                         '("--tftp-no-blocksize")
-                         '())
-                  #$@(if tftp-lowercase?
-                         '("--tftp-lowercase")
-                         '())
-                  #$@(if tftp-port-range
-                         (list (format #f "--tftp-port-range=~a"
-                                          tftp-port-range))
-                         '())
-                  #$@(if tftp-root
-                         (list (format #f "--tftp-root=~a" tftp-root))
-                         '())
-                  #$@(if tftp-unique-root
-                         (list
-                          (if (> (length tftp-unique-root) 0)
-                              (format #f "--tftp-unique-root=~a" tftp-unique-root)
-                              (format #f "--tftp-unique-root")))
-                         '()))
-                #:pid-file "/run/dnsmasq.pid"))
-      (stop #~(make-kill-destructor))))))
+(define (dnsmasq-shepherd-service config)
+  (match-record config <dnsmasq-configuration>
+    (package
+     no-hosts?
+     port local-service? listen-addresses
+     resolv-file no-resolv?
+     forward-private-reverse-lookup? query-servers-in-order?
+     servers addresses
+     cache-size negative-cache?
+     cpe-id
+     tftp-enable? tftp-no-fail?
+     tftp-single-port? tftp-secure?
+     tftp-max tftp-mtu tftp-no-blocksize?
+     tftp-lowercase? tftp-port-range
+     tftp-root tftp-unique-root)
+    (shepherd-service
+     (provision '(dnsmasq))
+     (requirement '(networking))
+     (documentation "Run the dnsmasq DNS server.")
+     (start #~(make-forkexec-constructor
+               '(#$(file-append package "/sbin/dnsmasq")
+                 "--keep-in-foreground"
+                 "--pid-file=/run/dnsmasq.pid"
+                 #$@(if no-hosts?
+                        '("--no-hosts")
+                        '())
+                 #$(format #f "--port=~a" port)
+                 #$@(if local-service?
+                        '("--local-service")
+                        '())
+                 #$@(map (cut format #f "--listen-address=~a" <>)
+                         listen-addresses)
+                 #$(format #f "--resolv-file=~a" resolv-file)
+                 #$@(if no-resolv?
+                        '("--no-resolv")
+                        '())
+                 #$@(if forward-private-reverse-lookup?
+                        '()
+                        '("--bogus-priv"))
+                 #$@(if query-servers-in-order?
+                        '("--strict-order")
+                        '())
+                 #$@(map (cut format #f "--server=~a" <>)
+                         servers)
+                 #$@(map (cut format #f "--address=~a" <>)
+                         addresses)
+                 #$(format #f "--cache-size=~a" cache-size)
+                 #$@(if negative-cache?
+                        '()
+                        '("--no-negcache"))
+                 #$@(if cpe-id
+                        (list (format #f "--add-cpe-id=~a" cpe-id))
+                        '())
+                 #$@(if tftp-enable?
+                        '("--enable-tftp")
+                        '())
+                 #$@(if tftp-no-fail?
+                        '("--tftp-no-fail")
+                        '())
+                 #$@(if tftp-single-port?
+                        '("--tftp-single-port")
+                        '())
+                 #$@(if tftp-secure?
+                        '("--tftp-secure?")
+                        '())
+                 #$@(if tftp-max
+                        (list (format #f "--tftp-max=~a" tftp-max))
+                        '())
+                 #$@(if tftp-mtu
+                        (list (format #f "--tftp-mtu=~a" tftp-mtu))
+                        '())
+                 #$@(if tftp-no-blocksize?
+                        '("--tftp-no-blocksize")
+                        '())
+                 #$@(if tftp-lowercase?
+                        '("--tftp-lowercase")
+                        '())
+                 #$@(if tftp-port-range
+                        (list (format #f "--tftp-port-range=~a"
+                                      tftp-port-range))
+                        '())
+                 #$@(if tftp-root
+                        (list (format #f "--tftp-root=~a" tftp-root))
+                        '())
+                 #$@(if tftp-unique-root
+                        (list
+                         (if (> (length tftp-unique-root) 0)
+                             (format #f "--tftp-unique-root=~a" tftp-unique-root)
+                             (format #f "--tftp-unique-root")))
+                        '()))
+               #:pid-file "/run/dnsmasq.pid"))
+     (stop #~(make-kill-destructor)))))
 
 (define (dnsmasq-activation config)
   #~(begin
@@ -957,8 +978,7 @@ manually.")
 
 (define (ddclient-activation config)
   "Return the activation GEXP for CONFIG."
-  (with-imported-modules '((guix build utils)
-                           (ice-9 rdelim))
+  (with-imported-modules '((guix build utils))
     #~(begin
         (use-modules (guix build utils)
                      (ice-9 rdelim))
diff --git a/gnu/services/games.scm b/gnu/services/games.scm
index b743f6a4b6..6c2af44b49 100644
--- a/gnu/services/games.scm
+++ b/gnu/services/games.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -22,6 +23,9 @@
   #:use-module (gnu packages admin)
   #:use-module (gnu packages games)
   #:use-module (gnu system shadow)
+  #:use-module ((gnu system file-systems) #:select (file-system-mapping))
+  #:use-module (gnu build linux-container)
+  #:autoload   (guix least-authority) (least-authority-wrapper)
   #:use-module (guix gexp)
   #:use-module (guix modules)
   #:use-module (guix records)
@@ -56,19 +60,34 @@
 (define wesnothd-shepherd-service
   (match-lambda
     (($ <wesnothd-configuration> package port)
-     (with-imported-modules (source-module-closure
-                             '((gnu build shepherd)))
+     (let ((wesnothd (least-authority-wrapper
+                      (file-append package "/bin/wesnothd")
+                      #:name "wesnothd"
+                      #:mappings (list (file-system-mapping
+                                        (source "/var/run/wesnothd")
+                                        (target source)
+                                        (writable? #t)))
+                      #:namespaces (delq 'net %namespaces))))
        (shepherd-service
         (documentation "The Battle for Wesnoth server")
         (provision '(wesnoth-daemon))
         (requirement '(networking))
-        (modules '((gnu build shepherd)))
-        (start #~(make-forkexec-constructor/container
-                  (list #$(file-append package "/bin/wesnothd")
-                        "-p" #$(number->string port))
+        (start #~(make-forkexec-constructor
+                  (list #$wesnothd "-p" #$(number->string port))
                   #:user "wesnothd" #:group "wesnothd"))
         (stop #~(make-kill-destructor)))))))
 
+(define wesnothd-activation
+  (with-imported-modules '((guix build utils))
+    #~(begin
+        (use-modules (guix build utils))
+
+        (let* ((user (getpw "wesnothd"))
+               (directory "/var/run/wesnothd"))
+          ;; wesnothd creates a Unix-domain socket in DIRECTORY.
+          (mkdir-p directory)
+          (chown directory (passwd:uid user) (passwd:gid user))))))
+
 (define wesnothd-service-type
   (service-type
    (name 'wesnothd)
@@ -77,6 +96,8 @@
    (extensions
     (list (service-extension account-service-type
                              (const %wesnothd-accounts))
+          (service-extension activation-service-type
+                             (const wesnothd-activation))
           (service-extension shepherd-root-service-type
                              (compose list wesnothd-shepherd-service))))
    (default-value (wesnothd-configuration))))
diff --git a/gnu/services/guix.scm b/gnu/services/guix.scm
index dc9bd8ad68..ad7b020b69 100644
--- a/gnu/services/guix.scm
+++ b/gnu/services/guix.scm
@@ -92,6 +92,7 @@
             guix-build-coordinator-queue-builds-configuration-systems
             guix-build-coordinator-queue-builds-configuration-system-and-targets
             guix-build-coordinator-queue-builds-configuration-guix-data-service
+            guix-build-coordinator-queue-builds-configuration-guix-data-service-build-server-id
             guix-build-coordinator-queue-builds-configuration-processed-commits-file
 
             guix-build-coordinator-queue-builds-service-type
@@ -122,7 +123,8 @@
             nar-herder-configuration-port
             nar-herder-configuration-storage
             nar-herder-configuration-storage-limit
-            nar-herder-configuration-storage-nar-removal-criteria))
+            nar-herder-configuration-storage-nar-removal-criteria
+            nar-herder-configuration-log-level))
 
 ;;;; Commentary:
 ;;;
@@ -229,6 +231,9 @@
   (guix-data-service
    guix-build-coordinator-queue-builds-configuration-guix-data-service
    (default "https://data.guix.gnu.org"))
+  (guix-data-service-build-server-id
+   guix-build-coordinator-queue-builds-configuration-guix-data-service-build-server-id
+   (default #f))
   (processed-commits-file
    guix-build-coordinator-queue-builds-configuration-processed-commits-file
    (default "/var/cache/guix-build-coordinator-queue-builds/processed-commits")))
@@ -493,7 +498,9 @@
 (define (guix-build-coordinator-queue-builds-shepherd-services config)
   (match-record config <guix-build-coordinator-queue-builds-configuration>
     (package user coordinator systems systems-and-targets
-             guix-data-service processed-commits-file)
+             guix-data-service
+             guix-data-service-build-server-id
+             processed-commits-file)
     (list
      (shepherd-service
       (documentation "Guix Build Coordinator queue builds from Guix Data Service")
@@ -516,6 +523,12 @@
            #$@(if guix-data-service
                   #~(#$(string-append "--guix-data-service=" guix-data-service))
                   #~())
+           #$@(if guix-data-service-build-server-id
+                  #~(#$(simple-format
+                        #f
+                        "--guix-data-service-build-server-id=~A"
+                        guix-data-service-build-server-id))
+                  #~())
            #$@(if processed-commits-file
                   #~(#$(string-append "--processed-commits-file="
                                       processed-commits-file))
@@ -630,7 +643,7 @@ ca-certificates.crt file in the system profile."
                 #:group #$group
                 #:pid-file "/var/run/guix-data-service/pid"
                 ;; Allow time for migrations to run
-                #:pid-file-timeout 60
+                #:pid-file-timeout 120
                 #:environment-variables
                 `(,(string-append
                     "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
@@ -778,7 +791,9 @@ ca-certificates.crt file in the system profile."
   (ttl           nar-herder-configuration-ttl
                  (default #f))
   (negative-ttl  nar-herder-configuration-negative-ttl
-                 (default #f)))
+                 (default #f))
+  (log-level     nar-herder-configuration-log-level
+                 (default 'DEBUG)))
 
 
 (define (nar-herder-shepherd-services config)
@@ -788,7 +803,7 @@ ca-certificates.crt file in the system profile."
              database database-dump
              host port
              storage storage-limit storage-nar-removal-criteria
-             ttl negative-ttl)
+             ttl negative-ttl log-level)
 
     (unless (or mirror storage)
       (error "nar-herder: mirror or storage must be set"))
@@ -829,6 +844,9 @@ ca-certificates.crt file in the system profile."
                              '())
                       #$@(if negative-ttl
                              (list (string-append "--negative-ttl=" negative-ttl))
+                             '())
+                      #$@(if log-level
+                             (list (simple-format #f "--log-level=~A" log-level))
                              '()))
                 #:user #$user
                 #:group #$group
diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm
index 35d69376d0..a7c845b4b0 100644
--- a/gnu/services/herd.scm
+++ b/gnu/services/herd.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016-2019, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -20,6 +20,7 @@
 (define-module (gnu services herd)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-9)
+  #:use-module (srfi srfi-9 gnu)
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
@@ -46,6 +47,7 @@
             live-service-provision
             live-service-requirement
             live-service-running
+            live-service-transient?
             live-service-canonical-name
 
             with-shepherd-action
@@ -56,7 +58,8 @@
             load-services/safe
             start-service
             stop-service
-            restart-service))
+            restart-service
+            wait-for-service))
 
 ;;; Commentary:
 ;;;
@@ -194,10 +197,11 @@ of pairs."
 
 ;; Information about live Shepherd services.
 (define-record-type <live-service>
-  (live-service provision requirement running)
+  (live-service provision requirement transient? running)
   live-service?
   (provision    live-service-provision)           ;list of symbols
   (requirement  live-service-requirement)         ;list of symbols
+  (transient?   live-service-transient?)          ;Boolean
   (running      live-service-running))            ;#f | object
 
 (define (live-service-canonical-name service)
@@ -215,13 +219,46 @@ obtained."
       ((services _ ...)
        (match services
          ((('service ('version 0 _ ...) _ ...) ...)
-          (map (lambda (service)
-                 (alist-let* service (provides requires running)
-                   (live-service provides requires running)))
-               services))
+          (resolve-transients
+           (map (lambda (service)
+                  (alist-let* service (provides requires running transient?)
+                    ;; The Shepherd 0.9.0 would not provide 'transient?' in its
+                    ;; status sexp.  Thus, when it's missing, query it via an
+                    ;; "eval" request.
+                    (live-service provides requires
+                                  (if (sloppy-assq 'transient? service)
+                                      transient?
+                                      (and running *unspecified*))
+                                  running)))
+                services)))
          (x
           #f))))))
 
+(define (resolve-transients services)
+  "Resolve the subset of SERVICES whose 'transient?' field is undefined.  This
+is necessary to deal with Shepherd 0.9.0, which did not communicate whether a
+service is transient."
+  ;; All the fuss here is to make sure we make a single "eval root" request
+  ;; for all of SERVICES.
+  (let* ((unresolved (filter (compose unspecified? live-service-transient?)
+                             services))
+         (values     (or (eval-there
+                          `(and (defined? 'transient?) ;shepherd >= 0.9.0
+                                (map (compose transient? lookup-running)
+                                     ',(map (compose first
+                                                     live-service-provision)
+                                            unresolved))))
+                         (make-list (length unresolved) #f)))
+         (resolved   (map (lambda (unresolved transient?)
+                            (cons unresolved
+                                  (set-field unresolved
+                                             (live-service-transient?)
+                                             transient?)))
+                          unresolved values)))
+    (map (lambda (service)
+           (or (assq-ref resolved service) service))
+         services)))
+
 (define (unload-service service)
   "Unload SERVICE, a symbol name; return #t on success."
   (with-shepherd-action 'root ('unload (symbol->string service)) result
@@ -277,6 +314,39 @@ when passed a service with an already-registered name."
   (with-shepherd-action name ('restart) result
     result))
 
+(define* (wait-for-service name #:key (timeout 20))
+  "Wait for the service providing NAME, a symbol, to be up and running, and
+return its \"running value\".  Give up after TIMEOUT seconds and raise a
+'&shepherd-error' exception.  Raise a '&service-not-found-error' exception
+when NAME is not found."
+  (define (relevant-service? service)
+    (memq name (live-service-provision service)))
+
+  (define start
+    (car (gettimeofday)))
+
+  ;; Note: As of Shepherd 0.9.1, we cannot just call the 'start' method and
+  ;; wait for it: it would spawn an additional elogind process.  Thus, poll.
+  (let loop ((attempts 0))
+    (define services
+      (current-services))
+
+    (define now
+      (car (gettimeofday)))
+
+    (when (>= (- now start) timeout)
+      (raise (condition (&shepherd-error))))      ;XXX: better exception?
+
+    (match (find relevant-service? services)
+      (#f
+       (raise (condition (&service-not-found-error
+                          (service name)))))
+      (service
+       (or (live-service-running service)
+           (begin
+             (sleep 1)
+             (loop (+ attempts 1))))))))
+
 ;; Local Variables:
 ;; eval: (put 'alist-let* 'scheme-indent-function 2)
 ;; eval: (put 'with-shepherd 'scheme-indent-function 1)
diff --git a/gnu/services/kerberos.scm b/gnu/services/kerberos.scm
index f09f47893c..f845c1bd89 100644
--- a/gnu/services/kerberos.scm
+++ b/gnu/services/kerberos.scm
@@ -410,8 +410,10 @@ machine does not have a keytab.")
   (service-type (name 'krb5)
                 (extensions
                  (list (service-extension etc-service-type
-                                          krb5-etc-service)))))
-
+                                          krb5-etc-service)))
+                (description "Programs using a Kerberos client library
+normally expect a configuration file in @file{/etc/krb5.conf}.  This service
+generates such a file.  It does not cause any daemon to be started.")))
 
 
 
@@ -455,4 +457,8 @@ machine does not have a keytab.")
                 (extensions
                  (list
                   (service-extension pam-root-service-type
-                                     pam-krb5-pam-services)))))
+                                     pam-krb5-pam-services)))
+                (description "The @code{pam-krb5} service allows for login
+authentication and password management via Kerberos.  You will need this
+service if you want PAM-enabled applications to authenticate users using
+Kerberos.")))
diff --git a/gnu/services/lirc.scm b/gnu/services/lirc.scm
index 1f5adcdd5f..492d77defa 100644
--- a/gnu/services/lirc.scm
+++ b/gnu/services/lirc.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -79,7 +79,9 @@
                  (list (service-extension shepherd-root-service-type
                                           lirc-shepherd-service)
                        (service-extension activation-service-type
-                                          (const %lirc-activation))))))
+                                          (const %lirc-activation))))
+                (description "Run LIRC, a daemon that decodes infrared signals
+from remote controls.")))
 
 (define* (lirc-service #:key (lirc lirc)
                        device driver config-file
diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm
index 4ad6ddb534..d99743ac31 100644
--- a/gnu/services/mail.scm
+++ b/gnu/services/mail.scm
@@ -1600,7 +1600,9 @@ greyed out, instead of only later giving \"not selectable\" popup error.
                        (service-extension pam-root-service-type
                                           (const %dovecot-pam-services))
                        (service-extension activation-service-type
-                                          %dovecot-activation)))))
+                                          %dovecot-activation)))
+                (description "Run Dovecot, a mail server that can run POP3,
+IMAP, and LMTP.")))
 
 (define* (dovecot-service #:key (config (dovecot-configuration)))
   "Return a service that runs @command{dovecot}, a mail server that can run
@@ -1729,7 +1731,9 @@ match from local for any action outbound
           (service-extension profile-service-type
                              (compose list opensmtpd-configuration-package))
           (service-extension shepherd-root-service-type
-                             opensmtpd-shepherd-service)))))
+                             opensmtpd-shepherd-service)))
+   (description "Run the OpenSMTPD, a lightweight @acronym{SMTP, Simple Mail
+Transfer Protocol} server.")))
 
 
 ;;;
@@ -1754,7 +1758,9 @@ match from local for any action outbound
    (extensions
     (list (service-extension etc-service-type mail-aliases-etc)))
    (compose concatenate)
-   (extend append)))
+   (extend append)
+   (description "Provide a @file{/etc/aliases} file---an email alias
+database---computed from the given alias list.")))
 
 
 ;;;
@@ -1831,7 +1837,8 @@ exim_group = exim
           (service-extension account-service-type (const %exim-accounts))
           (service-extension activation-service-type exim-activation)
           (service-extension profile-service-type exim-profile)
-          (service-extension mail-aliases-service-type (const '()))))))
+          (service-extension mail-aliases-service-type (const '()))))
+   (description "Run the Exim mail transfer agent (MTA).")))
 
 
 ;;;
diff --git a/gnu/services/messaging.scm b/gnu/services/messaging.scm
index 6ed55453db..48eff27b49 100644
--- a/gnu/services/messaging.scm
+++ b/gnu/services/messaging.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
-;;; Copyright © 2015, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2017-2020, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2018 Pierre-Antoine Rouby <contact@parouby.fr>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -20,19 +20,23 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu services messaging)
-  #:use-module (gnu packages messaging)
   #:use-module (gnu packages admin)
+  #:use-module (gnu packages base)
   #:use-module (gnu packages irc)
+  #:use-module (gnu packages messaging)
   #:use-module (gnu packages tls)
   #:use-module (gnu services)
   #:use-module (gnu services shepherd)
   #:use-module (gnu services configuration)
   #:use-module (gnu system shadow)
+  #:autoload   (gnu build linux-container) (%namespaces)
+  #:use-module ((gnu system file-systems) #:select (file-system-mapping))
   #:use-module (guix gexp)
   #:use-module (guix modules)
   #:use-module (guix records)
   #:use-module (guix packages)
   #:use-module (guix deprecation)
+  #:use-module (guix least-authority)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-35)
   #:use-module (ice-9 match)
@@ -180,7 +184,7 @@
   (and (list? val) (and-map file-name? val)))
 (define (serialize-file-name-list field-name val)
   (serialize-string-list field-name val))
-(define-maybe file-name)
+(define-maybe file-name-list)
 
 (define (file-object? val)
   (or (file-like? val) (file-name? val)))
@@ -192,7 +196,7 @@
   (and (list? val) (and-map file-object? val)))
 (define (serialize-file-object-list field-name val)
   (serialize-string-list field-name val))
-(define-maybe file-object)
+(define-maybe file-object-list)
 
 (define (raw-content? val)
   (not (eq? val 'disabled)))
@@ -821,7 +825,23 @@ string, you could instantiate a prosody service like this:
   DaemonInterface = " interface "
   DaemonPort = " (number->string port) "
   PluginDir = " plugins "/lib/bitlbee
-" extra-settings)))
+" extra-settings))
+            (bitlbee* (least-authority-wrapper
+                       (file-append bitlbee "/sbin/bitlbee")
+                       #:name "bitlbee"
+                       #:preserved-environment-variables
+                       '("PURPLE_PLUGIN_PATH" "GUIX_LOCPATH" "LC_ALL")
+                       #:mappings (list (file-system-mapping
+                                         (source "/var/lib/bitlbee")
+                                         (target source)
+                                         (writable? #t))
+                                        (file-system-mapping
+                                         (source "/run/current-system/locale")
+                                         (target source))
+                                        (file-system-mapping
+                                         (source conf)
+                                         (target conf)))
+                       #:namespaces (delq 'net %namespaces))))
 
        (with-imported-modules (source-module-closure
                                '((gnu build shepherd)
@@ -836,21 +856,41 @@ string, you could instantiate a prosody service like this:
 
                 (modules '((gnu build shepherd)
                            (gnu system file-systems)))
-                (start #~(make-forkexec-constructor/container
-                          (list #$(file-append bitlbee "/sbin/bitlbee")
-                                "-n" "-F" "-u" "bitlbee" "-c" #$conf)
-
-                          ;; Allow 'bitlbee-purple' to use libpurple plugins.
-                          #:environment-variables
-                          (list (string-append "PURPLE_PLUGIN_PATH="
-                                               #$plugins "/lib/purple-2"))
-
-                          #:pid-file "/var/run/bitlbee.pid"
-                          #:mappings (list (file-system-mapping
-                                            (source "/var/lib/bitlbee")
-                                            (target source)
-                                            (writable? #t)))))
-                (stop  #~(make-kill-destructor)))))))))
+                (start #~(if (defined? 'make-inetd-constructor)
+
+                             (make-inetd-constructor
+                              (list #$bitlbee* "-I" "-c" #$conf)
+                              (addrinfo:addr
+                               (car (getaddrinfo #$interface
+                                                 #$(number->string port)
+                                                 (logior AI_NUMERICHOST
+                                                         AI_NUMERICSERV))))
+                              #:service-name-stem "bitlbee"
+                              #:user "bitlbee" #:group "bitlbee"
+
+                              ;; Allow 'bitlbee-purple' to use libpurple plugins.
+                              #:environment-variables
+                              (list (string-append "PURPLE_PLUGIN_PATH="
+                                                   #$plugins "/lib/purple-2")
+                                    "GUIX_LOCPATH=/run/current-system/locale"))
+
+                             (make-forkexec-constructor/container
+                              (list #$(file-append bitlbee "/sbin/bitlbee")
+                                    "-n" "-F" "-u" "bitlbee" "-c" #$conf)
+
+                              ;; Allow 'bitlbee-purple' to use libpurple plugins.
+                              #:environment-variables
+                              (list (string-append "PURPLE_PLUGIN_PATH="
+                                                   #$plugins "/lib/purple-2"))
+
+                              #:pid-file "/var/run/bitlbee.pid"
+                              #:mappings (list (file-system-mapping
+                                                (source "/var/lib/bitlbee")
+                                                (target source)
+                                                (writable? #t))))))
+                (stop  #~(if (defined? 'make-inetd-destructor)
+                             (make-inetd-destructor)
+                             (make-kill-destructor))))))))))
 
 (define %bitlbee-accounts
   ;; User group and account to run BitlBee.
@@ -908,29 +948,31 @@ a gateway between IRC and chat networks.")))
 (define quassel-shepherd-service
   (match-lambda
     (($ <quassel-configuration> quassel interface port loglevel)
-     (with-imported-modules (source-module-closure
-                              '((gnu build shepherd)
-                                (gnu system file-systems)))
+     (let ((quassel (least-authority-wrapper
+                     (file-append quassel "/bin/quasselcore")
+                     #:name "quasselcore"
+                     #:mappings (list (file-system-mapping
+                                       (source "/var/lib/quassel")
+                                       (target source)
+                                       (writable? #t))
+                                      (file-system-mapping
+                                       (source "/var/log/quassel")
+                                       (target source)
+                                       (writable? #t)))
+                     ;; XXX: The daemon needs to live in the main user
+                     ;; namespace, as root, so it can access /var/lib/quassel
+                     ;; owned by "quasselcore".
+                     #:namespaces (fold delq %namespaces '(net user)))))
        (list (shepherd-service
                (provision '(quassel))
                (requirement '(user-processes networking))
-               (modules '((gnu build shepherd)
-                          (gnu system file-systems)))
-               (start #~(make-forkexec-constructor/container
-                          (list #$(file-append quassel "/bin/quasselcore")
-                                "--configdir=/var/lib/quassel"
-                                "--logfile=/var/log/quassel/core.log"
-                                (string-append "--loglevel=" #$loglevel)
-                                (string-append "--port=" (number->string #$port))
-                                (string-append "--listen=" #$interface))
-                          #:mappings (list (file-system-mapping
-                                             (source "/var/lib/quassel")
-                                             (target source)
-                                             (writable? #t))
-                                           (file-system-mapping
-                                             (source "/var/log/quassel")
-                                             (target source)
-                                             (writable? #t)))))
+               (start #~(make-forkexec-constructor
+                         (list #$quassel
+                               "--configdir=/var/lib/quassel"
+                               "--logfile=/var/log/quassel/core.log"
+                               (string-append "--loglevel=" #$loglevel)
+                               (string-append "--port=" (number->string #$port))
+                               (string-append "--listen=" #$interface))))
                (stop  #~(make-kill-destructor))))))))
 
 (define %quassel-account
diff --git a/gnu/services/monitoring.scm b/gnu/services/monitoring.scm
index 0e6aed2cac..9c8704092c 100644
--- a/gnu/services/monitoring.scm
+++ b/gnu/services/monitoring.scm
@@ -419,7 +419,10 @@ configuration file."))
                              zabbix-server-account)
           (service-extension activation-service-type
                              zabbix-server-activation)))
-   (default-value (zabbix-server-configuration))))
+   (default-value (zabbix-server-configuration))
+   (description "Run the Zabbix server, a high-performance monitoring system
+that can collect data about machines from a variety of sources and provide the
+results in a Web interface.")))
 
 (define (generate-zabbix-server-documentation)
   (generate-documentation
@@ -546,7 +549,9 @@ configuration file."))
                              zabbix-agent-account)
           (service-extension activation-service-type
                              zabbix-agent-activation)))
-   (default-value (zabbix-agent-configuration))))
+   (default-value (zabbix-agent-configuration))
+   (description "Run the Zabbix agent, @command{zabbix_agentd}, which gathers
+information about the running system for the Zabbix monitoring server.")))
 
 (define (generate-zabbix-agent-documentation)
   (generate-documentation
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 5bb8638930..90b9317510 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2016, 2018, 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 John Darrington <jmd@gnu.org>
@@ -41,8 +41,10 @@
   #:use-module (gnu services linux)
   #:use-module (gnu services shepherd)
   #:use-module (gnu services dbus)
+  #:use-module (gnu services admin)
   #:use-module (gnu system shadow)
   #:use-module (gnu system pam)
+  #:use-module ((gnu system file-systems) #:select (file-system-mapping))
   #:use-module (gnu packages admin)
   #:use-module (gnu packages base)
   #:use-module (gnu packages bash)
@@ -55,10 +57,10 @@
   #:use-module (gnu packages messaging)
   #:use-module (gnu packages networking)
   #:use-module (gnu packages ntp)
-  #:use-module (gnu packages wicd)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages ipfs)
   #:use-module (gnu build linux-container)
+  #:autoload   (guix least-authority) (least-authority-wrapper)
   #:use-module (guix gexp)
   #:use-module (guix records)
   #:use-module (guix modules)
@@ -127,9 +129,6 @@
             tor-hidden-service
             tor-service-type
 
-            wicd-service-type
-            wicd-service
-
             network-manager-configuration
             network-manager-configuration?
             network-manager-configuration-dns
@@ -382,6 +381,11 @@ daemon is responsible for allocating IP addresses to its client.")))
 ;;; NTP.
 ;;;
 
+
+(define %ntp-log-rotation
+  (list (log-rotation
+         (files '("/var/log/ntpd.log")))))
+
 (define ntp-server-types (make-enumeration
                           '(pool
                             server
@@ -530,7 +534,9 @@ restrict source notrap nomodify noquery\n"))
                        (service-extension account-service-type
                                           (const %ntp-accounts))
                        (service-extension activation-service-type
-                                          ntp-service-activation)))
+                                          ntp-service-activation)
+                       (service-extension rottlog-service-type
+                                          (const %ntp-log-rotation))))
                 (description
                  "Run the @command{ntpd}, the Network Time Protocol (NTP)
 daemon of the @uref{http://www.ntp.org, Network Time Foundation}.  The daemon
@@ -612,7 +618,7 @@ will keep the system clock synchronized with that of the given servers.")
                      ;; When ntpd is daemonized it repeatedly tries to respawn
                      ;; while running, leading shepherd to disable it.  To
                      ;; prevent spamming stderr, redirect output to logfile.
-                     #:log-file "/var/log/ntpd"))
+                     #:log-file "/var/log/ntpd.log"))
            (stop #~(make-kill-destructor))))))
 
 (define (openntpd-service-activation config)
@@ -638,7 +644,9 @@ will keep the system clock synchronized with that of the given servers.")
                        (service-extension profile-service-type
                                           (compose list openntpd-configuration-openntpd))
                        (service-extension activation-service-type
-                                          openntpd-service-activation)))
+                                          openntpd-service-activation)
+                       (service-extension rottlog-service-type
+                                          (const %ntp-log-rotation))))
                 (default-value (openntpd-configuration))
                 (description
                  "Run the @command{ntpd}, the Network Time Protocol (NTP)
@@ -794,7 +802,19 @@ CONFIG, an <opendht-configuration> object."
   (match-record config <opendht-configuration>
     (opendht bootstrap-host enable-logging? port debug? peer-discovery?
              proxy-server-port proxy-server-port-tls)
-    (let ((dhtnode #~(string-append #$opendht:tools "/bin/dhtnode")))
+    (let ((dhtnode (least-authority-wrapper
+                    ;; XXX: Work around lack of support for multiple outputs
+                    ;; in 'file-append'.
+                    (computed-file "dhtnode"
+                                   #~(symlink
+                                      (string-append #$opendht:tools
+                                                     "/bin/dhtnode")
+                                      #$output))
+                    #:name "dhtnode"
+                    #:mappings (list (file-system-mapping
+                                      (source "/dev/log") ;for syslog
+                                      (target source)))
+                    #:namespaces (delq 'net %namespaces))))
       `(,dhtnode
         "--service"                     ;non-forking mode
         ,@(if (string? bootstrap-host)
@@ -820,23 +840,15 @@ CONFIG, an <opendht-configuration> object."
 
 (define (opendht-shepherd-service config)
   "Return a <shepherd-service> running OpenDHT."
-  (with-imported-modules (source-module-closure
-                          '((gnu build shepherd)
-                            (gnu system file-systems)))
-    (shepherd-service
-     (documentation "Run an OpenDHT node.")
-     (provision '(opendht dhtnode dhtproxy))
-     (requirement '(networking syslogd))
-     (modules '((gnu build shepherd)
-                (gnu system file-systems)))
-     (start #~(make-forkexec-constructor/container
-               (list #$@(opendht-configuration->command-line-arguments config))
-               #:mappings (list (file-system-mapping
-                                 (source "/dev/log") ;for syslog
-                                 (target source)))
-               #:user "opendht"
-               #:group "opendht"))
-     (stop #~(make-kill-destructor)))))
+  (shepherd-service
+   (documentation "Run an OpenDHT node.")
+   (provision '(opendht dhtnode dhtproxy))
+   (requirement '(networking syslogd))
+   (start #~(make-forkexec-constructor
+             (list #$@(opendht-configuration->command-line-arguments config))
+             #:user "opendht"
+             #:group "opendht"))
+   (stop #~(make-kill-destructor))))
 
 (define opendht-service-type
   (service-type
@@ -981,6 +993,10 @@ HiddenServicePort ~a ~a~%"
                 (stop #~(make-kill-destructor))
                 (documentation "Run the Tor anonymous network overlay."))))))))
 
+(define %tor-log-rotation
+  (list (log-rotation
+         (files '("/var/log/tor.log")))))
+
 (define (tor-activation config)
   "Set up directories for Tor and its hidden services, if any."
   #~(begin
@@ -1026,7 +1042,9 @@ HiddenServicePort ~a ~a~%"
                        (service-extension account-service-type
                                           (const %tor-accounts))
                        (service-extension activation-service-type
-                                          tor-activation)))
+                                          tor-activation)
+                       (service-extension rottlog-service-type
+                                          (const %tor-log-rotation))))
 
                 ;; This can be extended with hidden services.
                 (compose concatenate)
@@ -1072,64 +1090,6 @@ project's documentation} for more information."
 
 
 ;;;
-;;; Wicd.
-;;;
-
-(define %wicd-activation
-  ;; Activation gexp for Wicd.
-  #~(begin
-      (use-modules (guix build utils))
-
-      (mkdir-p "/etc/wicd")
-      (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
-        (unless (file-exists? file-name)
-          (copy-file (string-append #$wicd file-name)
-                     file-name)))
-
-      ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
-      ;; named socket files.
-      (mkdir-p "/var/run/wpa_supplicant")
-      (chmod "/var/run/wpa_supplicant" #o750)))
-
-(define (wicd-shepherd-service wicd)
-  "Return a shepherd service for WICD."
-  (list (shepherd-service
-         (documentation "Run the Wicd network manager.")
-         (provision '(networking))
-         (requirement '(user-processes dbus-system loopback))
-         (start #~(make-forkexec-constructor
-                   (list (string-append #$wicd "/sbin/wicd")
-                         "--no-daemon")))
-         (stop #~(make-kill-destructor)))))
-
-(define wicd-service-type
-  (service-type (name 'wicd)
-                (extensions
-                 (list (service-extension shepherd-root-service-type
-                                          wicd-shepherd-service)
-                       (service-extension dbus-root-service-type
-                                          list)
-                       (service-extension activation-service-type
-                                          (const %wicd-activation))
-
-                       ;; Add Wicd to the global profile.
-                       (service-extension profile-service-type list)))
-                (description
-                 "Run @url{https://launchpad.net/wicd,Wicd}, a network
-management daemon that aims to simplify wired and wireless networking.")))
-
-(define* (wicd-service #:key (wicd wicd))
-  "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
-management daemon that aims to simplify wired and wireless networking.
-
-This service adds the @var{wicd} package to the global profile, providing
-several commands to interact with the daemon and configure networking:
-@command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
-and @command{wicd-curses} user interfaces."
-  (service wicd-service-type wicd))
-
-
-;;;
 ;;; ModemManager
 ;;;
 
@@ -1308,6 +1268,10 @@ wireless networking."))))
                       #:log-file "/var/log/connman.log"))
             (stop #~(make-kill-destructor)))))))
 
+(define %connman-log-rotation
+  (list (log-rotation
+         (files '("/var/log/connman.log")))))
+
 (define connman-service-type
   (let ((connman-package (compose list connman-configuration-connman)))
     (service-type (name 'connman)
@@ -1322,7 +1286,9 @@ wireless networking."))))
                                             connman-activation)
                          ;; Add connman to the system profile.
                          (service-extension profile-service-type
-                                            connman-package)))
+                                            connman-package)
+                         (service-extension rottlog-service-type
+                                            (const %connman-log-rotation))))
                   (default-value (connman-configuration))
                   (description
                    "Run @url{https://01.org/connman,Connman},
@@ -1564,12 +1530,18 @@ extra-settings "\n"))))
                    #:log-file "/var/log/hostapd.log"))
          (stop #~(make-kill-destructor)))))
 
+(define %hostapd-log-rotation
+  (list (log-rotation
+         (files '("/var/log/hostapd.log")))))
+
 (define hostapd-service-type
   (service-type
    (name 'hostapd)
    (extensions
     (list (service-extension shepherd-root-service-type
-                             hostapd-shepherd-services)))
+                             hostapd-shepherd-services)
+          (service-extension rottlog-service-type
+                             (const %hostapd-log-rotation))))
    (description
     "Run the @uref{https://w1.fi/hostapd/, hostapd} daemon for Wi-Fi access
 points and authentication servers.")))
@@ -1861,6 +1833,10 @@ table inet filter {
        ;; SIGTERM doesn't always work for some reason.
        (stop #~(make-kill-destructor SIGINT))))))
 
+(define %pagekite-log-rotation
+  (list (log-rotation
+         (files '("/var/log/pagekite.log")))))
+
 (define %pagekite-accounts
   (list (user-group (name "pagekite") (system? #t))
         (user-account
@@ -1879,7 +1855,9 @@ table inet filter {
     (list (service-extension shepherd-root-service-type
                              (compose list pagekite-shepherd-service))
           (service-extension account-service-type
-                             (const %pagekite-accounts))))
+                             (const %pagekite-accounts))
+          (service-extension rottlog-service-type
+                             (const %pagekite-log-rotation))))
    (description
     "Run @url{https://pagekite.net/,PageKite}, a tunneling solution to make
 local servers publicly accessible on the web, even behind NATs and firewalls.")))
@@ -1970,6 +1948,10 @@ local servers publicly accessible on the web, even behind NATs and firewalls."))
                    #:group "yggdrasil"))
          (stop #~(make-kill-destructor)))))
 
+(define %yggdrasil-log-rotation
+  (list (log-rotation
+         (files '("/var/log/yggdrasil.log")))))
+
 (define %yggdrasil-accounts
   (list (user-group (name "yggdrasil") (system? #t))))
 
@@ -1978,14 +1960,16 @@ local servers publicly accessible on the web, even behind NATs and firewalls."))
    (name 'yggdrasil)
    (description
     "Connect to the Yggdrasil mesh network.
-See yggdrasil -genconf for config options.")
+See @command{yggdrasil -genconf} for config options.")
    (extensions
     (list (service-extension shepherd-root-service-type
                              yggdrasil-shepherd-service)
           (service-extension account-service-type
                              (const %yggdrasil-accounts))
           (service-extension profile-service-type
-                             (compose list yggdrasil-configuration-package))))))
+                             (compose list yggdrasil-configuration-package))
+          (service-extension rottlog-service-type
+                             (const %yggdrasil-log-rotation))))))
 
 
 ;;;
@@ -2018,13 +2002,20 @@ See yggdrasil -genconf for config options.")
          (system? #t))))
 
 (define (ipfs-binary config)
-  (file-append (ipfs-configuration-package config) "/bin/ipfs"))
+  (define command
+    (file-append (ipfs-configuration-package config) "/bin/ipfs"))
+
+  (least-authority-wrapper
+   command
+   #:name "ipfs"
+   #:mappings (list %ipfs-home-mapping)
+   #:namespaces (delq 'net %namespaces)))
 
 (define %ipfs-home-mapping
-  #~(file-system-mapping
-     (source #$%ipfs-home)
-     (target #$%ipfs-home)
-     (writable? #t)))
+  (file-system-mapping
+   (source %ipfs-home)
+   (target %ipfs-home)
+   (writable? #t)))
 
 (define %ipfs-environment
   #~(list #$(string-append "HOME=" %ipfs-home)))
@@ -2033,75 +2024,70 @@ See yggdrasil -genconf for config options.")
   "Return a <shepherd-service> for IPFS with CONFIG."
   (define ipfs-daemon-command
     #~(list #$(ipfs-binary config) "daemon"))
-  (list
-   (with-imported-modules (source-module-closure
-                           '((gnu build shepherd)
-                             (gnu system file-systems)))
-     (shepherd-service
-      (provision '(ipfs))
-      ;; While IPFS is most useful when the machine is connected
-      ;; to the network, only loopback is required for starting
-      ;; the service.
-      (requirement '(loopback))
-      (documentation "Connect to the IPFS network")
-      (modules '((gnu build shepherd)
-                 (gnu system file-systems)))
-      (start #~(make-forkexec-constructor/container
-                #$ipfs-daemon-command
-                #:namespaces '#$(fold delq %namespaces '(user net))
-                #:mappings (list #$%ipfs-home-mapping)
-                #:log-file "/var/log/ipfs.log"
-                #:user "ipfs"
-                #:group "ipfs"
-                #:environment-variables #$%ipfs-environment))
-      (stop #~(make-kill-destructor))))))
+
+  (list (shepherd-service
+         (provision '(ipfs))
+         ;; While IPFS is most useful when the machine is connected
+         ;; to the network, only loopback is required for starting
+         ;; the service.
+         (requirement '(loopback))
+         (documentation "Connect to the IPFS network")
+         (start #~(make-forkexec-constructor
+                   #$ipfs-daemon-command
+                   #:log-file "/var/log/ipfs.log"
+                   #:user "ipfs" #:group "ipfs"
+                   #:environment-variables #$%ipfs-environment))
+         (stop #~(make-kill-destructor)))))
+
+(define %ipfs-log-rotation
+  (list (log-rotation
+         (files '("/var/log/ipfs.log")))))
 
 (define (%ipfs-activation config)
   "Return an activation gexp for IPFS with CONFIG"
-  (define (ipfs-config-command setting value)
-    #~(#$(ipfs-binary config) "config" #$setting #$value))
-  (define (set-config!-gexp setting value)
-    #~(system* #$@(ipfs-config-command setting value)))
+  (define (exec-command . args)
+    ;; Exec the given ifps command with the right authority.
+    #~(let ((pid (primitive-fork)))
+        (if (zero? pid)
+            (dynamic-wind
+              (const #t)
+              (lambda ()
+                ;; Run ipfs init and ipfs config from a container,
+                ;; in case the IPFS daemon was compromised at some point
+                ;; and ~/.ipfs is now a symlink to somewhere outside
+                ;; %ipfs-home.
+                (let ((pw (getpwnam "ipfs")))
+                  (setgroups '#())
+                  (setgid (passwd:gid pw))
+                  (setuid (passwd:uid pw))
+                  (environ #$%ipfs-environment)
+                  (execl #$(ipfs-binary config) #$@args)))
+              (lambda ()
+                (primitive-exit 127)))
+            (waitpid pid))))
+
   (define settings
     `(("Addresses.API" ,(ipfs-configuration-api config))
       ("Addresses.Gateway" ,(ipfs-configuration-gateway config))))
+
   (define inner-gexp
     #~(begin
         (umask #o077)
         ;; Create $HOME/.ipfs structure
-        (system* #$(ipfs-binary config) "init")
+        #$(exec-command "ipfs" "init")
         ;; Apply settings
-        #$@(map (cute apply set-config!-gexp <>) settings)))
+        #$@(map (match-lambda
+                  ((setting value)
+                   (exec-command "ipfs" "config" setting value)))
+                settings)))
+
   (define inner-script
     (program-file "ipfs-activation-inner" inner-gexp))
-  ;; Run ipfs init and ipfs config from a container,
-  ;; in case the IPFS daemon was compromised at some point
-  ;; and ~/.ipfs is now a symlink to somewhere outside
-  ;; %ipfs-home.
-  (define container-gexp
-    (with-extensions (list shepherd)
-      (with-imported-modules (source-module-closure
-                              '((gnu build shepherd)
-                                (gnu system file-systems)))
-        #~(begin
-            (use-modules (gnu build shepherd)
-                         (gnu system file-systems))
-            (let* ((constructor
-                    (make-forkexec-constructor/container
-                     (list #$inner-script)
-                     #:namespaces '#$(fold delq %namespaces '(user))
-                     #:mappings (list #$%ipfs-home-mapping)
-                     #:user "ipfs"
-                     #:group "ipfs"
-                     #:environment-variables #$%ipfs-environment))
-                   (pid (constructor)))
-              (waitpid pid))))))
+
   ;; The activation may happen from the initrd, which uses
   ;; a statically-linked guile, while the guix container
   ;; procedures require a working dynamic-link.
-  (define container-script
-    (program-file "ipfs-activation-container" container-gexp))
-  #~(system* #$container-script))
+  #~(system* #$inner-script))
 
 (define ipfs-service-type
   (service-type
@@ -2112,7 +2098,9 @@ See yggdrasil -genconf for config options.")
           (service-extension activation-service-type
                              %ipfs-activation)
           (service-extension shepherd-root-service-type
-                             ipfs-shepherd-service)))
+                             ipfs-shepherd-service)
+          (service-extension rottlog-service-type
+                             (const %ipfs-log-rotation))))
    (default-value (ipfs-configuration))
    (description
     "Run @command{ipfs daemon}, the reference implementation
@@ -2149,10 +2137,16 @@ of the IPFS peer-to-peer storage network.")))
        (respawn? #f)
        (stop #~(make-kill-destructor)))))))
 
+(define %keepalived-log-rotation
+  (list (log-rotation
+         (files '("/var/log/keepalived.log")))))
+
 (define keepalived-service-type
   (service-type (name 'keepalived)
                 (extensions (list (service-extension shepherd-root-service-type
-                                                     keepalived-shepherd-service)))
+                                                     keepalived-shepherd-service)
+                                  (service-extension rottlog-service-type
+                                                     (const %keepalived-log-rotation))))
                 (description
                  "Run @uref{https://www.keepalived.org/, Keepalived}
 routing software.")))
diff --git a/gnu/services/nfs.scm b/gnu/services/nfs.scm
index 0d1617354e..209cde24b3 100644
--- a/gnu/services/nfs.scm
+++ b/gnu/services/nfs.scm
@@ -92,7 +92,10 @@
                (match values
                  ((first . rest) first)
                  (_ config))))
-     (default-value (rpcbind-configuration)))))
+     (default-value (rpcbind-configuration))
+     (description "Run the RPC Bind service, which provides a facility to map
+ONC RPC program numbers into universal addresses.  Many NFS related services
+use this facility."))))
 
 
 
@@ -128,8 +131,13 @@
      ;; configure and start this service.  Only one value can be provided.  We
      ;; override it with the value returned by the extending service.
      (compose identity)
-     (extend (lambda (config values) (first values)))
-     (default-value (pipefs-configuration)))))
+     (extend (lambda (config values)
+               (match values
+                 ((first . rest) first)
+                 (_ config))))
+     (default-value (pipefs-configuration))
+     (description "Mount the pipefs file system, which is used to transfer
+NFS-related data between the kernel and user-space programs."))))
 
 
 
@@ -174,7 +182,10 @@
                (match values
                  ((first . rest) first)
                  (_ config))))
-     (default-value (gss-configuration)))))
+     (default-value (gss-configuration))
+     (description "Run the @dfn{global security system} (GSS) daemon, which
+provides strong security for protocols based on remote procedure calls (ONC
+RPC)."))))
 
 
 
@@ -239,7 +250,10 @@
      ;; override it with the value returned by the extending service.
      (compose identity)
      (extend (lambda (config values) (first values)))
-     (default-value (idmap-configuration)))))
+     (default-value (idmap-configuration))
+     (description "Run the idmap daemon, which provides a mapping between user
+IDs and user names.  It is typically required to access file systems mounted
+via NFSv4."))))
 
 (define-record-type* <nfs-configuration>
   nfs-configuration make-nfs-configuration
diff --git a/gnu/services/shepherd.scm b/gnu/services/shepherd.scm
index b44dbf9d9f..4fd4b2a497 100644
--- a/gnu/services/shepherd.scm
+++ b/gnu/services/shepherd.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013-2016, 2018-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
 ;;; Copyright © 2018 Carlo Zancanaro <carlo@zancanaro.id.au>
 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
@@ -26,6 +26,7 @@
   #:use-module (guix gexp)
   #:use-module (guix store)
   #:use-module (guix records)
+  #:use-module (guix packages)
   #:use-module (guix derivations)                 ;imported-modules, etc.
   #:use-module (guix utils)
   #:use-module (gnu services)
@@ -88,7 +89,7 @@
   shepherd-configuration make-shepherd-configuration
   shepherd-configuration?
   (shepherd shepherd-configuration-shepherd
-            (default shepherd)) ; file-like
+            (default shepherd-0.9)) ; file-like
   (services shepherd-configuration-services
             (default '()))) ; list of <shepherd-service>
 
@@ -304,8 +305,14 @@ stored."
 (define (scm->go file shepherd)
   "Compile FILE, which contains code to be loaded by shepherd's config file,
 and return the resulting '.go' file. SHEPHERD is used as shepherd package."
+  (define shepherd&co
+    (cons shepherd
+          (match (lookup-package-input shepherd "guile-fibers")
+            (#f '())
+            (fibers (list fibers)))))
+
   (let-system (system target)
-    (with-extensions (list shepherd)
+    (with-extensions shepherd&co
       (computed-file (string-append (basename (scheme-file-name file) ".scm")
                                     ".go")
                      #~(begin
@@ -359,29 +366,29 @@ as shepherd package."
                        (map load-compiled '#$(map scm->go files))))))
 
           (format #t "starting services...~%")
-          (for-each (lambda (service)
-                      ;; In the Shepherd 0.3 the 'start' method can raise
-                      ;; '&action-runtime-error' if it fails, so protect
-                      ;; against it.  (XXX: 'action-runtime-error?' is not
-                      ;; exported is 0.3, hence 'service-error?'.)
-                      (guard (c ((service-error? c)
-                                 (format (current-error-port)
-                                         "failed to start service '~a'~%"
-                                         service)))
-                        (start service)))
-                    '#$(append-map shepherd-service-provision
-                                   (filter shepherd-service-auto-start?
-                                           services)))
-
-          ;; Hang up stdin.  At this point, we assume that 'start' methods
-          ;; that required user interaction on the console (e.g.,
-          ;; 'cryptsetup open' invocations, post-fsck emergency REPL) have
-          ;; completed.  User interaction becomes impossible after this
-          ;; call; this avoids situations where services wrongfully lead
-          ;; PID 1 to read from stdin (the console), which users may not
-          ;; have access to (see <https://bugs.gnu.org/23697>).
-          (redirect-port (open-input-file "/dev/null")
-                         (current-input-port))))
+          (let ((services-to-start
+                 '#$(append-map shepherd-service-provision
+                                (filter shepherd-service-auto-start?
+                                        services))))
+            (if (defined? 'start-in-the-background)
+                (start-in-the-background services-to-start)
+                (for-each (lambda (service)       ;pre-0.9.0 compatibility
+                            (guard (c ((service-error? c)
+                                       (format (current-error-port)
+                                               "failed to start service '~a'~%"
+                                               service)))
+                              (start service)))
+                          services-to-start))
+
+            ;; Hang up stdin.  At this point, we assume that 'start' methods
+            ;; that required user interaction on the console (e.g.,
+            ;; 'cryptsetup open' invocations, post-fsck emergency REPL) have
+            ;; completed.  User interaction becomes impossible after this
+            ;; call; this avoids situations where services wrongfully lead
+            ;; PID 1 to read from stdin (the console), which users may not
+            ;; have access to (see <https://bugs.gnu.org/23697>).
+            (redirect-port (open-input-file "/dev/null")
+                           (current-input-port)))))
 
     (scheme-file "shepherd.conf" config)))
 
@@ -463,8 +470,13 @@ need to be restarted to complete their upgrade."
     (filter running? target))
 
   (define to-unload
-    ;; Unload services that are no longer required.
-    (remove essential? (filter obsolete? live)))
+    ;; Unload services that are no longer required.  Essential services must
+    ;; be kept and transient services such as inetd child services should be
+    ;; kept as well--they'll vanish eventually.
+    (remove (lambda (live)
+              (or (essential? live)
+                  (live-service-transient? live)))
+            (filter obsolete? live)))
 
   (values to-unload to-restart))
 
diff --git a/gnu/services/spice.scm b/gnu/services/spice.scm
index 3b88e29043..e5ec46b9b5 100644
--- a/gnu/services/spice.scm
+++ b/gnu/services/spice.scm
@@ -69,7 +69,10 @@
     (list (service-extension shepherd-root-service-type
                              spice-vdagent-shepherd-service)
           (service-extension profile-service-type
-                             spice-vdagent-profile)))))
+                             spice-vdagent-profile)))
+   (description "Start the @command{vdagentd} and @command{vdagent} daemons
+from the @code{spice-vdagent} package to enable window resizing and clipboard
+sharing for @acronym{VM, virtual machine} guests.")))
 
 (define* (spice-vdagent-service
           #:optional (config (spice-vdagent-configuration)))
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 5c8fe4eef4..57d3ad218c 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -292,6 +292,9 @@ The other options should be self-descriptive."
   ;; integer
   (port-number           openssh-configuration-port-number
                          (default 22))
+  ;; integer
+  (max-connections       openssh-configuration-max-connections
+                         (default 200))
   ;; Boolean | 'prohibit-password
   (permit-root-login     openssh-configuration-permit-root-login
                          (default #f))
@@ -391,7 +394,7 @@ The other options should be self-descriptive."
         ;; authorized-key directory to /etc.
         (catch 'system-error
           (lambda ()
-            (delete-file-recursively "/etc/authorized_keys.d"))
+            (delete-file-recursively "/etc/ssh/authorized_keys.d"))
           (lambda args
             (unless (= ENOENT (system-error-errno args))
               (apply throw args))))
@@ -515,17 +518,44 @@ of user-name/file-like tuples."
   (define pid-file
     (openssh-configuration-pid-file config))
 
+  (define port-number
+    (openssh-configuration-port-number config))
+
+  (define max-connections
+    (openssh-configuration-max-connections config))
+
   (define openssh-command
     #~(list (string-append #$(openssh-configuration-openssh config) "/sbin/sshd")
             "-D" "-f" #$(openssh-config-file config)))
 
+  (define inetd-style?
+    ;; Whether to use 'make-inetd-constructor'.  That procedure appeared in
+    ;; Shepherd 0.9.0, but in 0.9.0, 'make-inetd-constructor' wouldn't let us
+    ;; pass a list of endpoints, and it wouldn't let us define a service
+    ;; listening on both IPv4 and IPv6, hence the conditional below.
+    #~(and (defined? 'make-inetd-constructor)
+           (not (string=? (@ (shepherd config) Version) "0.9.0"))))
+
   (list (shepherd-service
          (documentation "OpenSSH server.")
          (requirement '(syslogd loopback))
          (provision '(ssh-daemon ssh sshd))
-         (start #~(make-forkexec-constructor #$openssh-command
-                                             #:pid-file #$pid-file))
-         (stop #~(make-kill-destructor))
+
+         (start #~(if #$inetd-style?
+                      (make-inetd-constructor
+                       (append #$openssh-command '("-i"))
+                       (list (endpoint
+                              (make-socket-address AF_INET INADDR_ANY
+                                                   #$port-number))
+                             (endpoint
+                              (make-socket-address AF_INET6 IN6ADDR_ANY
+                                                   #$port-number)))
+                       #:max-connections #$max-connections)
+                      (make-forkexec-constructor #$openssh-command
+                                                 #:pid-file #$pid-file)))
+         (stop #~(if #$inetd-style?
+                     (make-inetd-destructor)
+                     (make-kill-destructor)))
          (auto-start? (openssh-auto-start? config)))))
 
 (define (openssh-pam-services config)
@@ -541,11 +571,10 @@ of user-name/file-like tuples."
   (openssh-configuration
    (inherit config)
    (authorized-keys
-    (match (openssh-configuration-authorized-keys config)
-      (((users _ ...) ...)
+    (match (append (openssh-configuration-authorized-keys config) keys)
+      ((and alist ((users _ ...) ...))
        ;; Build a user/key-list mapping.
-       (let ((user-keys (alist->vhash
-                         (openssh-configuration-authorized-keys config))))
+       (let ((user-keys (alist->vhash alist)))
          ;; Coalesce the key lists associated with each user.
          (map (lambda (user)
                 `(,user
diff --git a/gnu/services/sysctl.scm b/gnu/services/sysctl.scm
index 80ed2ff46f..05fe6f4f7f 100644
--- a/gnu/services/sysctl.scm
+++ b/gnu/services/sysctl.scm
@@ -81,4 +81,6 @@
               (inherit config)
               (settings (append (sysctl-configuration-settings config)
                                 settings)))))
-   (default-value (sysctl-configuration))))
+   (default-value (sysctl-configuration))
+   (description "Set Linux kernel parameters under @file{/proc/sys} at system
+startup time.")))
diff --git a/gnu/services/telephony.scm b/gnu/services/telephony.scm
index e678bae87c..d8ebc7b39d 100644
--- a/gnu/services/telephony.scm
+++ b/gnu/services/telephony.scm
@@ -28,6 +28,7 @@
   #:use-module (gnu packages glib)
   #:use-module (gnu packages jami)
   #:use-module (gnu packages telephony)
+  #:use-module (guix deprecation)
   #:use-module (guix records)
   #:use-module (guix modules)
   #:use-module (guix packages)
@@ -56,53 +57,53 @@
 
             jami-service-type
 
-            murmur-configuration
-            make-murmur-configuration
-            murmur-configuration?
-            murmur-configuration-package
-            murmur-configuration-user
-            murmur-configuration-group
-            murmur-configuration-port
-            murmur-configuration-welcome-text
-            murmur-configuration-server-password
-            murmur-configuration-max-users
-            murmur-configuration-max-user-bandwidth
-            murmur-configuration-database-file
-            murmur-configuration-log-file
-            murmur-configuration-pid-file
-            murmur-configuration-autoban-attempts
-            murmur-configuration-autoban-timeframe
-            murmur-configuration-autoban-time
-            murmur-configuration-opus-threshold
-            murmur-configuration-channel-nesting-limit
-            murmur-configuration-channelname-regex
-            murmur-configuration-username-regex
-            murmur-configuration-text-message-length
-            murmur-configuration-image-message-length
-            murmur-configuration-cert-required?
-            murmur-configuration-remember-channel?
-            murmur-configuration-allow-html?
-            murmur-configuration-allow-ping?
-            murmur-configuration-bonjour?
-            murmur-configuration-send-version?
-            murmur-configuration-log-days
-            murmur-configuration-obfuscate-ips?
-            murmur-configuration-ssl-cert
-            murmur-configuration-ssl-key
-            murmur-configuration-ssl-dh-params
-            murmur-configuration-ssl-ciphers
-            murmur-configuration-public-registration
-            murmur-configuration-file
-
-            murmur-public-registration-configuration
-            make-murmur-public-registration-configuration
-            murmur-public-registration-configuration?
-            murmur-public-registration-configuration-name
-            murmur-public-registration-configuration-url
-            murmur-public-registration-configuration-password
-            murmur-public-registration-configuration-hostname
-
-            murmur-service-type))
+            mumble-server-configuration
+            make-mumble-server-configuration
+            mumble-server-configuration?
+            mumble-server-configuration-package
+            mumble-server-configuration-user
+            mumble-server-configuration-group
+            mumble-server-configuration-port
+            mumble-server-configuration-welcome-text
+            mumble-server-configuration-server-password
+            mumble-server-configuration-max-users
+            mumble-server-configuration-max-user-bandwidth
+            mumble-server-configuration-database-file
+            mumble-server-configuration-log-file
+            mumble-server-configuration-pid-file
+            mumble-server-configuration-autoban-attempts
+            mumble-server-configuration-autoban-timeframe
+            mumble-server-configuration-autoban-time
+            mumble-server-configuration-opus-threshold
+            mumble-server-configuration-channel-nesting-limit
+            mumble-server-configuration-channelname-regex
+            mumble-server-configuration-username-regex
+            mumble-server-configuration-text-message-length
+            mumble-server-configuration-image-message-length
+            mumble-server-configuration-cert-required?
+            mumble-server-configuration-remember-channel?
+            mumble-server-configuration-allow-html?
+            mumble-server-configuration-allow-ping?
+            mumble-server-configuration-bonjour?
+            mumble-server-configuration-send-version?
+            mumble-server-configuration-log-days
+            mumble-server-configuration-obfuscate-ips?
+            mumble-server-configuration-ssl-cert
+            mumble-server-configuration-ssl-key
+            mumble-server-configuration-ssl-dh-params
+            mumble-server-configuration-ssl-ciphers
+            mumble-server-configuration-public-registration
+            mumble-server-configuration-file
+
+            mumble-server-public-registration-configuration
+            make-mumble-server-public-registration-configuration
+            mumble-server-public-registration-configuration?
+            mumble-server-public-registration-configuration-name
+            mumble-server-public-registration-configuration-url
+            mumble-server-public-registration-configuration-password
+            mumble-server-public-registration-configuration-hostname
+
+            mumble-server-service-type))
 
 
 ;;;
@@ -747,91 +748,91 @@ normal user D-Bus session bus.")))
 
 
 ;;;
-;;; Murmur.
+;;; Mumble server.
 ;;;
 
 ;; https://github.com/mumble-voip/mumble/blob/master/scripts/murmur.ini
 
-(define-record-type* <murmur-configuration> murmur-configuration
-  make-murmur-configuration
-  murmur-configuration?
-  (package               murmur-configuration-package ;file-like
+(define-record-type* <mumble-server-configuration> mumble-server-configuration
+  make-mumble-server-configuration
+  mumble-server-configuration?
+  (package               mumble-server-configuration-package ;file-like
                          (default mumble))
-  (user                  murmur-configuration-user
-                         (default "murmur"))
-  (group                 murmur-configuration-group
-                         (default "murmur"))
-  (port                  murmur-configuration-port
+  (user                  mumble-server-configuration-user
+                         (default "mumble-server"))
+  (group                 mumble-server-configuration-group
+                         (default "mumble-server"))
+  (port                  mumble-server-configuration-port
                          (default 64738))
-  (welcome-text          murmur-configuration-welcome-text
+  (welcome-text          mumble-server-configuration-welcome-text
                          (default ""))
-  (server-password       murmur-configuration-server-password
+  (server-password       mumble-server-configuration-server-password
                          (default ""))
-  (max-users             murmur-configuration-max-users
+  (max-users             mumble-server-configuration-max-users
                          (default 100))
-  (max-user-bandwidth    murmur-configuration-max-user-bandwidth
+  (max-user-bandwidth    mumble-server-configuration-max-user-bandwidth
                          (default #f))
-  (database-file         murmur-configuration-database-file
-                         (default "/var/lib/murmur/db.sqlite"))
-  (log-file              murmur-configuration-log-file
-                         (default "/var/log/murmur/murmur.log"))
-  (pid-file              murmur-configuration-pid-file
-                         (default "/var/run/murmur/murmur.pid"))
-  (autoban-attempts      murmur-configuration-autoban-attempts
+  (database-file         mumble-server-configuration-database-file
+                         (default "/var/lib/mumble-server/db.sqlite"))
+  (log-file              mumble-server-configuration-log-file
+                         (default "/var/log/mumble-server/mumble-server.log"))
+  (pid-file              mumble-server-configuration-pid-file
+                         (default "/var/run/mumble-server/mumble-server.pid"))
+  (autoban-attempts      mumble-server-configuration-autoban-attempts
                          (default 10))
-  (autoban-timeframe     murmur-configuration-autoban-timeframe
+  (autoban-timeframe     mumble-server-configuration-autoban-timeframe
                          (default 120))
-  (autoban-time          murmur-configuration-autoban-time
+  (autoban-time          mumble-server-configuration-autoban-time
                          (default 300))
-  (opus-threshold        murmur-configuration-opus-threshold
+  (opus-threshold        mumble-server-configuration-opus-threshold
                          (default 100)) ; integer percent
-  (channel-nesting-limit murmur-configuration-channel-nesting-limit
+  (channel-nesting-limit mumble-server-configuration-channel-nesting-limit
                          (default 10))
-  (channelname-regex     murmur-configuration-channelname-regex
+  (channelname-regex     mumble-server-configuration-channelname-regex
                          (default #f))
-  (username-regex        murmur-configuration-username-regex
+  (username-regex        mumble-server-configuration-username-regex
                          (default #f))
-  (text-message-length   murmur-configuration-text-message-length
+  (text-message-length   mumble-server-configuration-text-message-length
                          (default 5000))
-  (image-message-length  murmur-configuration-image-message-length
+  (image-message-length  mumble-server-configuration-image-message-length
                          (default (* 128 1024))) ; 128 Kilobytes
-  (cert-required?         murmur-configuration-cert-required?
+  (cert-required?         mumble-server-configuration-cert-required?
                           (default #f))
-  (remember-channel?     murmur-configuration-remember-channel?
+  (remember-channel?     mumble-server-configuration-remember-channel?
                          (default #f))
-  (allow-html?           murmur-configuration-allow-html?
+  (allow-html?           mumble-server-configuration-allow-html?
                          (default #f))
-  (allow-ping?           murmur-configuration-allow-ping?
+  (allow-ping?           mumble-server-configuration-allow-ping?
                          (default #f))
-  (bonjour?              murmur-configuration-bonjour?
+  (bonjour?              mumble-server-configuration-bonjour?
                          (default #f))
-  (send-version?         murmur-configuration-send-version?
+  (send-version?         mumble-server-configuration-send-version?
                          (default #f))
-  (log-days              murmur-configuration-log-days
+  (log-days              mumble-server-configuration-log-days
                          (default 31))
-  (obfuscate-ips?        murmur-obfuscate-ips?
+  (obfuscate-ips?        mumble-server-obfuscate-ips?
                          (default #t))
-  (ssl-cert              murmur-configuration-ssl-cert
+  (ssl-cert              mumble-server-configuration-ssl-cert
                          (default #f))
-  (ssl-key               murmur-configuration-ssl-key
+  (ssl-key               mumble-server-configuration-ssl-key
                          (default #f))
-  (ssl-dh-params         murmur-configuration-ssl-dh-params
+  (ssl-dh-params         mumble-server-configuration-ssl-dh-params
                          (default #f))
-  (ssl-ciphers           murmur-configuration-ssl-ciphers
+  (ssl-ciphers           mumble-server-configuration-ssl-ciphers
                          (default #f))
-  (public-registration   murmur-configuration-public-registration
-                         (default #f))  ; <murmur-public-registration-configuration>
-  (file                  murmur-configuration-file
+  (public-registration   mumble-server-configuration-public-registration
+                         (default #f))  ; <mumble-server-public-registration-configuration>
+  (file                  mumble-server-configuration-file
                          (default #f)))
 
-(define-record-type* <murmur-public-registration-configuration>
-  murmur-public-registration-configuration
-  make-murmur-public-registration-configuration
-  murmur-public-registration-configuration?
-  (name         murmur-public-registration-configuration-name)
-  (password     murmur-public-registration-configuration-password)
-  (url          murmur-public-registration-configuration-url)
-  (hostname     murmur-public-registration-configuration-hostname
+(define-record-type* <mumble-server-public-registration-configuration>
+  mumble-server-public-registration-configuration
+  make-mumble-server-public-registration-configuration
+  mumble-server-public-registration-configuration?
+  (name         mumble-server-public-registration-configuration-name)
+  (password     mumble-server-public-registration-configuration-password)
+  (url          mumble-server-public-registration-configuration-url)
+  (hostname     mumble-server-public-registration-configuration-hostname
                 (default #f)))
 
 (define (flatten . lst)
@@ -842,10 +843,10 @@ normal user D-Bus session bus.")))
         (cons head out)))
   (fold-right flatten1 '() lst))
 
-(define (default-murmur-config config)
+(define (default-mumble-server-config config)
   (match-record
    config
-   <murmur-configuration>
+   <mumble-server-configuration>
    (user port welcome-text server-password max-users max-user-bandwidth
     database-file log-file pid-file autoban-attempts autoban-timeframe
     autoban-time opus-threshold channel-nesting-limit channelname-regex
@@ -853,7 +854,7 @@ normal user D-Bus session bus.")))
     remember-channel? allow-html? allow-ping? bonjour? send-version?
     log-days obfuscate-ips? ssl-cert ssl-key ssl-dh-params ssl-ciphers
     public-registration)
-   (apply mixed-text-file "murmur.ini"
+   (apply mixed-text-file "mumble-server.ini"
           (flatten
            "welcometext=" welcome-text "\n"
            "port=" (number->string port) "\n"
@@ -896,7 +897,7 @@ normal user D-Bus session bus.")))
 
            (match public-registration
              (#f '())
-             (($ <murmur-public-registration-configuration>
+             (($ <mumble-server-public-registration-configuration>
                  name password url hostname)
               (if (and (or (not server-password) (string-null? server-password))
                        allow-ping?)
@@ -907,41 +908,41 @@ normal user D-Bus session bus.")))
                    (if hostname
                        (string-append "registerHostname=" hostname "\n")
                        ""))
-                  (error "To publicly register your murmur server your server must be publicy visible
+                  (error "To publicly register your mumble-server server your server must be publicy visible
 and users must be able to join without a password. To fix this set:
 (allow-ping? #t)
 (server-password \"\")
 Or set public-registration to #f"))))))))
 
-(define (murmur-activation config)
+(define (mumble-server-activation config)
   #~(begin
       (use-modules (guix build utils))
-      (let* ((log-dir (dirname #$(murmur-configuration-log-file config)))
-             (pid-dir (dirname #$(murmur-configuration-pid-file config)))
-             (db-dir (dirname #$(murmur-configuration-database-file config)))
-             (user (getpwnam #$(murmur-configuration-user config)))
+      (let* ((log-dir (dirname #$(mumble-server-configuration-log-file config)))
+             (pid-dir (dirname #$(mumble-server-configuration-pid-file config)))
+             (db-dir (dirname #$(mumble-server-configuration-database-file config)))
+             (user (getpwnam #$(mumble-server-configuration-user config)))
              (init-dir
               (lambda (name dir)
-                (format #t "creating murmur ~a directory '~a'\n" name dir)
+                (format #t "creating mumble-server ~a directory '~a'\n" name dir)
                 (mkdir-p dir)
                 (chown dir (passwd:uid user) (passwd:gid user))
                 (chmod dir #o700)))
-             (ini #$(or (murmur-configuration-file config)
-                        (default-murmur-config config))))
+             (ini #$(or (mumble-server-configuration-file config)
+                        (default-mumble-server-config config))))
         (init-dir "log" log-dir)
         (init-dir "pid" pid-dir)
         (init-dir "database" db-dir)
 
-        (format #t "murmur: use config file: ~a~%\n" ini)
-        (format #t "murmur: to set the SuperUser password run:
+        (format #t "mumble-server: use config file: ~a~%\n" ini)
+        (format #t "mumble-server: to set the SuperUser password run:
     `~a -ini ~a -readsupw`\n"
-                #$(file-append (murmur-configuration-package config)
-                               "/bin/murmurd") ini)
+                #$(file-append (mumble-server-configuration-package config)
+                               "/bin/mumble-server") ini)
         #t)))
 
-(define murmur-accounts
+(define mumble-server-accounts
   (match-lambda
-    (($ <murmur-configuration> _ user group)
+    (($ <mumble-server-configuration> _ user group)
      (list
       (user-group
        (name group)
@@ -950,37 +951,174 @@ Or set public-registration to #f"))))))))
        (name user)
        (group group)
        (system? #t)
-       (comment "Murmur Daemon")
+       (comment "Mumble server daemon")
        (home-directory "/var/empty")
        (shell (file-append shadow "/sbin/nologin")))))))
 
-(define (murmur-shepherd-service config)
+(define (mumble-server-shepherd-service config)
   (list (shepherd-service
-         (provision '(murmur))
-         (documentation "Run the Murmur Mumble server.")
+         (provision '(mumble-server))
+         (documentation "Run the Mumble server.")
          (requirement '(networking))
          (start #~(make-forkexec-constructor
-                   '(#$(file-append (murmur-configuration-package config)
-                                    "/bin/murmurd")
+                   '(#$(file-append (mumble-server-configuration-package config)
+                                    "/bin/mumble-server")
                      "-ini"
-                     #$(or (murmur-configuration-file config)
-                           (default-murmur-config config)))
-                   #:pid-file #$(murmur-configuration-pid-file config)))
+                     #$(or (mumble-server-configuration-file config)
+                           (default-mumble-server-config config)))
+                   #:pid-file #$(mumble-server-configuration-pid-file config)))
          (stop #~(make-kill-destructor)))))
 
-(define murmur-service-type
-  (service-type (name 'murmur)
+(define mumble-server-service-type
+  (service-type (name 'mumble-server)
                 (description
-                 "Run the Murmur voice-over-IP (VoIP) server of the Mumble
-suite.")
+                 "Run the Mumble voice-over-IP (VoIP) server.")
                 (extensions
                  (list (service-extension shepherd-root-service-type
-                                          murmur-shepherd-service)
+                                          mumble-server-shepherd-service)
                        (service-extension activation-service-type
-                                          murmur-activation)
+                                          mumble-server-activation)
                        (service-extension account-service-type
-                                          murmur-accounts)))
-                (default-value (murmur-configuration))))
+                                          mumble-server-accounts)))
+                (default-value (mumble-server-configuration))))
+
+(define-deprecated/public-alias
+  murmur-configuration
+  mumble-server-configuration)
+(define-deprecated/public-alias
+  make-murmur-configuration
+  make-mumble-server-configuration)
+(define-deprecated/public-alias
+  murmur-configuration?
+  mumble-server-configuration?)
+(define-deprecated/public-alias
+  murmur-configuration-package
+  mumble-server-configuration-package)
+(define-deprecated/public-alias
+  murmur-configuration-user
+  mumble-server-configuration-user)
+(define-deprecated/public-alias
+  murmur-configuration-group
+  mumble-server-configuration-group)
+(define-deprecated/public-alias
+  murmur-configuration-port
+  mumble-server-configuration-port)
+(define-deprecated/public-alias
+  murmur-configuration-welcome-text
+  mumble-server-configuration-welcome-text)
+(define-deprecated/public-alias
+  murmur-configuration-server-password
+  mumble-server-configuration-server-password)
+(define-deprecated/public-alias
+  murmur-configuration-max-users
+  mumble-server-configuration-max-users)
+(define-deprecated/public-alias
+  murmur-configuration-max-user-bandwidth
+  mumble-server-configuration-max-user-bandwidth)
+(define-deprecated/public-alias
+  murmur-configuration-database-file
+  mumble-server-configuration-database-file)
+(define-deprecated/public-alias
+  murmur-configuration-log-file
+  mumble-server-configuration-log-file)
+(define-deprecated/public-alias
+  murmur-configuration-pid-file
+  mumble-server-configuration-pid-file)
+(define-deprecated/public-alias
+  murmur-configuration-autoban-attempts
+  mumble-server-configuration-autoban-attempts)
+(define-deprecated/public-alias
+  murmur-configuration-autoban-timeframe
+  mumble-server-configuration-autoban-timeframe)
+(define-deprecated/public-alias
+  murmur-configuration-autoban-time
+  mumble-server-configuration-autoban-time)
+(define-deprecated/public-alias
+  murmur-configuration-opus-threshold
+  mumble-server-configuration-opus-threshold)
+(define-deprecated/public-alias
+  murmur-configuration-channel-nesting-limit
+  mumble-server-configuration-channel-nesting-limit)
+(define-deprecated/public-alias
+  murmur-configuration-channelname-regex
+  mumble-server-configuration-channelname-regex)
+(define-deprecated/public-alias
+  murmur-configuration-username-regex
+  mumble-server-configuration-username-regex)
+(define-deprecated/public-alias
+  murmur-configuration-text-message-length
+  mumble-server-configuration-text-message-length)
+(define-deprecated/public-alias
+  murmur-configuration-image-message-length
+  mumble-server-configuration-image-message-length)
+(define-deprecated/public-alias
+  murmur-configuration-cert-required?
+  mumble-server-configuration-cert-required?)
+(define-deprecated/public-alias
+  murmur-configuration-remember-channel?
+  mumble-server-configuration-remember-channel?)
+(define-deprecated/public-alias
+  murmur-configuration-allow-html?
+  mumble-server-configuration-allow-html?)
+(define-deprecated/public-alias
+  murmur-configuration-allow-ping?
+  mumble-server-configuration-allow-ping?)
+(define-deprecated/public-alias
+  murmur-configuration-bonjour?
+  mumble-server-configuration-bonjour?)
+(define-deprecated/public-alias
+  murmur-configuration-send-version?
+  mumble-server-configuration-send-version?)
+(define-deprecated/public-alias
+  murmur-configuration-log-days
+  mumble-server-configuration-log-days)
+(define-deprecated/public-alias
+  murmur-configuration-obfuscate-ips?
+  mumble-server-configuration-obfuscate-ips?)
+(define-deprecated/public-alias
+  murmur-configuration-ssl-cert
+  mumble-server-configuration-ssl-cert)
+(define-deprecated/public-alias
+  murmur-configuration-ssl-key
+  mumble-server-configuration-ssl-key)
+(define-deprecated/public-alias
+  murmur-configuration-ssl-dh-params
+  mumble-server-configuration-ssl-dh-params)
+(define-deprecated/public-alias
+  murmur-configuration-ssl-ciphers
+  mumble-server-configuration-ssl-ciphers)
+(define-deprecated/public-alias
+  murmur-configuration-public-registration
+  mumble-server-configuration-public-registration)
+(define-deprecated/public-alias
+  murmur-configuration-file
+  mumble-server-configuration-file)
+
+(define-deprecated/public-alias
+  murmur-public-registration-configuration
+  mumble-server-public-registration-configuration)
+(define-deprecated/public-alias
+  make-murmur-public-registration-configuration
+  make-mumble-server-public-registration-configuration)
+(define-deprecated/public-alias
+  murmur-public-registration-configuration?
+  mumble-server-public-registration-configuration?)
+(define-deprecated/public-alias
+  murmur-public-registration-configuration-name
+  mumble-server-public-registration-configuration-name)
+(define-deprecated/public-alias
+  murmur-public-registration-configuration-url
+  mumble-server-public-registration-configuration-url)
+(define-deprecated/public-alias
+  murmur-public-registration-configuration-password
+  mumble-server-public-registration-configuration-password)
+(define-deprecated/public-alias
+  murmur-public-registration-configuration-hostname
+  mumble-server-public-registration-configuration-hostname)
+
+(define-deprecated/public-alias
+  murmur-service-type
+  mumble-server-service-type)
 
 ;; Local Variables:
 ;; eval: (put 'with-retries 'scheme-indent-function 2)
diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm
index 70d4d6c34c..41afe451c1 100644
--- a/gnu/services/virtualization.scm
+++ b/gnu/services/virtualization.scm
@@ -501,7 +501,10 @@ potential infinite waits blocking libvirt."))
                                      libvirt-shepherd-service)
                   (service-extension account-service-type
                                      (const %libvirt-accounts))))
-                (default-value (libvirt-configuration))))
+                (default-value (libvirt-configuration))
+                (description "Run @command{libvirtd}, a daemon of the libvirt
+virtualization management system.  This daemon runs on host servers and
+performs required management tasks for virtualized guests.")))
 
 
 (define-record-type* <virtlog-configuration>
@@ -550,7 +553,9 @@ potential infinite waits blocking libvirt."))
                  (list
                   (service-extension shepherd-root-service-type
                                      virtlogd-shepherd-service)))
-                (default-value (virtlog-configuration))))
+                (default-value (virtlog-configuration))
+                (description "Run @command{virtlogd}, a daemon libvirt that is
+used to manage logs from @acronym{VM, virtual machine} consoles.")))
 
 (define (generate-libvirt-documentation)
   (generate-documentation
diff --git a/gnu/services/vpn.scm b/gnu/services/vpn.scm
index b24e9cffb3..a3dc96c1a2 100644
--- a/gnu/services/vpn.scm
+++ b/gnu/services/vpn.scm
@@ -522,7 +522,9 @@ is truncated and rewritten every minute.")
                        (service-extension account-service-type
                                           (const %openvpn-accounts))
                        (service-extension activation-service-type
-                                          (const %openvpn-activation))))))
+                                          (const %openvpn-activation))))
+                (description "Run the OpenVPN server, which allows you to
+@emph{host} a @acronym{VPN, virtual private network}.")))
 
 (define openvpn-client-service-type
   (service-type (name 'openvpn-client)
@@ -532,7 +534,10 @@ is truncated and rewritten every minute.")
                        (service-extension account-service-type
                                           (const %openvpn-accounts))
                        (service-extension activation-service-type
-                                          (const %openvpn-activation))))))
+                                          (const %openvpn-activation))))
+                (description
+                 "Run the OpenVPN client service, which allows you to connect
+to an existing @acronym{VPN, virtual private network}.")))
 
 (define* (openvpn-client-service #:key (config (openvpn-client-configuration)))
   (validate-configuration config openvpn-client-configuration-fields)
@@ -819,4 +824,6 @@ PostUp = ~a set %i private-key ~a
     (list (service-extension shepherd-root-service-type
                              wireguard-shepherd-service)
           (service-extension activation-service-type
-                             wireguard-activation)))))
+                             wireguard-activation)))
+   (description "Set up Wireguard @acronym{VPN, Virtual Private Network}
+tunnels.")))
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index 2c7df19222..4f06d4e0bb 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
-;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2016 Nikita <nikita@n0.is>
 ;;; Copyright © 2016, 2017, 2018 Julien Lepiller <julien@lepiller.eu>
 ;;; Copyright © 2017, 2018, 2019 Christopher Baines <mail@cbaines.net>
@@ -486,7 +486,8 @@
                 (compose concatenate)
                 (extend httpd-process-extensions)
                 (default-value
-                  (httpd-configuration))))
+                  (httpd-configuration))
+                (description "Run the Apache httpd Web server.")))
 
 (define-record-type* <nginx-server-configuration>
   nginx-server-configuration make-nginx-server-configuration
@@ -867,7 +868,9 @@ of index files."
                                           fcgiwrap-accounts)
                        (service-extension activation-service-type
                                           fcgiwrap-activation)))
-                (default-value (fcgiwrap-configuration))))
+                (default-value (fcgiwrap-configuration))
+                (description "Run FastCGI, an interface between the front-end
+and the back-end of a Web service.")))
 
 (define-record-type* <php-fpm-configuration> php-fpm-configuration
   make-php-fpm-configuration
@@ -2010,10 +2013,12 @@ root=/srv/gemini
 
 (define agate-service-type
   (service-type
-   (name 'guix)
+   (name 'agate)
    (extensions
     (list (service-extension account-service-type
                              agate-accounts)
           (service-extension shepherd-root-service-type
                              agate-shepherd-service)))
-   (default-value (agate-configuration))))
+   (default-value (agate-configuration))
+   (description "Run Agate, a simple Gemini protocol server written in
+Rust.")))
diff --git a/gnu/services/xorg.scm b/gnu/services/xorg.scm
index d6dfb07425..0cbd9aa53b 100644
--- a/gnu/services/xorg.scm
+++ b/gnu/services/xorg.scm
@@ -145,8 +145,7 @@
 
         xf86-input-evdev
         xf86-input-keyboard
-        xf86-input-mouse
-        xf86-input-synaptics))
+        xf86-input-mouse))
 
 (define %default-xorg-fonts
   ;; Default list of fonts available to the X server.