Toggle diff (192 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 30cc3b6d45..d5b9de0de2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -32192,15 +32192,30 @@ The location of the file that stores current MPD's state.
@item @code{sticker-file} (default: @code{"~/.mpd/sticker.sql"})
The location of the sticker database.
-@item @code{port} (default: @code{"6600"})
-The port to run mpd on.
+@item @code{endpoints} (default: @code{(list (mpd-endpoint))})
+The endpoints to bind MPD to. This can be an mpd-endpoint (see below)
+or a list of shepherd endpoints. If using shepherd endpoints, MPD
+will be spawned as a systemd-style service rather than as a
+forkexec-style one. This delays the start of MPD until the first client
+connects.
+
+@item @code{outputs} (default: @code{"(list (mpd-output))"})
+The audio outputs that MPD can use. By default this is a single output using pulseaudio.
+
+@end table
+@end deftp
+
+@deftp {Data Type} mpd-endpoint
+Data type representing the configuration of @command{mpd}.
+
+@table @asis
@item @code{address} (default: @code{"any"})
The address that mpd will bind to. To use a Unix domain socket,
an absolute path can be specified here.
-@item @code{outputs} (default: @code{"(list (mpd-output))"})
-The audio outputs that MPD can use. By default this is a single output using pulseaudio.
+@item @code{port} (default: @code{"6600"})
+The port to run mpd on.
@end table
@end deftp
diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm
index c60053f33c..6e8fd460a1 100644
--- a/gnu/services/audio.scm
+++ b/gnu/services/audio.scm
@@ -20,6 +20,8 @@
(define-module (gnu services audio)
#:use-module (guix gexp)
+ #:use-module (guix diagnostics)
+ #:use-module (guix i18n)
#:use-module (gnu services)
#:use-module (gnu services shepherd)
#:use-module (gnu system shadow)
@@ -28,8 +30,14 @@ (define-module (gnu services audio)
#:use-module (guix records)
#:use-module (ice-9 match)
#:use-module (ice-9 format)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-35)
#:export (mpd-output
mpd-output?
+ mpd-endpoint
+ mpd-endpoint?
mpd-configuration
mpd-configuration?
mpd-service-type))
@@ -59,6 +67,30 @@ (define-record-type* <mpd-output>
(extra-options mpd-output-extra-options
(default '())))
+(define-record-type* <mpd-endpoint>
+ mpd-endpoint make-mpd-endpoint
+ mpd-endpoint?
+ (address mpd-endpoint-address (default "any"))
+ (port mpd-endpoint-port (default "6600")))
+
+(define-with-syntax-properties (sanitize-mpd-endpoints (endpoints properties))
+ (match endpoints
+ ((? mpd-endpoint? endpoint) (list endpoint))
+ (((? mpd-endpoint?)) endpoints)
+ (((? mpd-endpoint?) . _)
+ (raise (make-compound-condition
+ (condition (&message
+ (message
+ (G_ "\
+<mpd-endpoint> is mutually exclusive with other endpoints."))))
+ (condition (&error-location
+ (location (source-properties->location properties))))
+ (condition (&fix-hint
+ (hint "\
+Make sure you only need one endpoint or use shepherd endpoints instead."))))))
+ (((? shepherd-endpoint?) . (? (cute every shepherd-endpoint? <>)))
+ endpoints)))
+
(define-record-type* <mpd-configuration>
mpd-configuration make-mpd-configuration
mpd-configuration?
@@ -74,10 +106,9 @@ (define-record-type* <mpd-configuration>
(default "~/.mpd/state"))
(sticker-file mpd-configuration-sticker-file
(default "~/.mpd/sticker.sql"))
- (port mpd-configuration-port
- (default "6600"))
- (address mpd-configuration-address
- (default "any"))
+ (endpoints mpd-configuration-endpoints ; list of <shepherd-endpoint>
+ (default (list (mpd-endpoint))) ; | <mpd-endpoint>
+ (sanitize sanitize-mpd-endpoints))
(outputs mpd-configuration-outputs
(default (list (mpd-output)))))
@@ -124,9 +155,12 @@ (define (mpd-config->file config)
("playlist_directory" ,mpd-configuration-playlist-dir)
("db_file" ,mpd-configuration-db-file)
("state_file" ,mpd-configuration-state-file)
- ("sticker_file" ,mpd-configuration-sticker-file)
- ("port" ,mpd-configuration-port)
- ("bind_to_address" ,mpd-configuration-address))))))
+ ("sticker_file" ,mpd-configuration-sticker-file)))
+ (match (mpd-configuration-endpoints config)
+ (($ <mpd-endpoint> address port)
+ `(("bind_to_address" ,address)
+ ("port" ,port)))
+ (_ '())))))
(define (mpd-file-name config file)
"Return a path in /var/run/mpd/ that is writable
@@ -135,24 +169,48 @@ (define (mpd-file-name config file)
(mpd-configuration-user config)
"/" file))
+(define (mpd-configuration-shepherd-endpoints config)
+ "Return @code{(mpd-configuration-endpoints config)}"
+ (let ((endpoints (mpd-configuration-endpoints config)))
+ (match endpoints
+ (((? shepherd-endpoint?) . _) endpoints)
+ (_ #f))))
+
(define (mpd-shepherd-service config)
(shepherd-service
(documentation "Run the MPD (Music Player Daemon)")
(requirement '(user-processes))
(provision '(mpd))
- (start #~(make-forkexec-constructor
- (list #$(file-append mpd "/bin/mpd")
- "--no-daemon"
- #$(mpd-config->file config))
- #:environment-variables
- ;; Required to detect PulseAudio when run under a user account.
- (list (string-append
- "XDG_RUNTIME_DIR=/run/user/"
- (number->string
- (passwd:uid
- (getpwnam #$(mpd-configuration-user config))))))
- #:log-file #$(mpd-file-name config "log")))
- (stop #~(make-kill-destructor))))
+ (start (if (mpd-configuration-shepherd-endpoints config)
+ #~(make-systemd-constructor
+ (list #$(file-append mpd "/bin/mpd")
+ "--systemd"
+ #$(mpd-config->file config))
+ (list #$@(map shepherd-endpoint->sexp
+ (mpd-configuration-shepherd-endpoints config)))
+ #:environment-variables
+ ;; Required to detect PulseAudio when run under a user account.
+ (list (string-append
+ "XDG_RUNTIME_DIR=/run/user/"
+ (number->string
+ (passwd:uid
+ (getpwnam #$(mpd-configuration-user config))))))
+ #:log-file #$(mpd-file-name config "log"))
+ #~(make-forkexec-constructor
+ (list #$(file-append mpd "/bin/mpd")
+ "--no-daemon"
+ #$(mpd-config->file config))
+ #:environment-variables
+ ;; Required to detect PulseAudio when run under a user account.
+ (list (string-append
+ "XDG_RUNTIME_DIR=/run/user/"
+ (number->string
+ (passwd:uid
+ (getpwnam #$(mpd-configuration-user config))))))
+ #:log-file #$(mpd-file-name config "log"))))
+ (stop (if (mpd-configuration-shepherd-endpoints config)
+ #~(make-systemd-destructor)
+ #~(make-kill-destructor)))))
(define (mpd-service-activation config)
(with-imported-modules '((guix build utils))
--
2.37.3