services: mpd: Use proper records for user and group fields.

Deprecate using strings for these fields and prefer user-account
(resp. user-group) instead to avoid duplication within account-service-type.

Fixes #61570 <https://issues.guix.gnu.org/61570>.

* gnu/services/audio.scm (%mpd-user, %mpd-group)
(mpd-serialize-user-account, mpd-serialize-user-group)
(mpd-user-sanitizer, mpd-group-sanitizer): New variables.
(mpd-configuration)[user]: Use user-account as value type.
Sanitize via mpd-user-sanitizer.
[group]: Use user-group as value type.
Sanitize via mpd-group-sanitizer.
(mpd-shepherd-service): Adjust accordingly.
(mpd-accounts): Likewise.
* doc/guix.texi (Audio Services)[Music Player Daemon]: Likewise.

Signed-off-by: Liliana Marie Prikler <liliana.prikler@gmail.com>
This commit is contained in:
Bruno Victal 2023-03-26 19:41:32 +01:00 committed by Liliana Marie Prikler
parent 2c4df1a41a
commit 7fdadeac11
No known key found for this signature in database
GPG Key ID: 442A84B8C70E2F87
2 changed files with 86 additions and 30 deletions

View File

@ -6211,7 +6211,7 @@ Transformation Options}) so it should be lossless.
@item --profile=@var{profile} @item --profile=@var{profile}
@itemx -p @var{profile} @itemx -p @var{profile}
Create an environment containing the packages installed in @var{profile}. Create an environment containing the packages installed in @var{profile}.
Use @command{guix package} (@pxref{Invoking guix package}) to create Use @command{guix package} (@pxref{Invoking guix package}) to create
and manage profiles. and manage profiles.
@ -6657,7 +6657,7 @@ interpreted as packages that will be added to the environment directly.
@item --profile=@var{profile} @item --profile=@var{profile}
@itemx -p @var{profile} @itemx -p @var{profile}
Create an environment containing the packages installed in @var{profile}. Create an environment containing the packages installed in @var{profile}.
Use @command{guix package} (@pxref{Invoking guix package}) to create Use @command{guix package} (@pxref{Invoking guix package}) to create
and manage profiles. and manage profiles.
@ -12667,7 +12667,7 @@ candidates, and even to test their impact on packages that depend on
them: them:
@example @example
guix build elogind --with-source=@dots{}/shepherd-0.9.0rc1.tar.gz guix build elogind --with-source=@dots{}/shepherd-0.9.0rc1.tar.gz
@end example @end example
@dots{} or to build from a checkout in a pristine environment: @dots{} or to build from a checkout in a pristine environment:
@ -23783,7 +23783,7 @@ created for.
Restricts all controllers to the specified transport. @code{'dual} means both Restricts all controllers to the specified transport. @code{'dual} means both
BR/EDR and LE are enabled (if supported by the hardware). BR/EDR and LE are enabled (if supported by the hardware).
Possible values are: Possible values are:
@itemize @bullet @itemize @bullet
@item @item
@ -33494,14 +33494,17 @@ Data type representing the configuration of @command{mpd}.
@item @code{package} (default: @code{mpd}) (type: file-like) @item @code{package} (default: @code{mpd}) (type: file-like)
The MPD package. The MPD package.
@item @code{user} (default: @code{"mpd"}) (type: string) @item @code{user} (default: @code{%mpd-user}) (type: user-account)
The user to run mpd as. The user to run mpd as.
@item @code{group} (default: @code{"mpd"}) (type: string) The default @code{%mpd-user} is a system user with the name ``mpd'',
who is a part of the group @var{group} (see below).
@item @code{group} (default: @code{%mpd-group}) (type: user-group)
The group to run mpd as. The group to run mpd as.
The default @code{%mpd-group} is a system group with name ``mpd''.
@item @code{shepherd-requirement} (default: @code{()}) (type: list-of-symbol) @item @code{shepherd-requirement} (default: @code{()}) (type: list-of-symbol)
This is a list of symbols naming Shepherd services that this service A list of symbols naming Shepherd services that this service
will depend on. will depend on.
@item @code{environment-variables} (default: @code{("PULSE_CLIENTCONFIG=/etc/pulse/client.conf" "PULSE_CONFIG=/etc/pulse/daemon.conf")}) (type: list-of-strings) @item @code{environment-variables} (default: @code{("PULSE_CLIENTCONFIG=/etc/pulse/client.conf" "PULSE_CONFIG=/etc/pulse/daemon.conf")}) (type: list-of-strings)
@ -41215,7 +41218,7 @@ A clause can have one of the following forms:
(@var{field-name} (@var{field-name}
(@var{type} @var{default-value}) (@var{type} @var{default-value})
@var{documentation}) @var{documentation})
(@var{field-name} (@var{field-name}
(@var{type} @var{default-value}) (@var{type} @var{default-value})
@var{documentation} @var{documentation}
@ -41289,7 +41292,7 @@ A simple serializer procedure could look like this:
(define (serialize-boolean field-name value) (define (serialize-boolean field-name value)
(let ((value (if value "true" "false"))) (let ((value (if value "true" "false")))
#~(string-append #$field-name #$value))) #~(string-append #$field-name #$value)))
@end lisp @end lisp
In some cases multiple different configuration records might be defined In some cases multiple different configuration records might be defined
in the same file, but their serializers for the same type might have to in the same file, but their serializers for the same type might have to
@ -41307,7 +41310,7 @@ manually specify a custom @var{serializer} for every field.
(define (bar-serialize-string field-name value) (define (bar-serialize-string field-name value)
@dots{}) @dots{})
(define-configuration foo-configuration (define-configuration foo-configuration
(label (label
(string) (string)
@ -41339,7 +41342,7 @@ macro which is a shorthand of this.
(field (field
(string "test") (string "test")
"Some documentation.")) "Some documentation."))
@end lisp @end lisp
@end defmac @end defmac
@defmac define-maybe type @defmac define-maybe type
@ -44145,7 +44148,7 @@ down in its dependency graph. As it turns out, GLib does not have a
from /gnu/store/@dots{}-glib-2.62.6/lib/libglib-2.0.so.0 from /gnu/store/@dots{}-glib-2.62.6/lib/libglib-2.0.so.0
#1 0x00007ffff608a7d6 in gobject_init_ctor () #1 0x00007ffff608a7d6 in gobject_init_ctor ()
from /gnu/store/@dots{}-glib-2.62.6/lib/libgobject-2.0.so.0 from /gnu/store/@dots{}-glib-2.62.6/lib/libgobject-2.0.so.0
#2 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=1, argv=argv@@entry=0x7fffffffcfd8, #2 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=1, argv=argv@@entry=0x7fffffffcfd8,
env=env@@entry=0x7fffffffcfe8) at dl-init.c:72 env=env@@entry=0x7fffffffcfe8) at dl-init.c:72
#3 0x00007ffff7fe2866 in call_init (env=0x7fffffffcfe8, argv=0x7fffffffcfd8, argc=1, l=<optimized out>) #3 0x00007ffff7fe2866 in call_init (env=0x7fffffffcfe8, argv=0x7fffffffcfd8, argc=1, l=<optimized out>)
at dl-init.c:118 at dl-init.c:118
@ -44174,7 +44177,7 @@ Starting program: /gnu/store/@dots{}-profile/bin/sh -c exec\ inkscape
#0 g_getenv (variable=variable@@entry=0x7ffff60c7a2e "GOBJECT_DEBUG") at ../glib-2.62.6/glib/genviron.c:252 #0 g_getenv (variable=variable@@entry=0x7ffff60c7a2e "GOBJECT_DEBUG") at ../glib-2.62.6/glib/genviron.c:252
#1 0x00007ffff608a7d6 in gobject_init () at ../glib-2.62.6/gobject/gtype.c:4380 #1 0x00007ffff608a7d6 in gobject_init () at ../glib-2.62.6/gobject/gtype.c:4380
#2 gobject_init_ctor () at ../glib-2.62.6/gobject/gtype.c:4493 #2 gobject_init_ctor () at ../glib-2.62.6/gobject/gtype.c:4493
#3 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=3, argv=argv@@entry=0x7fffffffd088, #3 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=3, argv=argv@@entry=0x7fffffffd088,
env=env@@entry=0x7fffffffd0a8) at dl-init.c:72 env=env@@entry=0x7fffffffd0a8) at dl-init.c:72
@dots{} @dots{}
@end example @end example

View File

@ -140,6 +140,14 @@
(define list-of-symbol? (define list-of-symbol?
(list-of symbol?)) (list-of symbol?))
;; Helpers for deprecated field types, to be removed later.
(define %lazy-group (make-symbol "%lazy-group"))
(define (%set-user-group user group)
(user-account
(inherit user)
(group (user-group-name group))))
;;; ;;;
;;; MPD ;;; MPD
@ -164,10 +172,31 @@
(define (mpd-serialize-list-of-strings field-name value) (define (mpd-serialize-list-of-strings field-name value)
#~(string-append #$@(map (cut mpd-serialize-string field-name <>) value))) #~(string-append #$@(map (cut mpd-serialize-string field-name <>) value)))
(define (mpd-serialize-user-account field-name value)
(mpd-serialize-string field-name (user-account-name value)))
(define (mpd-serialize-user-group field-name value)
(mpd-serialize-string field-name (user-group-name value)))
(define-maybe string (prefix mpd-)) (define-maybe string (prefix mpd-))
(define-maybe list-of-strings (prefix mpd-)) (define-maybe list-of-strings (prefix mpd-))
(define-maybe boolean (prefix mpd-)) (define-maybe boolean (prefix mpd-))
(define %mpd-user
(user-account
(name "mpd")
(group %lazy-group)
(system? #t)
(comment "Music Player Daemon (MPD) user")
;; MPD can use $HOME (or $XDG_CONFIG_HOME) to place its data
(home-directory "/var/lib/mpd")
(shell (file-append shadow "/sbin/nologin"))))
(define %mpd-group
(user-group
(name "mpd")
(system? #t)))
;;; TODO: Procedures for deprecated fields, to be removed. ;;; TODO: Procedures for deprecated fields, to be removed.
(define mpd-deprecated-fields '((music-dir . music-directory) (define mpd-deprecated-fields '((music-dir . music-directory)
@ -197,6 +226,33 @@
(define-maybe port (prefix mpd-)) (define-maybe port (prefix mpd-))
;;; Procedures for unsupported value types, to be removed.
(define (mpd-user-sanitizer value)
(cond ((user-account? value) value)
((string? value)
(warning (G_ "string value for 'user' is deprecated, use \
user-account instead~%"))
(user-account
(inherit %mpd-user)
(name value)
;; XXX: This is to be lazily substituted in (…-accounts)
;; with the value from 'group'.
(group %lazy-group)))
(else
(configuration-field-error #f 'user value))))
(define (mpd-group-sanitizer value)
(cond ((user-group? value) value)
((string? value)
(warning (G_ "string value for 'group' is deprecated, use \
user-group instead~%"))
(user-group
(inherit %mpd-group)
(name value)))
(else
(configuration-field-error #f 'group value))))
;;; ;;;
;; Generic MPD plugin record, lists only the most prevalent fields. ;; Generic MPD plugin record, lists only the most prevalent fields.
@ -347,12 +403,14 @@ to be appended to the audio output configuration.")
empty-serializer) empty-serializer)
(user (user
(string "mpd") (user-account %mpd-user)
"The user to run mpd as.") "The user to run mpd as."
(sanitizer mpd-user-sanitizer))
(group (group
(string "mpd") (user-group %mpd-group)
"The group to run mpd as.") "The group to run mpd as."
(sanitizer mpd-group-sanitizer))
(shepherd-requirement (shepherd-requirement
(list-of-symbol '()) (list-of-symbol '())
@ -517,7 +575,8 @@ appended to the configuration.")
log-file playlist-directory log-file playlist-directory
db-file state-file sticker-file db-file state-file sticker-file
environment-variables) environment-variables)
(let* ((config-file (mpd-serialize-configuration config))) (let ((config-file (mpd-serialize-configuration config))
(username (user-account-name user)))
(shepherd-service (shepherd-service
(documentation "Run the MPD (Music Player Daemon)") (documentation "Run the MPD (Music Player Daemon)")
(requirement `(user-processes loopback ,@shepherd-requirement)) (requirement `(user-processes loopback ,@shepherd-requirement))
@ -526,7 +585,7 @@ appended to the configuration.")
(and=> #$(maybe-value log-file) (and=> #$(maybe-value log-file)
(compose mkdir-p dirname)) (compose mkdir-p dirname))
(let ((user (getpw #$user))) (let ((user (getpw #$username)))
(for-each (for-each
(lambda (x) (lambda (x)
(when (and x (not (file-exists? x))) (when (and x (not (file-exists? x)))
@ -560,17 +619,11 @@ appended to the configuration.")
(define (mpd-accounts config) (define (mpd-accounts config)
(match-record config <mpd-configuration> (user group) (match-record config <mpd-configuration> (user group)
(list (user-group ;; TODO: Deprecation code, to be removed.
(name group) (let ((user (if (eq? (user-account-group user) %lazy-group)
(system? #t)) (%set-user-group user group)
(user-account user)))
(name user) (list user group))))
(group group)
(system? #t)
(comment "Music Player Daemon (MPD) user")
;; MPD can use $HOME (or $XDG_CONFIG_HOME) to place its data
(home-directory "/var/lib/mpd")
(shell (file-append shadow "/sbin/nologin"))))))
(define mpd-service-type (define mpd-service-type
(service-type (service-type