gnu: services: Fix mysql service activation.
[jackhill/guix/guix.git] / gnu / services / dbus.scm
index 26390a4..7b3c810 100644 (file)
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -26,6 +26,7 @@
   #:use-module (gnu packages polkit)
   #:use-module (gnu packages admin)
   #:use-module (guix gexp)
+  #:use-module ((guix packages) #:select (package-name))
   #:use-module (guix records)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
@@ -33,6 +34,7 @@
             dbus-configuration?
             dbus-root-service-type
             dbus-service
+            wrapped-dbus-service
 
             polkit-service-type
             polkit-service))
@@ -63,7 +65,7 @@ all the services that may be activated by the daemon."
                                        (find-files
                                         (string-append
                                          service
-                                         "/share/dbus-1/system-services")
+                                         "/share/dbus-1/")
                                         "\\.service$"))
                                      (list #$@services)))
 
@@ -84,6 +86,19 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
         (use-modules (sxml simple)
                      (srfi srfi-1))
 
+        (define-syntax directives
+          (syntax-rules ()
+            ;; Expand the given directives (SXML expressions) only if their
+            ;; key names a file that exists.
+            ((_ (name directory) rest ...)
+             (let ((dir directory))
+               (if (file-exists? dir)
+                   `((name ,dir)
+                     ,@(directives rest ...))
+                   (directives rest ...))))
+            ((_)
+             '())))
+
         (define (services->sxml services)
           ;; Return the SXML 'includedir' clauses for DIRS.
           `(busconfig
@@ -96,10 +111,13 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
             (servicedir "/etc/dbus-1/system-services")
 
             ,@(append-map (lambda (dir)
-                            `((includedir
-                               ,(string-append dir "/etc/dbus-1/system.d"))
-                              (servicedir       ;for '.service' files
-                               ,(string-append dir "/share/dbus-1/services"))))
+                            (directives
+                             (includedir
+                              (string-append dir "/etc/dbus-1/system.d"))
+                             (includedir
+                              (string-append dir "/share/dbus-1/system.d"))
+                             (servicedir          ;for '.service' files
+                              (string-append dir "/share/dbus-1/services"))))
                           services)))
 
         (mkdir #$output)
@@ -150,22 +168,17 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
 
       (let ((user (getpwnam "messagebus")))
         (chown "/var/run/dbus"
-               (passwd:uid user) (passwd:gid user)))
+               (passwd:uid user) (passwd:gid user))
+
+        ;; This directory contains the daemon's socket so it must be
+        ;; world-readable.
+        (chmod "/var/run/dbus" #o755))
 
       (unless (file-exists? "/etc/machine-id")
         (format #t "creating /etc/machine-id...~%")
-        (let ((prog (string-append #$(dbus-configuration-dbus config)
-                                   "/bin/dbus-uuidgen")))
-          ;; XXX: We can't use 'system' because the initrd's
-          ;; guile system(3) only works when 'sh' is in $PATH.
-          (let ((pid (primitive-fork)))
-            (if (zero? pid)
-                (call-with-output-file "/etc/machine-id"
-                  (lambda (port)
-                    (close-fdes 1)
-                    (dup2 (port->fdes port) 1)
-                    (execl prog)))
-                (waitpid pid)))))))
+        (invoke (string-append #$(dbus-configuration-dbus config)
+                               "/bin/dbus-uuidgen")
+                "--ensure=/etc/machine-id"))))
 
 (define dbus-shepherd-service
   (match-lambda
@@ -173,10 +186,10 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
      (list (shepherd-service
             (documentation "Run the D-Bus system daemon.")
             (provision '(dbus-system))
-            (requirement '(user-processes))
+            (requirement '(user-processes syslogd))
             (start #~(make-forkexec-constructor
                       (list (string-append #$dbus "/bin/dbus-daemon")
-                            "--nofork" "--system")
+                            "--nofork" "--system" "--syslog-only")
                       #:pid-file "/var/run/dbus/pid"))
             (stop #~(make-kill-destructor)))))))
 
@@ -205,7 +218,12 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
                            (inherit config)
                            (services
                             (append (dbus-configuration-services config)
-                                    services)))))))
+                                    services)))))
+
+                (default-value (dbus-configuration))
+                (description "Run the system-wide D-Bus inter-process message
+bus.  It allows programs and daemons to communicate and is also responsible
+for spawning (@dfn{activating}) D-Bus services on demand.")))
 
 (define* (dbus-service #:key (dbus dbus) (services '()))
   "Return a service that runs the \"system bus\", using @var{dbus}, with
@@ -223,6 +241,52 @@ and policy files.  For example, to allow avahi-daemon to use the system bus,
            (dbus-configuration (dbus dbus)
                                (services services))))
 
+(define (wrapped-dbus-service service program variables)
+  "Return a wrapper for @var{service}, a package containing a D-Bus service,
+where @var{program} is wrapped such that @var{variables}, a list of name/value
+tuples, are all set as environment variables when the bus daemon launches it."
+  (define wrapper
+    (program-file (string-append (package-name service) "-program-wrapper")
+                  #~(begin
+                      (use-modules (ice-9 match))
+
+                      (for-each (match-lambda
+                                  ((variable value)
+                                   (setenv variable value)))
+                                '#$variables)
+
+                      (apply execl (string-append #$service "/" #$program)
+                             (string-append #$service "/" #$program)
+                             (cdr (command-line))))))
+
+  (define build
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils))
+
+          (define service-directory
+            "/share/dbus-1/system-services")
+
+          (mkdir-p (dirname (string-append #$output
+                                           service-directory)))
+          (copy-recursively (string-append #$service
+                                           service-directory)
+                            (string-append #$output
+                                           service-directory))
+          (symlink (string-append #$service "/etc") ;for etc/dbus-1
+                   (string-append #$output "/etc"))
+
+          (for-each (lambda (file)
+                      (substitute* file
+                        (("Exec[[:blank:]]*=[[:blank:]]*([[:graph:]]+)(.*)$"
+                          _ original-program arguments)
+                         (string-append "Exec=" #$wrapper arguments
+                                        "\n"))))
+                    (find-files #$output "\\.service$")))))
+
+  (computed-file (string-append (package-name service) "-wrapper")
+                 build))
+
 \f
 ;;;
 ;;; Polkit privilege management service.
@@ -297,7 +361,9 @@ and policy files.  For example, to allow avahi-daemon to use the system bus,
                            (inherit config)
                            (actions
                             (append (polkit-configuration-actions config)
-                                    actions)))))))
+                                    actions)))))
+
+                (default-value (polkit-configuration))))
 
 (define* (polkit-service #:key (polkit polkit))
   "Return a service that runs the