From 9137df26bbdfef6a777d702291508edf8c213af1 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Wed, 21 Dec 2022 13:31:44 +0000 Subject: doc: Clarify special-files-service-type expected value. * doc/guix.texi (Services, Base Services): Clarify special-files-service-type expected value. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index fa9ea5a6ec..fa1f46c2b1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -17975,7 +17975,7 @@ This is the service that sets up ``special files'' such as @file{/bin/sh}; an instance of it is part of @code{%base-services}. The value associated with @code{special-files-service-type} services -must be a list of tuples where the first element is the ``special file'' +must be a list of two-element lists where the first element is the ``special file'' and the second element is its target. By default it is: @cindex @file{/bin/sh} -- cgit v1.2.3 From 6f4fd8f5b87d9f55013c91ecc3b92fc43269599e Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Mon, 13 Mar 2023 19:30:48 +0000 Subject: services: mcron: Restyle mcron-configuration. * doc/guix.texi (Scheduled Job Execution): Sync doc with source. * gnu/services/mcron.scm (mcron-configuration): Restyle. [log-format]: Fix incorrectly formatted text. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 2 +- gnu/services/mcron.scm | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index fa1f46c2b1..119ff8499b 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -19365,7 +19365,7 @@ Log messages to standard output. @item @code{log-format} (default: @code{"~1@@*~a ~a: ~a~%"}) (type: string) @code{(ice-9 format)} format string for log messages. The default value -produces messages like "@samp{@var{pid} @var{name}: @var{message}"} +produces messages like @samp{@var{pid} @var{name}: @var{message}} (@pxref{Invoking mcron, Invoking,, mcron,GNU@tie{}mcron}). Each message is also prefixed by a timestamp by GNU Shepherd. diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm index 52332d6123..6ee333f253 100644 --- a/gnu/services/mcron.scm +++ b/gnu/services/mcron.scm @@ -56,18 +56,25 @@ (define list-of-gexps? (list-of gexp?)) (define-configuration/no-serialization mcron-configuration - (mcron (file-like mcron) "The mcron package to use.") + (mcron + (file-like mcron) + "The mcron package to use.") + (jobs (list-of-gexps '()) "This is a list of gexps (@pxref{G-Expressions}), where each gexp corresponds to an mcron job specification (@pxref{Syntax, mcron job specifications,, mcron, GNU@tie{}mcron}).") - (log? (boolean #t) "Log messages to standard output.") + + (log? + (boolean #t) + "Log messages to standard output.") + (log-format (string "~1@*~a ~a: ~a~%") "@code{(ice-9 format)} format string for log messages. The default value -produces messages like \"@samp{@var{pid} @var{name}: -@var{message}\"} (@pxref{Invoking mcron, Invoking,, mcron, GNU@tie{}mcron}). +produces messages like @samp{@var{pid} @var{name}: @var{message}} +(@pxref{Invoking mcron, Invoking,, mcron, GNU@tie{}mcron}). Each message is also prefixed by a timestamp by GNU Shepherd.")) (define (job-files mcron jobs) -- cgit v1.2.3 From c88582a6740777b5f15690990b04cdd153905042 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Mon, 13 Mar 2023 19:30:50 +0000 Subject: services: mcron: Add log-file and date-format fields. * doc/guix.texi (Scheduled Job Execution): Document it. * gnu/services/mcron.scm (mcron-configuration)[log-file, date-format]: New field. (mcron-shepherd-services): Add log-file and date-format support. Use file-append instead of string-append. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 6 ++++++ gnu/services/mcron.scm | 34 ++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 119ff8499b..77ee2c6e30 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -19363,12 +19363,18 @@ specifications,, mcron,GNU@tie{}mcron}). @item @code{log?} (default: @code{#t}) (type: boolean) Log messages to standard output. +@item @code{log-file} (default: @code{"/var/log/mcron.log"}) (type: string) +Log file location. + @item @code{log-format} (default: @code{"~1@@*~a ~a: ~a~%"}) (type: string) @code{(ice-9 format)} format string for log messages. The default value produces messages like @samp{@var{pid} @var{name}: @var{message}} (@pxref{Invoking mcron, Invoking,, mcron,GNU@tie{}mcron}). Each message is also prefixed by a timestamp by GNU Shepherd. +@item @code{date-format} (type: maybe-string) +@code{(srfi srfi-19)} format string for date. + @end table @end deftp @c %end of fragment diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm index 9f3afecf62..2ef5980e09 100644 --- a/gnu/services/mcron.scm +++ b/gnu/services/mcron.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2017, 2018, 2019, 2020 Ludovic Courtès ;;; Copyright © 2022 Maxim Cournoyer +;;; Copyright © 2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -33,7 +34,9 @@ (define-module (gnu services mcron) mcron-configuration-mcron mcron-configuration-jobs mcron-configuration-log? + mcron-configuration-log-file mcron-configuration-log-format + mcron-configuration-date-format mcron-service-type)) @@ -55,6 +58,8 @@ (define-module (gnu services mcron) (define list-of-gexps? (list-of gexp?)) +(define-maybe/no-serialization string) + (define-configuration/no-serialization mcron-configuration (mcron (file-like mcron) @@ -70,12 +75,20 @@ (define-configuration/no-serialization mcron-configuration (boolean #t) "Log messages to standard output.") + (log-file + (string "/var/log/mcron.log") + "Log file location.") + (log-format (string "~1@*~a ~a: ~a~%") "@code{(ice-9 format)} format string for log messages. The default value produces messages like @samp{@var{pid} @var{name}: @var{message}} (@pxref{Invoking mcron, Invoking,, mcron, GNU@tie{}mcron}). -Each message is also prefixed by a timestamp by GNU Shepherd.")) +Each message is also prefixed by a timestamp by GNU Shepherd.") + + (date-format + maybe-string + "@code{(srfi srfi-19)} format string for date.")) (define (job-files mcron jobs) "Return a list of file-like object for JOBS, a list of gexps." @@ -144,24 +157,29 @@ (define (shepherd-schedule-action mcron files) (loop))))))))) (define (mcron-shepherd-services config) - (match-record config (mcron jobs log? log-format) + (match-record config + (mcron jobs log? log-file log-format date-format) (if (eq? jobs '()) - '() ; nothing to do + '() ;nothing to do (let ((files (job-files mcron jobs))) (list (shepherd-service (provision '(mcron)) (requirement '(user-processes)) (modules `((srfi srfi-1) (srfi srfi-26) - (ice-9 popen) ;for the 'schedule' action + (ice-9 popen) ;for the 'schedule' action (ice-9 rdelim) (ice-9 match) ,@%default-modules)) (start #~(make-forkexec-constructor - (list (string-append #$mcron "/bin/mcron") + (list #$(file-append mcron "/bin/mcron") #$@(if log? - #~("--log" "--log-format" #$log-format) - #~()) + `("--log" "--log-format" ,log-format + ,@(if (maybe-value-set? date-format) + (list "--date-format" + date-format) + '())) + '()) #$@files) ;; Disable auto-compilation of the job files and @@ -172,7 +190,7 @@ (define (mcron-shepherd-services config) (remove (cut string-prefix? "PATH=" <>) (environ))) - #:log-file "/var/log/mcron.log")) + #:log-file #$log-file)) (stop #~(make-kill-destructor)) (actions (list (shepherd-schedule-action mcron files))))))))) -- cgit v1.2.3 From 4e9f914680988a23e369c16616c31a4dbd8da3e4 Mon Sep 17 00:00:00 2001 From: jgart Date: Wed, 4 Jan 2023 19:10:32 -0600 Subject: scripts: refresh: Add -T option. * doc/guix.texi (Invoking guix refresh): Document the -T option. * guix/scripts/refresh.scm (%options): Add the -T flag. Signed-off-by: Maxim Cournoyer Modified-by: Maxim Cournoyer --- doc/guix.texi | 1 + guix/scripts/refresh.scm | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 77ee2c6e30..330d83d9ab 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14324,6 +14324,7 @@ for compatibility with an upgraded @code{flex} package. @table @code @item --list-transitive +@itemx --T List all the packages which one or more packages depend upon. @example diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm index ee94ed29a1..bc6c24967a 100644 --- a/guix/scripts/refresh.scm +++ b/guix/scripts/refresh.scm @@ -98,7 +98,7 @@ (define %options (option '(#\r "recursive") #f #f (lambda (opt name arg result) (alist-cons 'recursive? #t result))) - (option '("list-transitive") #f #f + (option '(#\T "list-transitive") #f #f (lambda (opt name arg result) (alist-cons 'list-transitive? #t result))) @@ -156,7 +156,7 @@ (define (show-help) (display (G_ " -r, --recursive check the PACKAGE and its inputs for upgrades")) (display (G_ " - --list-transitive list all the packages that PACKAGE depends on")) + -T, --list-transitive list all the packages that PACKAGE depends on")) (newline) (display (G_ " --keyring=FILE use FILE as the keyring of upstream OpenPGP keys")) -- cgit v1.2.3 From 306bd7b8b952b1e721fd36a9d69b3373862e8087 Mon Sep 17 00:00:00 2001 From: Karl Hallsby Date: Sun, 8 Jan 2023 13:37:55 -0600 Subject: doc: Document how to use specific package outputs in code. * doc/guix.texi (Packages with Multiple Outputs): Provide an example of selecting a package's output in Scheme. Signed-off-by: Maxim Cournoyer Modified-by: Maxim Cournoyer --- doc/guix.texi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 330d83d9ab..5a2dc2a3a3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -113,6 +113,7 @@ Copyright @copyright{} 2022⁠–⁠2023 Bruno Victal@* Copyright @copyright{} 2022 Ivan Vilata-i-Balaguer@* Copyright @copyright{} 2023 Giacomo Leidi@* Copyright @copyright{} 2022 Antero Mejr@* +Copyright @copyright{} 2023 Karl Hallsby Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -4317,6 +4318,25 @@ The command to install its documentation is: guix install glib:doc @end example +While the colon syntax works for command-line specification of package +outputs, it will not work when using a package @emph{variable} in Scheme +code. For example, to add the documentation of @code{glib} to the +globally installed packages of an @code{operating-system} (see +@ref{operating-system Reference}), a list of two items, the first one +being the package @emph{variable} and the second one the name of the +output to select (a string), must be used instead: + +@lisp +(use-modules (gnu packages glib)) +;; glib-with-documentation is the Guile symbol for the glib package +(operating-system + ... + (packages + (append + (list (list glib-with-documentation "doc")) + %base-packages))) +@end lisp + Some packages install programs with different ``dependency footprints''. For instance, the WordNet package installs both command-line tools and graphical user interfaces (GUIs). The former depend solely on the C -- cgit v1.2.3 From 72ef1bef07c00cda9b26af70e1fbb3c28b0824ad Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Wed, 22 Mar 2023 11:47:19 +0000 Subject: services: Add fstrim-service-type. * gnu/services/linux.scm (fstrim-service-type): New variable. (fstrim-mcron-job, serialize-fstrim-configuration) (fstrim-serialize-list-of-strings, fstrim-serialize-boolean): New procedure. (mcron-time?): New predicate. (fstrim-configuration): New record. * doc/guix.texi (Linux Services): Document new fstrim-service-type. Signed-off-by: Maxim Cournoyer Modified-by: Maxim Cournoyer --- doc/guix.texi | 62 ++++++++++++++++++++++++++++++ gnu/services/linux.scm | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 5a2dc2a3a3..dfdb26103a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -37485,6 +37485,68 @@ notifications. @end table @end deftp +@subsubheading fstrim Service +@cindex fstrim service +@cindex solid state drives, periodic trim +@cindex solid state drives, trim + +The command @command{fstrim} can be used to discard (or @dfn{trim}) +unused blocks on a mounted file system. + +@c This was copied from the fstrim manpage, with some Texinfo touch-ups. +@quotation Warning +Running @command{fstrim} frequently, or even using +@command{mount -o discard}, might negatively affect the lifetime of +poor-quality SSD devices. For most desktop and server systems a +sufficient trimming frequency is once a week. Note that not all devices +support a queued trim, so each trim command incurs a performance penalty +on whatever else might be trying to use the disk at the time. +@end quotation + +@defvar fstrim-service-type +Type for a service that periodically runs @command{fstrim}, whose value must +be a @code{} object. The service can be instantiated +in its default configuration with: + +@lisp +(service fstrim-service-type) +@end lisp +@end defvar + +@c %start of fragment +@deftp {Data Type} fstrim-configuration +Available @code{fstrim-configuration} fields are: + +@table @asis +@item @code{package} (default: @code{util-linux}) (type: file-like) +The package providing the @command{fstrim} command. + +@item @code{schedule} (default: @code{"0 0 * * 0"}) (type: mcron-time) +Schedule for launching @command{fstrim}. This can be a procedure, a +list or a string. For additional information, see @ref{Guile +Syntax,,Job specification,mcron,the mcron manual}. By default this is +set to run weekly on Sunday at 00:00. + +@item @code{listed-in} (default: @code{("/etc/fstab" "/proc/self/mountinfo")}) (type: maybe-list-of-strings) +List of files in fstab or kernel mountinfo format. All missing or empty +files are silently ignored. The evaluation of the list @emph{stops} +after the first non-empty file. File systems with +@code{X-fstrim.notrim} mount option in fstab are skipped. + +@item @code{verbose?} (default: @code{#t}) (type: boolean) +Verbose execution. + +@item @code{quiet-unsupported?} (default: @code{#t}) (type: boolean) +Suppress error messages if trim operation (ioctl) is unsupported. + +@item @code{extra-arguments} (type: maybe-list-of-strings) +Extra options to append to @command{fstrim} (run @samp{man fstrim} for +more information). + +@end table +@end deftp +@c %end of fragment + @cindex modprobe @cindex kernel module loader @subsubheading Kernel Module Loader Service diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm index 60e2093e1d..d085b375a2 100644 --- a/gnu/services/linux.scm +++ b/gnu/services/linux.scm @@ -5,6 +5,7 @@ ;;; Copyright © 2021 raid5atemyhomework ;;; Copyright © 2021 B. Wilson ;;; Copyright © 2022 Josselin Poiret +;;; Copyright © 2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -30,12 +31,15 @@ (define-module (gnu services linux) #:use-module (guix ui) #:use-module (gnu services) #:use-module (gnu services base) + #:use-module (gnu services configuration) + #:use-module (gnu services mcron) #:use-module (gnu services shepherd) #:use-module (gnu packages linux) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) + #:use-module (ice-9 format) #:use-module (ice-9 match) #:export (earlyoom-configuration earlyoom-configuration? @@ -50,6 +54,16 @@ (define-module (gnu services linux) earlyoom-configuration-send-notification-command earlyoom-service-type + fstrim-configuration + fstrim-configuration? + fstrim-configuration-package + fstrim-configuration-schedule + fstrim-configuration-listed-in + fstrim-configuration-verbose? + fstrim-configuration-quiet-unsupported? + fstrim-configuration-extra-arguments + fstrim-service-type + kernel-module-loader-service-type rasdaemon-configuration @@ -150,6 +164,92 @@ (define earlyoom-service-type (compose list earlyoom-shepherd-service)))) (description "Run @command{earlyoom}, the Early OOM daemon."))) + +;;; +;;; fstrim +;;; + +(define (mcron-time? x) + (or (procedure? x) (string? x) (list? x))) + +(define-maybe list-of-strings (prefix fstrim-)) + +(define (fstrim-serialize-boolean field-name value) + (list (format #f "~:[~;--~a~]" value + ;; Drop trailing '?' character. + (string-drop-right (symbol->string field-name) 1)))) + +(define (fstrim-serialize-list-of-strings field-name value) + (list (string-append "--" (symbol->string field-name)) + #~(string-join '#$value ":"))) + +(define-configuration fstrim-configuration + (package + (file-like util-linux) + "The package providing the @command{fstrim} command." + empty-serializer) + (schedule + (mcron-time "0 0 * * 0") + "Schedule for launching @command{fstrim}. This can be a procedure, a list +or a string. For additional information, see @ref{Guile Syntax,, +Job specification, mcron, the mcron manual}. By default this is set to run +weekly on Sunday at 00:00." + empty-serializer) + ;; The following are fstrim-related options. + (listed-in + (maybe-list-of-strings '("/etc/fstab" "/proc/self/mountinfo")) + ;; Note: documentation sourced from the fstrim manpage. + "List of files in fstab or kernel mountinfo format. All missing or +empty files are silently ignored. The evaluation of the list @emph{stops} +after the first non-empty file. File systems with @code{X-fstrim.notrim} mount +option in fstab are skipped.") + (verbose? + (boolean #t) + "Verbose execution.") + (quiet-unsupported? + (boolean #t) + "Suppress error messages if trim operation (ioctl) is unsupported.") + (extra-arguments + maybe-list-of-strings + "Extra options to append to @command{fstrim} (run @samp{man fstrim} for +more information)." + (lambda (_ value) + (if (maybe-value-set? value) + value '()))) + (prefix fstrim-)) + +(define (serialize-fstrim-configuration config) + (concatenate + (filter list? + (map (lambda (field) + ((configuration-field-serializer field) + (configuration-field-name field) + ((configuration-field-getter field) config))) + fstrim-configuration-fields)))) + +(define (fstrim-mcron-job config) + (match-record config (package schedule) + #~(job + ;; Note: The “if” below is to ensure that + ;; lists are ungexp'd correctly since @var{schedule} + ;; can be either a procedure, a string or a list. + #$(if (list? schedule) + `(list ,@schedule) + schedule) + (lambda () + (system* #$(file-append package "/sbin/fstrim") + #$@(serialize-fstrim-configuration config))) + "fstrim"))) + +(define fstrim-service-type + (service-type + (name 'fstrim) + (extensions + (list (service-extension mcron-service-type + (compose list fstrim-mcron-job)))) + (description "Discard unused blocks from file systems.") + (default-value (fstrim-configuration)))) + ;;; ;;; Kernel module loader. -- cgit v1.2.3 From f9ceb205f555e030a2da1ff118109b6f2a75d94a Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Thu, 23 Mar 2023 22:15:27 -0400 Subject: doc: Mention Python 2 packages should not be added anymore. * doc/contributing.texi (Python Modules): Mention Python 2 packages should not be added anymore. --- doc/contributing.texi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/contributing.texi b/doc/contributing.texi index 911c3a7bbf..e03d888bd1 100644 --- a/doc/contributing.texi +++ b/doc/contributing.texi @@ -776,9 +776,8 @@ the word @code{python}. Some modules are compatible with only one version of Python, others with both. If the package Foo is compiled with Python 3, we name it @code{python-foo}. If it is compiled with Python 2, we name it -@code{python2-foo}. Packages should be added when they are necessary; -we don't add Python 2 variants of the package unless we are going to use -them. +@code{python2-foo}. Python 2 packages are being removed from the +distribution; please do no not submit any new Python 2 packages. If a project already contains the word @code{python}, we drop this; for instance, the module python-dateutil is packaged under the names -- cgit v1.2.3 From 206446b4840279596b3b4522beaee43a3359133d Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Thu, 23 Mar 2023 15:02:13 +0000 Subject: services: audio: Remove redundant list-of-string? predicate. Use list-of-strings? predicate defined in (gnu services configuration). * gnu/services/audio.scm (list-of-string?): Remove predicate. (mpd-serialize-list-of-string): Rename procedure to ... (mpd-serialize-list-of-strings): ... this. (mpd-configuration)[environment-variables]: Switch to list-of-strings. [endpoints]: Switch to maybe-list-of-strings. (mympd-ip-acl)[allow, deny]: Switch to list-of-strings. (mympd-serialize-configuration): Rename serialize-list-of-string to serialize-list-of-strings. * doc/guix.texi (Audio Services): Update it. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 8 ++++---- gnu/services/audio.scm | 25 +++++++++++-------------- 2 files changed, 15 insertions(+), 18 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index dfdb26103a..7c2feb1dd8 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -33501,7 +33501,7 @@ The group to run mpd as. This is a list of symbols naming Shepherd services that this service will depend on. -@item @code{environment-variables} (default: @code{()}) (type: list-of-string) +@item @code{environment-variables} (default: @code{()}) (type: list-of-strings) A list of strings specifying environment variables. @item @code{log-file} (default: @code{"/var/log/mpd/log"}) (type: maybe-string) @@ -33532,7 +33532,7 @@ The location of the sticker database. @item @code{default-port} (default: @code{6600}) (type: maybe-integer) The default port to run mpd on. -@item @code{endpoints} (type: maybe-list-of-string) +@item @code{endpoints} (type: maybe-list-of-strings) The addresses that mpd will bind to. A port different from @var{default-port} may be specified, e.g. @code{localhost:6602} and IPv6 addresses must be enclosed in square brackets when a different port is used. @@ -33808,10 +33808,10 @@ Whether to preserve caches between service restarts. Available @code{mympd-ip-acl} fields are: @table @asis -@item @code{allow} (default: @code{()}) (type: list-of-string) +@item @code{allow} (default: @code{()}) (type: list-of-strings) Allowed IP addresses. -@item @code{deny} (default: @code{()}) (type: list-of-string) +@item @code{deny} (default: @code{()}) (type: list-of-strings) Disallowed IP addresses. @end table diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm index 848da651d7..73aae9dfcf 100644 --- a/gnu/services/audio.scm +++ b/gnu/services/audio.scm @@ -2,7 +2,7 @@ ;;; Copyright © 2017 Peter Mikkelsen ;;; Copyright © 2019 Ricardo Wurmus ;;; Copyright © 2020 Ludovic Courtès -;;; Copyright © 2022 Bruno Victal +;;; Copyright © 2022⁠–⁠2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -137,9 +137,6 @@ (define (uglify-field-name field-name) str) #\-) "_"))) -(define list-of-string? - (list-of string?)) - (define list-of-symbol? (list-of symbol?)) @@ -159,11 +156,11 @@ (define (mpd-serialize-alist field-name value) (define mpd-serialize-string mpd-serialize-field) (define mpd-serialize-boolean mpd-serialize-field) -(define (mpd-serialize-list-of-string field-name value) +(define (mpd-serialize-list-of-strings field-name value) #~(string-append #$@(map (cut mpd-serialize-string field-name <>) value))) (define-maybe string (prefix mpd-)) -(define-maybe list-of-string (prefix mpd-)) +(define-maybe list-of-strings (prefix mpd-)) (define-maybe boolean (prefix mpd-)) ;;; TODO: Procedures for deprecated fields, to be removed. @@ -349,7 +346,7 @@ (define-configuration mpd-configuration empty-serializer) (environment-variables - (list-of-string '()) + (list-of-strings '()) "A list of strings specifying environment variables." empty-serializer) @@ -400,7 +397,7 @@ (define-configuration mpd-configuration "The default port to run mpd on.") (endpoints - maybe-list-of-string + maybe-list-of-strings "The addresses that mpd will bind to. A port different from @var{default-port} may be specified, e.g. @code{localhost:6602} and IPv6 addresses must be enclosed in square brackets when a different @@ -409,7 +406,7 @@ (define-configuration mpd-configuration can be specified here." (lambda (_ endpoints) (if (maybe-value-set? endpoints) - (mpd-serialize-list-of-string "bind_to_address" endpoints) + (mpd-serialize-list-of-strings "bind_to_address" endpoints) ""))) (address ; TODO: deprecated, remove later @@ -581,11 +578,11 @@ (define (string-or-symbol? x) (define-configuration/no-serialization mympd-ip-acl (allow - (list-of-string '()) + (list-of-strings '()) "Allowed IP addresses.") (deny - (list-of-string '()) + (list-of-strings '()) "Disallowed IP addresses.")) (define-maybe/no-serialization integer) @@ -707,12 +704,12 @@ (define serialize-value ((? string? val) val))) (define (ip-acl-serialize-configuration config) - (define (serialize-list-of-string prefix lst) + (define (serialize-list-of-strings prefix lst) (map (cut format #f "~a~a" prefix <>) lst)) (string-join (append - (serialize-list-of-string "+" (mympd-ip-acl-allow config)) - (serialize-list-of-string "-" (mympd-ip-acl-deny config))) ",")) + (serialize-list-of-strings "+" (mympd-ip-acl-allow config)) + (serialize-list-of-strings "-" (mympd-ip-acl-deny config))) ",")) ;; myMPD configuration fields are serialized as individual files under ;; /config/. -- cgit v1.2.3 From bc30a9ee889fb1b81c43a7f94ea4c2b95a15db75 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Thu, 23 Mar 2023 15:02:16 +0000 Subject: services: mpd: Set PulseAudio-related variables. These variables are necessary for PulseAudio to work properly out-of-the-box for 'non-interactive' users. * doc/guix.texi (Audio Services): Update environment-variables field description for mpd-configuration data type. * gnu/services/audio.scm (mpd-configuration)[environment-variables]: Set PULSE_CLIENTCONFIG and PULSE_CONFIG environment variables to the system-wide PulseAudio configuration. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 2 +- gnu/services/audio.scm | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 7c2feb1dd8..3e335306f1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -33501,7 +33501,7 @@ The group to run mpd as. This is a list of symbols naming Shepherd services that this service will depend on. -@item @code{environment-variables} (default: @code{()}) (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) A list of strings specifying environment variables. @item @code{log-file} (default: @code{"/var/log/mpd/log"}) (type: maybe-string) diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm index 73aae9dfcf..4885fb8424 100644 --- a/gnu/services/audio.scm +++ b/gnu/services/audio.scm @@ -346,7 +346,8 @@ (define-configuration mpd-configuration empty-serializer) (environment-variables - (list-of-strings '()) + (list-of-strings '("PULSE_CLIENTCONFIG=/etc/pulse/client.conf" + "PULSE_CONFIG=/etc/pulse/daemon.conf")) "A list of strings specifying environment variables." empty-serializer) -- cgit v1.2.3 From 67a7eaa13dcd33c61ff0ec71b1f5e38c65f439ad Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 23 Mar 2023 15:38:10 +0100 Subject: doc: Properly document 'replace' clause of 'modify-inputs'. * doc/guix.texi (Defining Package Variants): Add 'replace' to the reference of 'modify-inputs' clauses. --- doc/guix.texi | 3 +++ 1 file changed, 3 insertions(+) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 3e335306f1..c49e51b72e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -8210,6 +8210,9 @@ Add @var{package}s to the front of the input list. @item (append @var{package}@dots{}) Add @var{package}s to the end of the input list. + +@item (replace @var{name} @var{replacement}) +Replace the package called @var{name} with @var{replacement}. @end table The example below removes the GMP and ACL inputs of Coreutils and adds -- cgit v1.2.3 From ed5053188565063b353711772fc2dc3ca50e8568 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Sat, 4 Mar 2023 21:17:38 +0000 Subject: services: base: Deprecate 'pam-limits-service' procedure. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc/guix.texi (Base Services): Replace pam-limits-service with pam-limits-service-type. * gnu/packages/benchmark.scm (python-locust)[description]: Update index anchor to manual. * gnu/services/base.scm (pam-limits-service-type): Set default value. (pam-limits-service): Deprecate procedure. Signed-off-by: Ludovic Courtès --- doc/guix.texi | 37 ++++++++++++++++++++++--------------- gnu/packages/benchmark.scm | 2 +- gnu/services/base.scm | 8 +++++--- 3 files changed, 28 insertions(+), 19 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index c49e51b72e..c5f5558e2c 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -18959,7 +18959,6 @@ will fail if @var{device} does not exist. @end table @end deftp -@anchor{pam-limits-service} @cindex session limits @cindex ulimit @cindex priority @@ -18967,22 +18966,28 @@ will fail if @var{device} does not exist. @cindex jackd @cindex nofile @cindex open file descriptors -@deffn {Scheme Procedure} pam-limits-service [#:limits @code{'()}] - -Return a service that installs a configuration file for the +@anchor{pam-limits-service-type} +@defvar pam-limits-service-type +Type of the service that installs a configuration file for the @uref{http://linux-pam.org/Linux-PAM-html/sag-pam_limits.html, -@code{pam_limits} module}. The procedure optionally takes a list of -@code{pam-limits-entry} values, which can be used to specify -@code{ulimit} limits and @code{nice} priority limits to user sessions. +@code{pam_limits} module}. The value for this service type is +a file-like object containing a list of @code{pam-limits-entry} values +which can be used to specify @code{ulimit} limits and @code{nice} +priority limits to user sessions. The following limits definition sets two hard and soft limits for all login sessions of users in the @code{realtime} group: @lisp -(pam-limits-service - (list - (pam-limits-entry "@@realtime" 'both 'rtprio 99) - (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited))) +(service + pam-limits-service-type + (plain-file + "limits.conf" + (string-join + (map pam-limits-entry->string + (list (pam-limits-entry "@@realtime" 'both 'rtprio 99) + (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited))) + "\n"))) @end lisp The first entry increases the maximum realtime priority for @@ -18994,9 +18999,11 @@ Another useful example is raising the maximum number of open file descriptors that can be used: @lisp -(pam-limits-service - (list - (pam-limits-entry "*" 'both 'nofile 100000))) +(service + pam-limits-service-type + (plain-file + "limits.conf" + (pam-limits-entry->string (pam-limits-entry "*" 'both 'nofile 100000)))) @end lisp In the above example, the asterisk means the limit should apply to any @@ -19005,7 +19012,7 @@ maximum system value visible in the @file{/proc/sys/fs/file-max} file, else the users would be prevented from login in. For more information about the Pluggable Authentication Module (PAM) limits, refer to the @samp{pam_limits} man page from the @code{linux-pam} package. -@end deffn +@end defvar @defvar greetd-service-type @uref{https://git.sr.ht/~kennylevinsen/greetd, @code{greetd}} is a minimal and diff --git a/gnu/packages/benchmark.scm b/gnu/packages/benchmark.scm index 33e2466da9..fd8513f41d 100644 --- a/gnu/packages/benchmark.scm +++ b/gnu/packages/benchmark.scm @@ -458,7 +458,7 @@ (define-public python-locust Note: Locust will complain if the available open file descriptors limit for the user is too low. To raise such limit on a Guix System, refer to -@samp{info guix --index-search=pam-limits-service}.") +@samp{info guix --index-search=pam-limits-service-type}.") (license license:expat))) (define-public interbench diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 5b0b3bb0ab..acbfb879fc 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -246,7 +246,7 @@ (define-module (gnu services base) kmscon-service-type pam-limits-service-type - pam-limits-service + pam-limits-service ; deprecated greetd-service-type greetd-configuration @@ -1616,9 +1616,11 @@ (module "pam_limits.so") (description "Install the specified resource usage limits by populating @file{/etc/security/limits.conf} and using the @code{pam_limits} -authentication module.")))) +authentication module.") + (default-value (plain-file "limits.conf" ""))))) -(define* (pam-limits-service #:optional (limits '())) +(define-deprecated (pam-limits-service #:optional (limits '())) + pam-limits-service-type "Return a service that makes selected programs respect the list of pam-limits-entry specified in LIMITS via pam_limits.so." (service pam-limits-service-type -- cgit v1.2.3 From 6d0ad930206dccf382ec65c6504df51b5c798a34 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Sat, 4 Mar 2023 21:17:39 +0000 Subject: services: pam-limits-service-type: Deprecate file-like object support in favour for lists as service value. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc/guix.texi (Base Services): Document it. * gnu/local.mk: Register test. * gnu/services/base.scm (pam-limits-service-type): Accept both lists and file-like objects. Deprecate file-like object support. * gnu/tests/pam.scm: New file. Signed-off-by: Ludovic Courtès --- doc/guix.texi | 27 ++++++-------- gnu/local.mk | 1 + gnu/services/base.scm | 36 +++++++++++++------ gnu/tests/pam.scm | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 gnu/tests/pam.scm (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index c5f5558e2c..a58ea8f9ec 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -18971,23 +18971,18 @@ will fail if @var{device} does not exist. Type of the service that installs a configuration file for the @uref{http://linux-pam.org/Linux-PAM-html/sag-pam_limits.html, @code{pam_limits} module}. The value for this service type is -a file-like object containing a list of @code{pam-limits-entry} values -which can be used to specify @code{ulimit} limits and @code{nice} -priority limits to user sessions. +a list of @code{pam-limits-entry} values, which can be used to specify +@code{ulimit} limits and @code{nice} priority limits to user sessions. +By default, the value is the empty list. The following limits definition sets two hard and soft limits for all login sessions of users in the @code{realtime} group: @lisp -(service - pam-limits-service-type - (plain-file - "limits.conf" - (string-join - (map pam-limits-entry->string - (list (pam-limits-entry "@@realtime" 'both 'rtprio 99) - (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited))) - "\n"))) +(service pam-limits-service-type + (list + (pam-limits-entry "@@realtime" 'both 'rtprio 99) + (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited))) @end lisp The first entry increases the maximum realtime priority for @@ -18999,11 +18994,9 @@ Another useful example is raising the maximum number of open file descriptors that can be used: @lisp -(service - pam-limits-service-type - (plain-file - "limits.conf" - (pam-limits-entry->string (pam-limits-entry "*" 'both 'nofile 100000)))) +(service pam-limits-service-type + (list + (pam-limits-entry "*" 'both 'nofile 100000))) @end lisp In the above example, the asterisk means the limit should apply to any diff --git a/gnu/local.mk b/gnu/local.mk index aee0b8a645..3a93ab50dd 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -782,6 +782,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests/messaging.scm \ %D%/tests/networking.scm \ %D%/tests/package-management.scm \ + %D%/tests/pam.scm \ %D%/tests/reconfigure.scm \ %D%/tests/rsync.scm \ %D%/tests/samba.scm \ diff --git a/gnu/services/base.scm b/gnu/services/base.scm index acbfb879fc..e063828d3b 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -40,7 +40,7 @@ (define-module (gnu services base) #:use-module (guix store) #:use-module (guix deprecation) - #:autoload (guix diagnostics) (warning &fix-hint) + #:autoload (guix diagnostics) (warning formatted-message &fix-hint) #:autoload (guix i18n) (G_) #:use-module (guix combinators) #:use-module (gnu services) @@ -1588,17 +1588,13 @@ (define-deprecated (syslog-service #:optional (config (syslog-configuration))) (define pam-limits-service-type - (let ((security-limits - ;; Create /etc/security containing the provided "limits.conf" file. - (lambda (limits-file) - `(("security/limits.conf" - ,limits-file)))) - (pam-extension + (let ((pam-extension (lambda (pam) (let ((pam-limits (pam-entry (control "required") (module "pam_limits.so") - (arguments '("conf=/etc/security/limits.conf"))))) + (arguments + '("conf=/etc/security/limits.conf"))))) (if (member (pam-service-name pam) '("login" "greetd" "su" "slim" "gdm-password" "sddm" "sudo" "sshd")) @@ -1606,7 +1602,27 @@ (module "pam_limits.so") (inherit pam) (session (cons pam-limits (pam-service-session pam)))) - pam))))) + pam)))) + + ;; XXX: Using file-like objects is deprecated, use lists instead. + ;; This is to be reduced into the list? case when the deprecated + ;; code gets removed. + ;; Create /etc/security containing the provided "limits.conf" file. + (security-limits + (match-lambda + ((? file-like? obj) + (warning (G_ "Using file-like value for \ +'pam-limits-service-type' is deprecated~%")) + `(("security/limits.conf" ,obj))) + ((? list? lst) + `(("security/limits.conf" + ,(plain-file "limits.conf" + (string-join (map pam-limits-entry->string lst) + "\n" 'suffix))))) + (_ (raise + (formatted-message + (G_ "invalid input for 'pam-limits-service-type'~%"))))))) + (service-type (name 'limits) (extensions @@ -1617,7 +1633,7 @@ (module "pam_limits.so") "Install the specified resource usage limits by populating @file{/etc/security/limits.conf} and using the @code{pam_limits} authentication module.") - (default-value (plain-file "limits.conf" ""))))) + (default-value '())))) (define-deprecated (pam-limits-service #:optional (limits '())) pam-limits-service-type diff --git a/gnu/tests/pam.scm b/gnu/tests/pam.scm new file mode 100644 index 0000000000..5cf13d97d7 --- /dev/null +++ b/gnu/tests/pam.scm @@ -0,0 +1,97 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Bruno Victal +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu tests pam) + #:use-module (gnu tests) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu system) + #:use-module (gnu system pam) + #:use-module (gnu system vm) + #:use-module (guix gexp) + #:use-module (ice-9 format) + #:export (%test-pam-limits + %test-pam-limits-deprecated)) + + +;;; +;;; pam-limits-service-type +;;; + +(define pam-limit-entries + (list + (pam-limits-entry "@realtime" 'both 'rtprio 99) + (pam-limits-entry "@realtime" 'both 'memlock 'unlimited))) + +(define (run-test-pam-limits config) + "Run tests in a os with pam-limits-service-type configured." + (define os + (marionette-operating-system + (simple-operating-system + (service pam-limits-service-type config)))) + + (define vm + (virtual-machine os)) + + (define name (format #f "pam-limit-service~:[~;-deprecated~]" + (file-like? config))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (gnu build marionette) + (srfi srfi-64)) + + (let ((marionette (make-marionette (list #$vm)))) + + (test-runner-current (system-test-runner #$output)) + + (test-begin #$name) + + (test-assert "/etc/security/limits.conf ready" + (wait-for-file "/etc/security/limits.conf" marionette)) + + (test-equal "/etc/security/limits.conf content matches" + #$(string-join (map pam-limits-entry->string pam-limit-entries) + "\n" 'suffix) + (marionette-eval + '(call-with-input-file "/etc/security/limits.conf" + get-string-all) + marionette)) + + (test-end))))) + + (gexp->derivation (string-append name "-test") test)) + +(define %test-pam-limits + (system-test + (name "pam-limits-service") + (description "Test that pam-limits-service can serialize its config +(as a list) to @file{limits.conf}.") + (value (run-test-pam-limits pam-limit-entries)))) + +(define %test-pam-limits-deprecated + (system-test + (name "pam-limits-service-deprecated") + (description "Test that pam-limits-service can serialize its config +(as a file-like object) to @file{limits.conf}.") + (value (run-test-pam-limits + (plain-file "limits.conf" + (string-join (map pam-limits-entry->string + pam-limit-entries) + "\n" 'suffix)))))) -- cgit v1.2.3 From 6f48efa9b89f3c33f7b2827cae88e87ec64faa09 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Sun, 26 Mar 2023 19:41:29 +0100 Subject: services: configuration: Add user-defined sanitizer support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the 'custom-serializer' field into a generic 'extra-args' field that can be extended to support new literals. Within extra-args, the literals 'sanitizer' and 'serializer' allow for user-defined sanitization and serialization procedures respectively. The 'empty-serializer' was also added as a literal to be used as before. To prevent confusion between the new “explicit” style of specifying a sanitizer, and the old “implicit” style, the latter has been deprecated, and a warning is issued if it is encountered. * gnu/services/configuration.scm (define-configuration-helper): Rename 'custom-serializer' to 'extra-args'. Add support for literals 'sanitizer', 'serializer' and 'empty-serializer'. Rename procedure 'field-sanitizer' to 'default-field-sanitizer' to avoid syntax clash. Only define default field sanitizers if user-defined ones are absent. (normalize-extra-args): New variable. ()[sanitizer]: New field. * doc/guix.texi (Complex Configurations): Document the newly added literals. * tests/services/configuration.scm: Add tests for the new literals. Signed-off-by: Liliana Marie Prikler --- doc/guix.texi | 29 ++++++- gnu/services/configuration.scm | 90 ++++++++++++++----- tests/services/configuration.scm | 183 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 276 insertions(+), 26 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index a58ea8f9ec..495a930d0d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41219,7 +41219,7 @@ A clause can have one of the following forms: (@var{field-name} (@var{type} @var{default-value}) @var{documentation} - @var{serializer}) + (serializer @var{serializer})) (@var{field-name} (@var{type}) @@ -41228,7 +41228,18 @@ A clause can have one of the following forms: (@var{field-name} (@var{type}) @var{documentation} - @var{serializer}) + (serializer @var{serializer})) + +(@var{field-name} + (@var{type}) + @var{documentation} + (sanitizer @var{sanitizer}) + +(@var{field-name} + (@var{type}) + @var{documentation} + (sanitizer @var{sanitizer}) + (serializer @var{serializer})) @end example @var{field-name} is an identifier that denotes the name of the field in @@ -41251,6 +41262,20 @@ an object of the record type. @var{documentation} is a string formatted with Texinfo syntax which should provide a description of what setting this field does. +@var{sanitizer} is a procedure which takes one argument, +a user-supplied value, and returns a ``sanitized'' value for the field. +If no sanitizer is specified, a default sanitizer is used, which raises +an error if the value is not of type @var{type}. + +An example of a sanitizer for a field that accepts both strings and +symbols looks like this: +@lisp +(define (sanitize-foo value) + (cond ((string? value) value) + ((symbol? value) (symbol->string value)) + (else (error "bad value")))) +@end lisp + @var{serializer} is the name of a procedure which takes two arguments, the first is the name of the field, and the second is the value corresponding to the field. The procedure should return a string or diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index ed9d95f906..367b85c1be 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2021, 2022 Maxim Cournoyer ;;; Copyright © 2021 Andrew Tropin ;;; Copyright © 2022 Maxime Devos +;;; Copyright © 2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -28,7 +29,8 @@ (define-module (gnu services configuration) #:use-module (guix gexp) #:use-module ((guix utils) #:select (source-properties->location)) #:use-module ((guix diagnostics) - #:select (formatted-message location-file &error-location)) + #:select (formatted-message location-file &error-location + warning)) #:use-module ((guix modules) #:select (file-name->module-name)) #:use-module (guix i18n) #:autoload (texinfo) (texi-fragment->stexi) @@ -37,6 +39,7 @@ (define-module (gnu services configuration) #:use-module (ice-9 format) #:use-module (ice-9 match) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:export (configuration-field @@ -44,6 +47,7 @@ (define-module (gnu services configuration) configuration-field-type configuration-missing-field configuration-field-error + configuration-field-sanitizer configuration-field-serializer configuration-field-getter configuration-field-default-value-thunk @@ -116,6 +120,7 @@ (define-record-type* (type configuration-field-type) (getter configuration-field-getter) (predicate configuration-field-predicate) + (sanitizer configuration-field-sanitizer) (serializer configuration-field-serializer) (default-value-thunk configuration-field-default-value-thunk) (documentation configuration-field-documentation)) @@ -181,11 +186,44 @@ (define (normalize-field-type+def s) (values #'(field-type %unset-value))))) (define (define-configuration-helper serialize? serializer-prefix syn) + + (define (normalize-extra-args s) + "Extract and normalize arguments following @var{doc}." + (let loop ((s s) + (sanitizer* %unset-value) + (serializer* %unset-value)) + (syntax-case s (sanitizer serializer empty-serializer) + (((sanitizer proc) tail ...) + (if (maybe-value-set? sanitizer*) + (syntax-violation 'sanitizer "duplicate entry" + #'proc) + (loop #'(tail ...) #'proc serializer*))) + (((serializer proc) tail ...) + (if (maybe-value-set? serializer*) + (syntax-violation 'serializer "duplicate or conflicting entry" + #'proc) + (loop #'(tail ...) sanitizer* #'proc))) + ((empty-serializer tail ...) + (if (maybe-value-set? serializer*) + (syntax-violation 'empty-serializer + "duplicate or conflicting entry" #f) + (loop #'(tail ...) sanitizer* #'empty-serializer))) + (() ; stop condition + (values (list sanitizer* serializer*))) + ((proc) ; TODO: deprecated, to be removed. + (null? (filter-map maybe-value-set? (list sanitizer* serializer*))) + (begin + (warning #f (G_ "specifying serializers after documentation is \ +deprecated, use (serializer ~a) instead~%") (syntax->datum #'proc)) + (values (list %unset-value #'proc))))))) + (syntax-case syn () - ((_ stem (field field-type+def doc custom-serializer ...) ...) + ((_ stem (field field-type+def doc extra-args ...) ...) (with-syntax ((((field-type def) ...) - (map normalize-field-type+def #'(field-type+def ...)))) + (map normalize-field-type+def #'(field-type+def ...))) + (((sanitizer* serializer*) ...) + (map normalize-extra-args #'((extra-args ...) ...)))) (with-syntax (((field-getter ...) (map (lambda (field) @@ -200,21 +238,18 @@ (define (define-configuration-helper serialize? serializer-prefix syn) ((field-type default-value) default-value)) #'((field-type def) ...))) + ((field-sanitizer ...) + (map maybe-value #'(sanitizer* ...))) ((field-serializer ...) - (map (lambda (type custom-serializer) + (map (lambda (type proc) (and serialize? - (match custom-serializer - ((serializer) - serializer) - (() - (if serializer-prefix - (id #'stem - serializer-prefix - #'serialize- type) - (id #'stem #'serialize- type)))))) + (or (maybe-value proc) + (if serializer-prefix + (id #'stem serializer-prefix #'serialize- type) + (id #'stem #'serialize- type))))) #'(field-type ...) - #'((custom-serializer ...) ...)))) - (define (field-sanitizer name pred) + #'(serializer* ...)))) + (define (default-field-sanitizer name pred) ;; Define a macro for use as a record field sanitizer, where NAME ;; is the name of the field and PRED is the predicate that tells ;; whether a value is valid for this field. @@ -235,21 +270,29 @@ (define (field-sanitizer name pred) #`(begin ;; Define field validation macros. - #,@(map field-sanitizer - #'(field ...) - #'(field-predicate ...)) + #,@(filter-map (lambda (name pred sanitizer) + (if sanitizer + #f + (default-field-sanitizer name pred))) + #'(field ...) + #'(field-predicate ...) + #'(field-sanitizer ...)) (define-record-type* #,(id #'stem #'< #'stem #'>) stem #,(id #'stem #'make- #'stem) #,(id #'stem #'stem #'?) - #,@(map (lambda (name getter def) - #`(#,name #,getter (default #,def) + #,@(map (lambda (name getter def sanitizer) + #`(#,name #,getter + (default #,def) (sanitize - #,(id #'stem #'validate- #'stem #'- name)))) + #,(or sanitizer + (id #'stem + #'validate- #'stem #'- name))))) #'(field ...) #'(field-getter ...) - #'(field-default ...)) + #'(field-default ...) + #'(field-sanitizer ...)) (%location #,(id #'stem #'stem #'-source-location) (default (and=> (current-source-location) source-properties->location)) @@ -261,6 +304,9 @@ (define #,(id #'stem #'stem #'-fields) (type 'field-type) (getter field-getter) (predicate field-predicate) + (sanitizer + (or field-sanitizer + (id #'stem #'validate- #'stem #'- #'field))) (serializer field-serializer) (default-value-thunk (lambda () diff --git a/tests/services/configuration.scm b/tests/services/configuration.scm index 4f8a74dc8a..0392cce927 100644 --- a/tests/services/configuration.scm +++ b/tests/services/configuration.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2021, 2022 Maxim Cournoyer ;;; Copyright © 2021 Xinglu Chen ;;; Copyright © 2022 Ludovic Courtès +;;; Copyright © 2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -22,6 +23,7 @@ (define-module (tests services configuration) #:use-module (gnu services configuration) #:use-module (guix diagnostics) #:use-module (guix gexp) + #:autoload (guix i18n) (G_) #:use-module (srfi srfi-34) #:use-module (srfi srfi-64)) @@ -46,14 +48,14 @@ (define-configuration port-configuration (port-configuration-port (port-configuration))) (test-equal "wrong type for a field" - '("configuration.scm" 57 11) ;error location + '("configuration.scm" 59 11) ;error location (guard (c ((configuration-error? c) (let ((loc (error-location c))) (list (basename (location-file loc)) (location-line loc) (location-column loc))))) (port-configuration - ;; This is line 56; the test relies on line/column numbers! + ;; This is line 58; the test relies on line/column numbers! (port "This is not a number!")))) (define-configuration port-configuration-cs @@ -109,6 +111,183 @@ (define-configuration configuration-with-prefix (let ((config (configuration-with-prefix))) (serialize-configuration config configuration-with-prefix-fields)))) + +;;; +;;; define-configuration macro, extra-args literals +;;; + +(define (eval-gexp x) + "Get serialized config as string." + (eval (gexp->approximate-sexp x) + (current-module))) + +(define (port? value) + (or (string? value) (number? value))) + +(define (sanitize-port value) + (cond ((number? value) value) + ((string? value) (string->number value)) + (else (raise (formatted-message (G_ "Bad value: ~a") value))))) + +(test-group "Basic sanitizer literal tests" + (define serialize-port serialize-number) + + (define-configuration config-with-sanitizer + (port + (port 80) + "Lorem Ipsum." + (sanitizer sanitize-port))) + + (test-equal "default value, sanitizer" + 80 + (config-with-sanitizer-port (config-with-sanitizer))) + + (test-equal "string value, sanitized to number" + 56 + (config-with-sanitizer-port (config-with-sanitizer + (port "56")))) + + (define (custom-serialize-port field-name value) + (number->string value)) + + (define-configuration config-serializer + (port + (port 80) + "Lorem Ipsum." + (serializer custom-serialize-port))) + + (test-equal "default value, serializer literal" + "80" + (eval-gexp + (serialize-configuration (config-serializer) + config-serializer-fields)))) + +(test-group "empty-serializer as literal/procedure tests" + (define-configuration config-with-literal + (port + (port 80) + "Lorem Ipsum." + empty-serializer)) + + (define-configuration config-with-proc + (port + (port 80) + "Lorem Ipsum." + (serializer empty-serializer))) + + (test-equal "empty-serializer as literal" + "" + (eval-gexp + (serialize-configuration (config-with-literal) + config-with-literal-fields))) + + (test-equal "empty-serializer as procedure" + "" + (eval-gexp + (serialize-configuration (config-with-proc) + config-with-proc-fields)))) + +(test-group "permutation tests" + (define-configuration config-san+empty-ser + (port + (port 80) + "Lorem Ipsum." + (sanitizer sanitize-port) + empty-serializer)) + + (define-configuration config-san+ser + (port + (port 80) + "Lorem Ipsum." + (sanitizer sanitize-port) + (serializer (lambda _ "foo")))) + + (test-equal "default value, sanitizer, permutation" + 80 + (config-san+empty-ser-port (config-san+empty-ser))) + + (test-equal "default value, serializer, permutation" + "foo" + (eval-gexp + (serialize-configuration (config-san+ser) config-san+ser-fields))) + + (test-equal "string value sanitized to number, permutation" + 56 + (config-san+ser-port (config-san+ser + (port "56")))) + + ;; Ordering tests. + (define-configuration config-ser+san + (port + (port 80) + "Lorem Ipsum." + (sanitizer sanitize-port) + (serializer (lambda _ "foo")))) + + (define-configuration config-empty-ser+san + (port + (port 80) + "Lorem Ipsum." + empty-serializer + (sanitizer sanitize-port))) + + (test-equal "default value, sanitizer, permutation 2" + 56 + (config-empty-ser+san-port (config-empty-ser+san + (port "56")))) + + (test-equal "default value, serializer, permutation 2" + "foo" + (eval-gexp + (serialize-configuration (config-ser+san) config-ser+san-fields)))) + +(test-group "duplicated/conflicting entries" + (test-error + "duplicate sanitizer" #t + (macroexpand '(define-configuration dupe-san + (foo + (list '()) + "Lorem Ipsum." + (sanitizer (lambda () #t)) + (sanitizer (lambda () #t)))))) + + (test-error + "duplicate serializer" #t + (macroexpand '(define-configuration dupe-ser + (foo + (list '()) + "Lorem Ipsum." + (serializer (lambda _ "")) + (serializer (lambda _ "")))))) + + (test-error + "conflicting use of serializer + empty-serializer" #t + (macroexpand '(define-configuration ser+empty-ser + (foo + (list '()) + "Lorem Ipsum." + (serializer (lambda _ "lorem")) + empty-serializer))))) + +(test-group "Mix of deprecated and new syntax" + (test-error + "Mix of bare serializer and new syntax" #t + (macroexpand '(define-configuration mixed + (foo + (list '()) + "Lorem Ipsum." + (sanitizer (lambda () #t)) + (lambda _ "lorem"))))) + + (test-error + "Mix of bare serializer and new syntax, permutation)" #t + (macroexpand '(define-configuration mixed + (foo + (list '()) + "Lorem Ipsum." + (lambda _ "lorem") + (sanitizer (lambda () #t))))))) + ;;; ;;; define-maybe macro. -- cgit v1.2.3 From 7fdadeac11a997583305cb867b4a8828808ae953 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Sun, 26 Mar 2023 19:41:32 +0100 Subject: 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 . * 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 --- doc/guix.texi | 29 +++++++++-------- gnu/services/audio.scm | 87 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 30 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 495a930d0d..40decb2f50 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -6211,7 +6211,7 @@ Transformation Options}) so it should be lossless. @item --profile=@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 and manage profiles. @@ -6657,7 +6657,7 @@ interpreted as packages that will be added to the environment directly. @item --profile=@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 and manage profiles. @@ -12667,7 +12667,7 @@ candidates, and even to test their impact on packages that depend on them: @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 @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 BR/EDR and LE are enabled (if supported by the hardware). -Possible values are: +Possible values are: @itemize @bullet @item @@ -33494,14 +33494,17 @@ Data type representing the configuration of @command{mpd}. @item @code{package} (default: @code{mpd}) (type: file-like) 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. -@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 default @code{%mpd-group} is a system group with name ``mpd''. @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. @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{type} @var{default-value}) @var{documentation}) - + (@var{field-name} (@var{type} @var{default-value}) @var{documentation} @@ -41289,7 +41292,7 @@ A simple serializer procedure could look like this: (define (serialize-boolean field-name value) (let ((value (if value "true" "false"))) #~(string-append #$field-name #$value))) -@end lisp +@end lisp In some cases multiple different configuration records might be defined 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) @dots{}) - + (define-configuration foo-configuration (label (string) @@ -41339,7 +41342,7 @@ macro which is a shorthand of this. (field (string "test") "Some documentation.")) -@end lisp +@end lisp @end defmac @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 #1 0x00007ffff608a7d6 in gobject_init_ctor () from /gnu/store/@dots{}-glib-2.62.6/lib/libgobject-2.0.so.0 -#2 0x00007ffff7fe275a in call_init (l=, argc=argc@@entry=1, argv=argv@@entry=0x7fffffffcfd8, +#2 0x00007ffff7fe275a in call_init (l=, argc=argc@@entry=1, argv=argv@@entry=0x7fffffffcfd8, env=env@@entry=0x7fffffffcfe8) at dl-init.c:72 #3 0x00007ffff7fe2866 in call_init (env=0x7fffffffcfe8, argv=0x7fffffffcfd8, argc=1, l=) 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 #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 -#3 0x00007ffff7fe275a in call_init (l=, argc=argc@@entry=3, argv=argv@@entry=0x7fffffffd088, +#3 0x00007ffff7fe275a in call_init (l=, argc=argc@@entry=3, argv=argv@@entry=0x7fffffffd088, env=env@@entry=0x7fffffffd0a8) at dl-init.c:72 @dots{} @end example diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm index bc4aed71dc..854efd744a 100644 --- a/gnu/services/audio.scm +++ b/gnu/services/audio.scm @@ -140,6 +140,14 @@ (define (uglify-field-name field-name) (define 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 @@ -164,10 +172,31 @@ (define mpd-serialize-boolean mpd-serialize-field) (define (mpd-serialize-list-of-strings 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 list-of-strings (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. (define mpd-deprecated-fields '((music-dir . music-directory) @@ -197,6 +226,33 @@ (define (mpd-serialize-port field-name value) (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. @@ -347,12 +403,14 @@ (define-configuration mpd-configuration empty-serializer) (user - (string "mpd") - "The user to run mpd as.") + (user-account %mpd-user) + "The user to run mpd as." + (sanitizer mpd-user-sanitizer)) (group - (string "mpd") - "The group to run mpd as.") + (user-group %mpd-group) + "The group to run mpd as." + (sanitizer mpd-group-sanitizer)) (shepherd-requirement (list-of-symbol '()) @@ -517,7 +575,8 @@ (define (mpd-shepherd-service config) log-file playlist-directory db-file state-file sticker-file environment-variables) - (let* ((config-file (mpd-serialize-configuration config))) + (let ((config-file (mpd-serialize-configuration config)) + (username (user-account-name user))) (shepherd-service (documentation "Run the MPD (Music Player Daemon)") (requirement `(user-processes loopback ,@shepherd-requirement)) @@ -526,7 +585,7 @@ (define (mpd-shepherd-service config) (and=> #$(maybe-value log-file) (compose mkdir-p dirname)) - (let ((user (getpw #$user))) + (let ((user (getpw #$username))) (for-each (lambda (x) (when (and x (not (file-exists? x))) @@ -560,17 +619,11 @@ (define (mpd-shepherd-service config) (define (mpd-accounts config) (match-record config (user group) - (list (user-group - (name group) - (system? #t)) - (user-account - (name user) - (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")))))) + ;; TODO: Deprecation code, to be removed. + (let ((user (if (eq? (user-account-group user) %lazy-group) + (%set-user-group user group) + user))) + (list user group)))) (define mpd-service-type (service-type -- cgit v1.2.3 From 380faf265b0c3b231ab8b69597d161be5e704e18 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Sun, 26 Mar 2023 19:41:33 +0100 Subject: services: mympd: Use records for user and group fields. * gnu/services/audio.scm (%mympd-user, %mympd-group) (mympd-user-sanitizer, mympd-group-sanitizer): New variables. (mympd-configuration)[user]: Use user-account as value type. Sanitize via mympd-user-sanitizer. [group]: Use user-group as value type. Sanitize via mympd-group-sanitizer. (mympd-serialize-configuration): Adjust accordingly. (mympd-accounts): Likewise. * doc/guix.texi (Audio Services)[myMPD]: Likewise. Signed-off-by: Liliana Marie Prikler --- doc/guix.texi | 7 +++-- gnu/services/audio.scm | 70 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 16 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 40decb2f50..4f72e2f34a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -33738,12 +33738,15 @@ The package object of the myMPD server. This is a list of symbols naming Shepherd services that this service will depend on. -@item @code{user} (default: @code{"mympd"}) (type: string) +@item @code{user} (default: @code{%mympd-user}) (type: user-account) Owner of the @command{mympd} process. -@item @code{group} (default: @code{"nogroup"}) (type: string) +The default @code{%mympd-user} is a system user with the name ``mympd'', +who is a part of the group @var{group} (see below). +@item @code{group} (default: @code{%mympd-group}) (type: user-group) Owner group of the @command{mympd} process. +The default @code{%mympd-group} is a system group with name ``mympd''. @item @code{work-directory} (default: @code{"/var/lib/mympd"}) (type: string) Where myMPD will store its data. diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm index 854efd744a..690409b7a1 100644 --- a/gnu/services/audio.scm +++ b/gnu/services/audio.scm @@ -658,6 +658,48 @@ (define-configuration/no-serialization mympd-ip-acl (define-maybe/no-serialization integer) (define-maybe/no-serialization mympd-ip-acl) +(define %mympd-user + (user-account + (name "mympd") + (group %lazy-group) + (system? #t) + (comment "myMPD user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin")))) + +(define %mympd-group + (user-group + (name "mympd") + (system? #t))) + +;;; TODO: Procedures for unsupported value types, to be removed. +(define (mympd-user-sanitizer value) + (cond ((user-account? value) value) + ((string? value) + (warning (G_ "string value for 'user' is not supported, use \ +user-account instead~%")) + (user-account + (inherit %mympd-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 (mympd-group-sanitizer value) + (cond ((user-group? value) value) + ((string? value) + (warning (G_ "string value for 'group' is not supported, use \ +user-group instead~%")) + (user-group + (inherit %mympd-group) + (name value))) + (else + (configuration-field-error #f 'group value)))) +;;; + + ;; XXX: The serialization procedures are insufficient since we require ;; access to multiple fields at once. ;; Fields marked with empty-serializer are never serialized and are @@ -675,13 +717,15 @@ (define-configuration/no-serialization mympd-configuration empty-serializer) (user - (string "mympd") + (user-account %mympd-user) "Owner of the @command{mympd} process." + (sanitizer mympd-user-sanitizer) empty-serializer) (group - (string "nogroup") + (user-group %mympd-group) "Owner group of the @command{mympd} process." + (sanitizer mympd-group-sanitizer) empty-serializer) (work-directory @@ -816,7 +860,8 @@ (define (mympd-shepherd-service config) (match-record config (package shepherd-requirement user work-directory cache-directory log-level log-to) - (let ((log-level* (format #f "MYMPD_LOGLEVEL=~a" log-level))) + (let ((log-level* (format #f "MYMPD_LOGLEVEL=~a" log-level)) + (username (user-account-name user))) (shepherd-service (documentation "Run the myMPD daemon.") (requirement `(loopback user-processes @@ -826,7 +871,7 @@ (define (mympd-shepherd-service config) ,@shepherd-requirement)) (provision '(mympd)) (start #~(begin - (let* ((pw (getpwnam #$user)) + (let* ((pw (getpwnam #$username)) (uid (passwd:uid pw)) (gid (passwd:gid pw))) (for-each (lambda (dir) @@ -836,8 +881,8 @@ (define (mympd-shepherd-service config) (make-forkexec-constructor `(#$(file-append package "/bin/mympd") - "--user" #$user - #$@(if (eqv? log-to 'syslog) '("--syslog") '()) + "--user" #$username + #$@(if (eq? log-to 'syslog) '("--syslog") '()) "--workdir" #$work-directory "--cachedir" #$cache-directory) #:environment-variables (list #$log-level*) @@ -846,14 +891,11 @@ (define (mympd-shepherd-service config) (define (mympd-accounts config) (match-record config (user group) - (list (user-group (name group) - (system? #t)) - (user-account (name user) - (group group) - (system? #t) - (comment "myMPD user") - (home-directory "/var/empty") - (shell (file-append shadow "/sbin/nologin")))))) + ;; TODO: Deprecation code, to be removed. + (let ((user (if (eq? (user-account-group user) %lazy-group) + (%set-user-group user group) + user))) + (list user group)))) (define (mympd-log-rotation config) (match-record config (log-to) -- cgit v1.2.3 From 52d373dfef7ddd93c67bd615e74057af90c189ac Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Fri, 17 Mar 2023 16:07:52 -0400 Subject: doc: Add a reference to a page explaining consensus decision making. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to make explicit something which until now had always been implicit. * doc/contributing.texi (Commit Access): Mention that committers are expected to employ consensus decision making. Co-authored-by: Ludovic Courtès --- doc/contributing.texi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/contributing.texi b/doc/contributing.texi index e03d888bd1..73d1cd2648 100644 --- a/doc/contributing.texi +++ b/doc/contributing.texi @@ -1727,7 +1727,12 @@ project for at least 6 months. This ensures enough interactions with the contributor, which is essential for mentoring and assessing whether they are ready to become a committer. Commit access should not be thought of as a ``badge of honor'' but rather as a responsibility a -contributor is willing to take to help the project. +contributor is willing to take to help the project. It is expected from +all contributors, and even more so from committers, to help build +consensus and make decisions based on consensus. To learn what +consensus decision making means and understand its finer details, you +are encouraged to read +@url{https://www.seedsforchange.org.uk/consensus}. The following sections explain how to get commit access, how to be ready to push commits, and the policies and community expectations for commits -- cgit v1.2.3 From 57db09aae73e3713a10c5253758d84e1046f80dc Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 23 Mar 2023 17:22:38 +0100 Subject: environment: Add '--nesting'. * guix/scripts/environment.scm (show-environment-options-help) (%options): Add '--nesting'. (options/resolve-packages): Handle it. (launch-environment/container): Add #:nesting? and honor it. [nesting-mappings]: New procedure. (guix-environment*): Add support for '--nesting'. * guix/scripts/shell.scm (profile-cached-gc-root): Special-case 'nesting?'. * tests/guix-environment-container.sh: Test it. * doc/guix.texi (Invoking guix shell): Document it. --- doc/guix.texi | 51 ++++++++++++++++++++++++++++ guix/scripts/environment.scm | 66 ++++++++++++++++++++++++++++++++++--- guix/scripts/shell.scm | 2 ++ tests/guix-environment-container.sh | 9 +++++ 4 files changed, 124 insertions(+), 4 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 4f72e2f34a..c0bd28fdae 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -6357,6 +6357,57 @@ cache (contrary to glibc in regular Guix usage) and set up the expected FHS directories: @file{/bin}, @file{/etc}, @file{/lib}, and @file{/usr} from the container's profile. +@cindex nested containers, for @command{guix shell} +@cindex container nesting, for @command{guix shell} +@item --nesting +@itemx -W +When used with @option{--container}, provide Guix @emph{inside} the +container and arrange so that it can interact with the build daemon that +runs outside the container. This is useful if you want, within your +isolated container, to create other containers, as in this sample +session: + +@example +$ guix shell -CW coreutils +[env]$ guix shell -C guile -- guile -c '(display "hello!\n")' +hello! +[env]$ exit +@end example + +The session above starts a container with @code{coreutils} programs +available in @env{PATH}. From there, we spawn @command{guix shell} to +create a @emph{nested} container that provides nothing but Guile. + +Another example is evaluating a @file{guix.scm} file that is untrusted, +as shown here: + +@example +guix shell -CW -- guix build -f guix.scm +@end example + +The @command{guix build} command as executed above can only access the +current directory. + +Under the hood, the @option{-W} option does several things: + +@itemize +@item +map the daemon's socket (by default +@file{/var/guix/daemon-socket/socket}) inside the container; +@item +map the whole store (by default @file{/gnu/store}) inside the container +such that store items made available by nested @command{guix} +invocations are visible; +@item +add the currently-used @command{guix} command to the profile in the +container, such that @command{guix describe} returns the same state +inside and outside the container; +@item +share the cache (by default @file{~/.cache/guix}) with the host, to +speed up operations such as @command{guix time-machine} and +@command{guix shell}. +@end itemize + @item --rebuild-cache @cindex caching, of profiles @cindex caching, in @command{guix shell} diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index a4939ea63c..ebfc05731c 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -31,6 +31,8 @@ (define-module (guix scripts environment) #:use-module (guix build utils) #:use-module (guix monads) #:use-module ((guix gexp) #:select (lower-object)) + #:autoload (guix describe) (current-profile current-channels) + #:autoload (guix channels) (guix-channel? channel-commit) #:use-module (guix scripts) #:use-module (guix scripts build) #:autoload (guix scripts pack) (symlink-spec-option-parser) @@ -49,9 +51,11 @@ (define-module (guix scripts environment) #:autoload (gnu packages) (specification->package+output) #:autoload (gnu packages bash) (bash) #:autoload (gnu packages bootstrap) (bootstrap-executable %bootstrap-guile) + #:autoload (gnu packages package-management) (guix) #:use-module (ice-9 match) #:autoload (ice-9 rdelim) (read-line) #:use-module (ice-9 vlist) + #:autoload (web uri) (string->uri uri-scheme) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) @@ -108,6 +112,8 @@ (define (show-environment-options-help) -P, --link-profile link environment profile to ~/.guix-profile within an isolated container")) (display (G_ " + -W, --nesting make Guix available within the container")) + (display (G_ " -u, --user=USER instead of copying the name and home of the current user into an isolated container, use the name USER with home directory /home/USER")) @@ -238,6 +244,9 @@ (define %options (option '(#\N "network") #f #f (lambda (opt name arg result) (alist-cons 'network? #t result))) + (option '(#\W "nesting") #f #f + (lambda (opt name arg result) + (alist-cons 'nesting? #t result))) (option '(#\P "link-profile") #f #f (lambda (opt name arg result) (alist-cons 'link-profile? #t result))) @@ -342,6 +351,26 @@ (define (packages->outputs packages mode) (packages->outputs (load* file module) mode))) (('manifest . file) (manifest-entries (load-manifest file))) + (('nesting? . #t) + (if (assoc-ref opts 'profile) + '() + (let ((profile (and=> (current-profile) readlink*))) + (if (or (not profile) (not (store-path? profile))) + (begin + (warning (G_ "\ +could not add current Guix to the profile~%")) + '()) + (list (manifest-entry + (name "guix") + (version + (or (any (lambda (channel) + (and (guix-channel? channel) + (channel-commit channel))) + (current-channels)) + "0")) + (item profile) + (search-paths + (package-native-search-paths guix)))))))) (_ '())) opts) manifest-entry=?))) @@ -688,7 +717,8 @@ (define* (launch-environment/fork command profile manifest (define* (launch-environment/container #:key command bash user user-mappings profile manifest link-profile? network? - map-cwd? emulate-fhs? (setup-hook #f) + map-cwd? emulate-fhs? nesting? + (setup-hook #f) (symlinks '()) (white-list '())) "Run COMMAND within a container that features the software in PROFILE. Environment variables are set according to the search paths of MANIFEST. The @@ -704,6 +734,9 @@ (define* (launch-environment/container #:key command bash user user-mappings SETUP-HOOK is an additional setup procedure to be called, currently only used with the EMULATE-FHS? option. +When NESTING? is true, share all the store with the container and add Guix to +its profile, allowing its use from within the container. + LINK-PROFILE? creates a symbolic link from ~/.guix-profile to the environment profile. @@ -731,8 +764,26 @@ (define fhs-mappings ("/libexec" . "/usr/libexec") ("/share" . "/usr/share")))) - (mlet %store-monad ((reqs (inputs->requisites - (list (direct-store-path bash) profile)))) + (define (nesting-mappings) + ;; Files shared with the host when enabling nesting. + (cons* (file-system-mapping + (source (%store-prefix)) + (target source)) + (file-system-mapping + (source (cache-directory)) + (target source) + (writable? #t)) + (let ((uri (string->uri (%daemon-socket-uri)))) + (if (or (not uri) (eq? 'file (uri-scheme uri))) + (list (file-system-mapping + (source (%daemon-socket-uri)) + (target source))) + '())))) + + (mlet %store-monad ((reqs (if nesting? + (return '()) + (inputs->requisites + (list (direct-store-path bash) profile))))) (return (let* ((cwd (getcwd)) (home (getenv "HOME")) @@ -795,11 +846,14 @@ (define fhs-mappings (filter-map optional-mapping->fs %network-file-mappings) '()) - ;; Mappings for an FHS container. (if emulate-fhs? (filter-map optional-mapping->fs fhs-mappings) '()) + (if nesting? + (filter-map optional-mapping->fs + (nesting-mappings)) + '()) (map file-system-mapping->bind-mount mappings)))) (exit/status @@ -1013,6 +1067,7 @@ (define (guix-environment* opts) (network? (assoc-ref opts 'network?)) (no-cwd? (assoc-ref opts 'no-cwd?)) (emulate-fhs? (assoc-ref opts 'emulate-fhs?)) + (nesting? (assoc-ref opts 'nesting?)) (user (assoc-ref opts 'user)) (bootstrap? (assoc-ref opts 'bootstrap?)) (system (assoc-ref opts 'system)) @@ -1059,6 +1114,8 @@ (define-syntax-rule (with-store/maybe store exp ...) (leave (G_ "--no-cwd cannot be used without '--container'~%"))) (when emulate-fhs? (leave (G_ "'--emulate-fhs' cannot be used without '--container~%'"))) + (when nesting? + (leave (G_ "'--nesting' cannot be used without '--container~%'"))) (when (pair? symlinks) (leave (G_ "'--symlink' cannot be used without '--container~%'")))) @@ -1141,6 +1198,7 @@ (define manifest #:network? network? #:map-cwd? (not no-cwd?) #:emulate-fhs? emulate-fhs? + #:nesting? nesting? #:symlinks symlinks #:setup-hook (and emulate-fhs? diff --git a/guix/scripts/shell.scm b/guix/scripts/shell.scm index 92bbfb04d0..1b42cc2af0 100644 --- a/guix/scripts/shell.scm +++ b/guix/scripts/shell.scm @@ -389,6 +389,8 @@ (define (key->file key) (if (not file) (loop rest system file (cons spec specs)) (values #f #f))) + ((('nesting? . #t) . rest) + (loop rest system file (append specs '("nested guix")))) ((('load . ('package candidate)) . rest) (if (and (not file) (null? specs)) (loop rest system candidate specs) diff --git a/tests/guix-environment-container.sh b/tests/guix-environment-container.sh index 0475405a89..a30d6b7fb2 100644 --- a/tests/guix-environment-container.sh +++ b/tests/guix-environment-container.sh @@ -264,3 +264,12 @@ guix shell --bootstrap guile-bootstrap --container \ # An invalid symlink spec causes the command to fail. ! guix shell --bootstrap -CS bin/guile=/usr/bin/guile guile-bootstrap -- exit + +# Check whether '--nesting' works. +guix build hello -d +env="$(type -P pre-inst-env)" +if guix shell -C -D guix -- "$env" guix build hello -d # cannot work +then false; else true; fi +hello_drv="$(guix build hello -d)" +hello_drv_nested="$(cd "$(dirname env)" && guix shell --bootstrap -CW -D guix -- "$env" guix build hello -d)" +test "$hello_drv" = "$hello_drv_nested" -- cgit v1.2.3 From 6420015e6d3300e7a73da9a8253428d8386954d6 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 2 Apr 2023 12:49:40 +0200 Subject: home: Add gpg-agent service. * gnu/home/services/gnupg.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (GNU Privacy Guard): New node. (Secure Shell): Link to it. --- doc/guix.texi | 93 +++++++++++++++++++++++++-- gnu/home/services/gnupg.scm | 150 ++++++++++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 240 insertions(+), 4 deletions(-) create mode 100644 gnu/home/services/gnupg.scm (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index c0bd28fdae..ed42488882 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41869,11 +41869,12 @@ services)}. * Power Management: Power Management Home Services. Services for battery power. * Shepherd: Shepherd Home Service. Managing User's Daemons. * SSH: Secure Shell. Setting up the secure shell client. +* GPG: GNU Privacy Guard. Setting up GPG and related tools. * Desktop: Desktop Home Services. Services for graphical environments. * Guix: Guix Home Services. Services for Guix. * Fonts: Fonts Home Services. Services for managing User's fonts. * Sound: Sound Home Services. Dealing with audio. -* Messaging: Messaging Home Services. Services for managing messaging. +* Messaging: Messaging Home Services. Services for managing messaging. * Media: Media Home Services. Services for managing media. @end menu @c In addition to that Home Services can provide @@ -42639,15 +42640,18 @@ The @uref{https://www.openssh.com, OpenSSH package} includes a daemon, the @command{ssh-agent} command, that manages keys to connect to remote machines using the @acronym{SSH, secure shell} protocol. With the @code{(gnu home services ssh-agent)} service, you can configure the -OpenSSH ssh-agent to run upon login. +OpenSSH ssh-agent to run upon login. @xref{GNU Privacy Guard, +@code{home-gpg-agent-service-type}}, for an alternative to OpenSSH's +@command{ssh-agent}. + Here is an example of a service and its configuration that you could add to the @code{services} field of your @code{home-environment}: @lisp (service home-ssh-agent-service-type - (home-ssh-agent-configuration - (extra-options '("-t" "1h30m")))) + (home-ssh-agent-configuration + (extra-options '("-t" "1h30m")))) @end lisp @defvar home-ssh-agent-service-type @@ -42672,6 +42676,87 @@ Extra options will be passed to @command{ssh-agent}, please run @end table @end deftp +@node GNU Privacy Guard +@subsection GNU Privacy Guard + +@cindex GNU Privacy Guard, Home service +@cindex GPG, Home service +The @code{(gnu home services gnupg)} modules provides services that help +you set up the GNU Privacy Guard, also known as GnuPG or GPG, in your +home environment. + +@cindex gpg-agent, Home service +@cindex SSH agent, with gpg-agent +The @code{gpg-agent} service configures and sets up GPG's agent, the +program that is responsible for managing OpenPGP private keys and, +optionally, OpenSSH (secure shell) private keys (@pxref{Invoking +GPG-AGENT,,, gnupg, Using the GNU Privacy Guard}). + +As an example, here is how you would configure @code{gpg-agent} with SSH +support such that it uses the Emacs-based Pinentry interface when +prompting for a passphrase: + +@lisp +(service home-gpg-agent-service-type + (home-gpg-agent-configuration + (pinentry-program + (file-append pinentry-emacs "/bin/pinentry-emacs")) + (ssh-support? #t))) +@end lisp + +The service reference is given below. + +@defvar home-gpg-agent-service-type +This is the service type for @command{gpg-agent} (@pxref{Invoking +GPG-AGENT,,, gnupg, Using the GNU Privacy Guard}). Its value must be a +@code{home-gpg-agent-configuration}, as shown below. +@end defvar + +@c %start of fragment + +@deftp {Data Type} home-gpg-agent-configuration +Available @code{home-gpg-agent-configuration} fields are: + +@table @asis +@item @code{gnupg} (default: @code{gnupg}) (type: file-like) +The GnuPG package to use. + +@item @code{pinentry-program} (type: file-like) +Pinentry program to use. Pinentry is a small user interface that +@command{gpg-agent} delegates to anytime it needs user input for a +passphrase or @acronym{PIN,personal identification number} +(@pxref{Top,,, pinentry,Using the PIN-Entry}). + +@item @code{ssh-support?} (default: @code{#f}) (type: boolean) +Whether to enable @acronym{SSH,secure shell} support. When true, +@command{gpg-agent} acts as a drop-in replacement for OpenSSH's +@command{ssh-agent} program, taking care of OpenSSH secret keys and +directing passphrase requests to the chosen Pinentry program. + +@item @code{default-cache-ttl} (default: @code{600}) (type: integer) +Time a cache entry is valid, in seconds. + +@item @code{max-cache-ttl} (default: @code{7200}) (type: integer) +Maximum time a cache entry is valid, in seconds. After this time a +cache entry will be expired even if it has been accessed recently. + +@item @code{default-cache-ttl-ssh} (default: @code{1800}) (type: integer) +Time a cache entry for SSH keys is valid, in seconds. + +@item @code{max-cache-ttl-ssh} (default: @code{7200}) (type: integer) +Maximum time a cache entry for SSH keys is valid, in seconds. + +@item @code{extra-content} (default: @code{""}) (type: raw-configuration-string) +Raw content to add to the end of @file{~/.gnupg/gpg-agent.conf}. + +@end table + +@end deftp + + +@c %end of fragment + + @node Desktop Home Services @subsection Desktop Home Services diff --git a/gnu/home/services/gnupg.scm b/gnu/home/services/gnupg.scm new file mode 100644 index 0000000000..7e9e02a3cc --- /dev/null +++ b/gnu/home/services/gnupg.scm @@ -0,0 +1,150 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Ludovic Courtès +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu home services gnupg) + #:use-module (guix gexp) + #:use-module ((guix records) #:select (match-record)) + #:use-module (gnu services) + #:use-module (gnu services configuration) + #:use-module (gnu home services) + #:use-module (gnu home services shepherd) + #:autoload (gnu packages gnupg) (gnupg pinentry) + #:export (home-gpg-agent-configuration + home-gpg-agent-configuration? + home-gpg-agent-configuration-gnupg + home-gpg-agent-configuration-pinentry-program + home-gpg-agent-configuration-ssh-support? + home-gpg-agent-configuration-default-cache-ttl + home-gpg-agent-configuration-max-cache-ttl + home-gpg-agent-configuration-max-cache-ttl-ssh + home-gpg-agent-configuration-extra-content + + home-gpg-agent-service-type)) + +(define raw-configuration-string? string?) + +;; Configuration of 'gpg-agent'. +(define-configuration/no-serialization home-gpg-agent-configuration + (gnupg + (file-like gnupg) + "The GnuPG package to use.") + (pinentry-program + (file-like (file-append pinentry "/bin/pinentry-curses")) + "Pinentry program to use. Pinentry is a small user interface that +@command{gpg-agent} delegates to anytime it needs user input for a passphrase +or @acronym{PIN, personal identification number} (@pxref{Top,,, pinentry, +Using the PIN-Entry}).") + (ssh-support? + (boolean #f) + "Whether to enable @acronym{SSH, secure shell} support. When true, +@command{gpg-agent} acts as a drop-in replacement for OpenSSH's +@command{ssh-agent} program, taking care of OpenSSH secret keys and directing +passphrase requests to the chosen Pinentry program.") + (default-cache-ttl + (integer 600) + "Time a cache entry is valid, in seconds.") + (max-cache-ttl + (integer 7200) + "Maximum time a cache entry is valid, in seconds. After this time a cache +entry will be expired even if it has been accessed recently.") + (default-cache-ttl-ssh + (integer 1800) + "Time a cache entry for SSH keys is valid, in seconds.") + (max-cache-ttl-ssh + (integer 7200) + "Maximum time a cache entry for SSH keys is valid, in seconds.") + (extra-content + (raw-configuration-string "") + "Raw content to add to the end of @file{~/.gnupg/gpg-agent.conf}.")) + +(define (home-gpg-agent-configuration-file config) + "Return the @file{gpg-agent.conf} file for @var{config}." + (match-record config + (pinentry-program default-cache-ttl max-cache-ttl + default-cache-ttl-ssh max-cache-ttl-ssh + extra-content) + (mixed-text-file "gpg-agent.conf" + "pinentry-program " pinentry-program "\n" + "default-cache-ttl " + (number->string default-cache-ttl) "\n" + "max-cache-ttl " + (number->string max-cache-ttl) "\n" + "default-cache-ttl-ssh " + (number->string default-cache-ttl-ssh) "\n" + "max-cache-ttl-ssh " + (number->string max-cache-ttl-ssh) "\n" + extra-content))) + +(define (home-gpg-agent-shepherd-services config) + "Return the possibly-empty list of Shepherd services for @var{config}." + (match-record config + (gnupg ssh-support?) + ;; 'gpg-agent' is started on demand by GnuPG's programs, but it has to be + ;; started explicitly when OpenSSH support is enabled (info "(gnupg) Agent + ;; Options"). + (if ssh-support? + (let ((endpoint (lambda (name socket) + #~(endpoint + (make-socket-address + AF_UNIX + (string-append %user-runtime-dir + "/gnupg/" #$socket)) + #:name #$name + #:socket-directory-permissions #o700)))) + (list (shepherd-service + (provision '(gpg-agent ssh-agent)) + (modules '((shepherd support))) ;for '%user-runtime-dir' + (start #~(make-systemd-constructor + (list #$(file-append gnupg "/bin/gpg-agent") + "--supervised" "--enable-ssh-support") + (list #$(endpoint "ssh" "S.gpg-agent.ssh") + #$(endpoint "browser" "S.gpg-agent.browser") + #$(endpoint "extra" "S.gpg-agent.extra") + ;; #$(endpoint "scdaemon" "S.scdaemon") + #$(endpoint "std" "S.gpg-agent")))) + (stop #~(make-systemd-destructor)) + (documentation "Start 'gpg-agent', the GnuPG passphrase +agent, with support for handling OpenSSH material.")))) + '()))) + +(define (home-gpg-agent-files config) + `((".gnupg/gpg-agent.conf" ,(home-gpg-agent-configuration-file config)))) + +(define (home-gpg-agent-environment-variables config) + "Return GnuPG environment variables needed for @var{config}." + (if (home-gpg-agent-configuration-ssh-support? config) + `(("SSH_AUTH_SOCK" + . "$XDG_RUNTIME_DIR/gnupg/S.gpg-agent.ssh")) + '())) + +(define home-gpg-agent-service-type + (service-type + (name 'home-gpg-agent) + (extensions + (list (service-extension home-files-service-type + home-gpg-agent-files) + (service-extension home-shepherd-service-type + home-gpg-agent-shepherd-services) + (service-extension home-environment-variables-service-type + home-gpg-agent-environment-variables))) + (default-value (home-gpg-agent-configuration)) + (description + "Configure GnuPG's agent, @command{gpg-agent}, which is responsible for +managing OpenPGP and optionally SSH private keys. When SSH support is +enabled, @command{gpg-agent} acts as a drop-in replacement for OpenSSH's +@command{ssh-agent}."))) diff --git a/gnu/local.mk b/gnu/local.mk index b7e19b6bc2..f0a228f19f 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -91,6 +91,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/desktop.scm \ %D%/home/services/symlink-manager.scm \ %D%/home/services/fontutils.scm \ + %D%/home/services/gnupg.scm \ %D%/home/services/guix.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ -- cgit v1.2.3 From 309d8294e93ddf46eb690e7cf4202857ad5f7f55 Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Tue, 28 Mar 2023 13:51:04 +0200 Subject: doc: Regarding SSL certs, clarify when we write about Guix System. Rationale: Even though the section 'X.509 Certificates' is part of the System Configuration chapter, readers might also come here from a cross-reference when reading about Application Setup on a foreign distro. * doc/guix.texi (System Configuration)[X.509 Certificates]: Clarify. --- doc/guix.texi | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index ed42488882..fa6c9f46a3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -60,7 +60,7 @@ Copyright @copyright{} 2018, 2021 Oleg Pykhalov@* Copyright @copyright{} 2018 Mike Gerwitz@* Copyright @copyright{} 2018 Pierre-Antoine Rouby@* Copyright @copyright{} 2018, 2019 Gábor Boskovits@* -Copyright @copyright{} 2018, 2019, 2020, 2022 Florian Pelz@* +Copyright @copyright{} 2018, 2019, 2020, 2022, 2023 Florian Pelz@* Copyright @copyright{} 2018 Laura Lazzati@* Copyright @copyright{} 2018 Alex Vong@* Copyright @copyright{} 2019 Josh Holland@* @@ -38696,11 +38696,12 @@ However, most other programs that can talk HTTPS---@command{wget}, certificates can be found. @cindex @code{nss-certs} -In Guix, this is done by adding a package that provides certificates -to the @code{packages} field of the @code{operating-system} declaration -(@pxref{operating-system Reference}). Guix includes one such package, -@code{nss-certs}, which is a set of CA certificates provided as part of -Mozilla's Network Security Services. +For users of Guix System, this is done by adding a package that +provides certificates to the @code{packages} field of the +@code{operating-system} declaration (@pxref{operating-system +Reference}). Guix includes one such package, @code{nss-certs}, which +is a set of CA certificates provided as part of Mozilla's Network +Security Services. Note that it is @emph{not} part of @code{%base-packages}, so you need to explicitly add it. The @file{/etc/ssl/certs} directory, which is where -- cgit v1.2.3 From dd10ba41847fbe0251bd3cc7ffc7bb640cca7e84 Mon Sep 17 00:00:00 2001 From: Bruno Victal Date: Mon, 3 Apr 2023 12:58:02 +0100 Subject: services: nginx: Make logging level configurable. * gnu/services/web.scm ()[log-level]: New field. (assert-valid-log-level): New procedure. (default-nginx-config): Make log-level configurable. * doc/guix.texi (Web Services): Document it. Signed-off-by: Maxim Cournoyer --- doc/guix.texi | 5 +++++ gnu/services/web.scm | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index fa6c9f46a3..acb6f0c2e1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -29889,6 +29889,11 @@ started. @item @code{log-directory} (default: @code{"/var/log/nginx"}) The directory to which NGinx will write log files. +@item @code{log-level} (default: @code{'error}) (type: symbol) +Logging level, which can be any of the following values: @code{'debug}, +@code{'info}, @code{'notice}, @code{'warn}, @code{'error}, @code{'crit}, +@code{'alert}, or @code{'emerg}. + @item @code{run-directory} (default: @code{"/var/run/nginx"}) The directory in which NGinx will create a pid file, and write temporary files. diff --git a/gnu/services/web.scm b/gnu/services/web.scm index d56e893527..4fe9c2d9ab 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -15,6 +15,7 @@ ;;; Copyright © 2020 Oleg Pykhalov ;;; Copyright © 2020, 2021 Alexandru-Sergiu Marton ;;; Copyright © 2022 Simen Endsjø +;;; Copyright © 2023 Bruno Victal ;;; ;;; This file is part of GNU Guix. ;;; @@ -51,6 +52,8 @@ (define-module (gnu services web) #:use-module (gnu packages logging) #:use-module (gnu packages mail) #:use-module (gnu packages rust-apps) + #:autoload (guix i18n) (G_) + #:use-module (guix diagnostics) #:use-module (guix packages) #:use-module (guix records) #:use-module (guix modules) @@ -61,6 +64,7 @@ (define-module (gnu services web) #:use-module ((guix packages) #:select (package-version)) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) + #:use-module (srfi srfi-34) #:use-module (ice-9 match) #:use-module (ice-9 format) #:export (httpd-configuration @@ -96,6 +100,7 @@ (define-module (gnu services web) nginx-configuration-nginx nginx-configuration-shepherd-requirement nginx-configuration-log-directory + nginx-configuration-log-level nginx-configuration-run-directory nginx-configuration-server-blocks nginx-configuration-upstream-blocks @@ -562,6 +567,9 @@ (define-record-type* (default '())) ;list of symbols (log-directory nginx-configuration-log-directory ;string (default "/var/log/nginx")) + (log-level nginx-configuration-log-level + (sanitize assert-valid-log-level) + (default 'error)) (run-directory nginx-configuration-run-directory ;string (default "/var/run/nginx")) (server-blocks nginx-configuration-server-blocks @@ -584,6 +592,14 @@ (define-record-type* (file nginx-configuration-file ;#f | string | file-like (default #f))) +(define (assert-valid-log-level level) + "Ensure @var{level} is one of @code{'debug}, @code{'info}, @code{'notice}, +@code{'warn}, @code{'error}, @code{'crit}, @code{'alert}, or @code{'emerg}." + (unless (memq level '(debug info notice warn error crit alert emerg)) + (raise + (formatted-message (G_ "unknown log level '~a'~%") level))) + level) + (define (config-domain-strings names) "Return a string denoting the nginx config representation of NAMES, a list of domain names." @@ -692,6 +708,7 @@ (define (default-nginx-config config) (match-record config (nginx log-directory run-directory + log-level server-blocks upstream-blocks server-names-hash-bucket-size server-names-hash-bucket-max-size @@ -704,7 +721,7 @@ (define (default-nginx-config config) (flatten "user nginx nginx;\n" "pid " run-directory "/pid;\n" - "error_log " log-directory "/error.log info;\n" + "error_log " log-directory "/error.log " (symbol->string log-level) ";\n" (map emit-load-module modules) (map emit-global-directive global-directives) "http {\n" -- cgit v1.2.3 From 11ecc5a4f873eaa88c39de0c0c1ac6c165745d8c Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Wed, 12 Apr 2023 16:22:45 +0200 Subject: doc: Fix various typos. * doc/guix.texi: Fix typos. --- doc/guix.texi | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index acb6f0c2e1..adb1975935 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14398,7 +14398,7 @@ for compatibility with an upgraded @code{flex} package. @table @code @item --list-transitive -@itemx --T +@itemx -T List all the packages which one or more packages depend upon. @example @@ -18464,7 +18464,7 @@ The Kmscon package to use. @cindex @abbr{nscd, name service cache daemon} @defvar nscd-service-type Type of the service that runs the libc @abbr{nscd, name service cache -daemon}, whose value is a @code{} object. +daemon}, whose value is an @code{} object. For convenience, the Shepherd service for nscd provides the following actions: @@ -18992,7 +18992,7 @@ seconds for the negative lookups. @xref{Invoking guix publish, @end deftp @defvar rngd-service-type -Type of the service that runs rng-tools rngd, whose value is a +Type of the service that runs rng-tools rngd, whose value is an @code{} object. @end defvar @@ -26315,7 +26315,7 @@ variables. @defvar getmail-service-type This is the type of the @uref{http://pyropus.ca/software/getmail/, Getmail} -mail retriever, whose value should be an @code{getmail-configuration}. +mail retriever, whose value should be a @code{getmail-configuration}. @end defvar Available @code{getmail-configuration} fields are: @@ -31520,7 +31520,7 @@ The list of knot-zone-configuration used by this configuration. @defvar knot-resolver-service-type This is the type of the knot resolver service, whose value should be -an @code{knot-resolver-configuration} object as in this example: +a @code{knot-resolver-configuration} object as in this example: @lisp (service knot-resolver-service-type @@ -31557,7 +31557,7 @@ Number of milliseconds for @code{kres-cache-gc} to periodically trim the cache. @subsubheading Dnsmasq Service @defvar dnsmasq-service-type -This is the type of the dnsmasq service, whose value should be an +This is the type of the dnsmasq service, whose value should be a @code{dnsmasq-configuration} object as in this example: @lisp @@ -37570,7 +37570,7 @@ on whatever else might be trying to use the disk at the time. @defvar fstrim-service-type Type for a service that periodically runs @command{fstrim}, whose value must -be a @code{} object. The service can be instantiated +be an @code{} object. The service can be instantiated in its default configuration with: @lisp @@ -42313,7 +42313,7 @@ for home services is that they have to be declared in a record. @defvar home-mcron-service-type -This is the type of the @code{mcron} home service, whose value is an +This is the type of the @code{mcron} home service, whose value is a @code{home-mcron-configuration} object. It allows to manage scheduled tasks. @@ -42661,7 +42661,7 @@ to the @code{services} field of your @code{home-environment}: @end lisp @defvar home-ssh-agent-service-type -This is the type of the @code{git daemon} home service, whose value is an +This is the type of the @code{ssh-agent} home service, whose value is a @code{home-ssh-agent-configuration} object. @end defvar @@ -42669,8 +42669,8 @@ This is the type of the @code{git daemon} home service, whose value is an Available @code{home-ssh-agent-configuration} fields are: @table @asis -@item @code{git} (default: @code{git}) (type: file-like) -The git package to use. +@item @code{openssh} (default: @code{openssh}) (type: file-like) +The OpenSSH package to use. @item @code{socket-directory} (default: @code{@env{XDG_RUNTIME_DIR}/ssh-agent"}) (type: gexp) The directory to write the ssh-agent's @file{socket} file. @@ -43100,7 +43100,7 @@ to the @code{services} field of your @code{home-environment}: @end lisp @defvar home-znc-service-type -This is the type of the @code{git daemon} home service, whose value is an +This is the type of the ZNC home service, whose value is a @code{home-znc-configuration} object. @end defvar @@ -43108,8 +43108,8 @@ This is the type of the @code{git daemon} home service, whose value is an Available @code{home-znc-configuration} fields are: @table @asis -@item @code{git} (default: @code{git}) (type: file-like) -The git package to use. +@item @code{znc} (default: @code{znc}) (type: file-like) +The ZNC package to use. @item @code{extra-options} (default: @code{'()}) Extra options will be passed to @command{znc}, please run @command{man @@ -43122,9 +43122,9 @@ znc} for more information. @subsection Media Home Services @cindex kodi -The @uref{https://kodi.tv, KODI media center} can be run as a daemon on +The @uref{https://kodi.tv, Kodi media center} can be run as a daemon on a media server. With the @code{(gnu home services kodi)} service, you -can configure KODI to run upon login. +can configure Kodi to run upon login. Here is an example of a service and its configuration that you could add to the @code{services} field of your @code{home-environment}: @@ -43136,7 +43136,7 @@ to the @code{services} field of your @code{home-environment}: @end lisp @defvar home-kodi-service-type -This is the type of the @code{git daemon} home service, whose value is an +This is the type of the Kodi home service, whose value is a @code{home-kodi-configuration} object. @end defvar @@ -43144,8 +43144,8 @@ This is the type of the @code{git daemon} home service, whose value is an Available @code{home-kodi-configuration} fields are: @table @asis -@item @code{git} (default: @code{git}) (type: file-like) -The git package to use. +@item @code{kodi} (default: @code{kodi}) (type: file-like) +The Kodi package to use. @item @code{extra-options} (default: @code{'()}) Extra options will be passed to @command{kodi}, please run @command{man -- cgit v1.2.3