From 63bafb05bc71874cc195ccc12f09f95a461e2987 Mon Sep 17 00:00:00 2001 From: Tomas Volf <~@wolfsden.cz> Date: Sat, 6 Jan 2024 16:52:35 +0100 Subject: doc: Delete trailing whitespace. * doc/guix.texi: Delete trailing whitespace. Change-Id: Ibf99a551f890044b8ce5772bdebb8a0b02ab1c21 Signed-off-by: Mathieu Othacehe --- doc/guix.texi | 72 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index a648a106b3..fc18deb85b 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -45243,25 +45243,25 @@ PulseAudio clients to use PipeWire transparently. @node Mail Home Services @subsection Mail Home Services - + The @code{(gnu home services mail)} module provides services that help you set up the tools to work with emails in your home environment. - + @cindex msmtp @uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail Transfer Protocol} client. It sends mail to a predefined SMTP server that takes care of proper delivery. - + The service reference is given below. - + @defvar home-msmtp-service-type This is the service type for @command{msmtp}. Its value must be a @code{home-msmtp-configuration}, as shown below. It provides the @file{~/.config/msmtp/config} file. - + As an example, here is how you would configure @code{msmtp} for a single account: - + @lisp (service home-msmtp-service-type (home-msmtp-configuration @@ -45279,101 +45279,101 @@ account: @end defvar @c %start of fragment - + @deftp {Data Type} home-msmtp-configuration Available @code{home-msmtp-configuration} fields are: - + @table @asis @item @code{defaults} (type: msmtp-configuration) The configuration that will be set as default for all accounts. - + @item @code{accounts} (default: @code{'()}) (type: list-of-msmtp-accounts) A list of @code{msmtp-account} records which contain information about all your accounts. - + @item @code{default-account} (type: maybe-string) Set the default account. - + @item @code{extra-content} (default: @code{""}) (type: string) Extra content appended as-is to the configuration file. Run @command{man msmtp} for more information about the configuration file format. - + @end table - + @end deftp - + @c %end of fragment - + @c %start of fragment - + @deftp {Data Type} msmtp-account Available @code{msmtp-account} fields are: - + @table @asis @item @code{name} (type: string) The unique name of the account. - + @item @code{configuration} (type: msmtp-configuration) The configuration for this given account. - + @end table - + @end deftp - + @c %end of fragment @c %start of fragment - + @deftp {Data Type} msmtp-configuration Available @code{msmtp-configuration} fields are: - + @table @asis @item @code{auth?} (type: maybe-boolean) Enable or disable authentication. - + @item @code{tls?} (type: maybe-boolean) Enable or disable TLS (also known as SSL) for secured connections. - + @item @code{tls-starttls?} (type: maybe-boolean) Choose the TLS variant: start TLS from within the session (‘on’, default), or tunnel the session through TLS (‘off’). - + @item @code{tls-trust-file} (type: maybe-string) Activate server certificate verification using a list of trusted Certification Authorities (CAs). - + @item @code{log-file} (type: maybe-string) Enable logging to the specified file. An empty argument disables logging. The file name ‘-’ directs the log information to standard output. - + @item @code{host} (type: maybe-string) The SMTP server to send the mail to. - + @item @code{port} (type: maybe-integer) The port that the SMTP server listens on. The default is 25 ("smtp"), unless TLS without STARTTLS is used, in which case it is 465 ("smtps"). - + @item @code{user} (type: maybe-string) Set the user name for authentication. - + @item @code{from} (type: maybe-string) Set the envelope-from address. - + @item @code{password-eval} (type: maybe-string) Set the password for authentication to the output (stdout) of the command cmd. - + @item @code{extra-content} (default: @code{""}) (type: string) Extra content appended as-is to the configuration block. Run @command{man msmtp} for more information about the configuration file format. - + @end table - + @end deftp - + @c %end of fragment @node Messaging Home Services -- cgit v1.2.3 From 7d5168a2af3ed922c6a46985124fb73402cc8844 Mon Sep 17 00:00:00 2001 From: Graham James Addis Date: Wed, 12 Jul 2023 09:17:13 +0100 Subject: guix: pack: Add '--entry-point-argument' option. * guix/scripts/pack.scm: (entry-point-argument-spec-option-parser): New procedure. (docker-image, %default-options, %docker-format-options, show-docker-format-options/detailed, %options, show-docker-format-options, guix-pack): Handle '--entry-point-argument' option. * doc/guix.texi: (Invoking guix pack): Document this Signed-off-by: Oleg Pykhalov Change-Id: I1124feff6af39dcc63c85fd6cc7ad50f398489dc --- doc/guix.texi | 14 +++++++++++++- guix/scripts/pack.scm | 50 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 54 insertions(+), 10 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index fc18deb85b..27ebed137d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -122,6 +122,7 @@ Copyright @copyright{} 2023 Felix Lechner@* Copyright @copyright{} 2023 Foundation Devices, Inc.@* Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* +Copyright @copyright{} 2023 Graham James Addis@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -7406,7 +7407,7 @@ execution engines listed above by setting the @env{GUIX_EXECUTION_ENGINE} environment variable accordingly. @end quotation -@cindex entry point, for Docker images +@cindex entry point, for Docker and Singularity images @item --entry-point=@var{command} Use @var{command} as the @dfn{entry point} of the resulting pack, if the pack format supports it---currently @code{docker} and @code{squashfs} (Singularity) @@ -7429,6 +7430,17 @@ docker load -i pack.tar.gz docker run @var{image-id} @end example +@cindex entry point arguments, for docker images +@item --entry-point-argument=@var{command} +@itemx -A @var{command} +Use @var{command} as an argument to @dfn{entry point} of the resulting pack. +This option is only valid in conjunction with @code{--entry-point} and can +appear multiple times on the command line. + +@example +guix pack -f docker --entry-point=bin/guile --entry-point-argument="--help" guile +@end example + @item --expression=@var{expr} @itemx -e @var{expr} Consider the package @var{expr} evaluates to. diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 8071840de1..4c0a602eb1 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2020, 2021, 2022, 2023 Maxim Cournoyer ;;; Copyright © 2020 Eric Bavier ;;; Copyright © 2022 Alex Griffin +;;; Copyright © 2023 Graham James Addis ;;; ;;; This file is part of GNU Guix. ;;; @@ -202,6 +203,16 @@ (define (symlink-spec-option-parser opt name arg result) (leave (G_ "~a: invalid symlink specification~%") arg)))) +(define (entry-point-argument-spec-option-parser opt name arg result) + "A SRFI-37 opion parser for the --entry-point-argument option. The spec +takes multiple occurances. The entries are used in the exec form for the +docker entry-point. The values are used as parameters in conjunction with +the --entry-point option which is used as the first value in the exec form." + (let ((entry-point-argument (assoc-ref result 'entry-point-argument))) + (alist-cons 'entry-point-argument + (append entry-point-argument (list arg)) + (alist-delete 'entry-point-argument result eq?)))) + (define (set-utf8-locale profile) "Configure the environment to use the \"en_US.utf8\" locale provided by the GLIBC-UT8-LOCALES package." @@ -562,10 +573,22 @@ (define directives `((directory "/tmp" ,(getuid) ,(getgid) #o1777) ,@(append-map symlink->directives '#$symlinks))) + (define (form-entry-point prefix entry-point entry-point-argument) + ;; Construct entry-point parameter for build-docker-image. The + ;; first entry is constructed by prefixing the entry-point with + ;; the supplied index subsequent entries are taken from the + ;; --entry-point-argument options. + (and=> entry-point + (lambda (entry-point) + (cons* (string-append prefix "/" entry-point) + entry-point-argument)))) + (setenv "PATH" #+(file-append archiver "/bin")) (let-keywords '#$extra-options #f - ((image-tag #f)) + ((image-tag #f) + (entry-point-argument #f)) + (build-docker-image #$output (map store-info-item (call-with-input-file "profile" @@ -578,11 +601,10 @@ (define directives #:database #+database #:system (or #$target %host-type) #:environment environment - #:entry-point - #$(and entry-point - #~(list - (string-append #$profile "/" - #$entry-point))) + #:entry-point (form-entry-point + #$profile + #$entry-point + entry-point-argument) #:extra-files directives #:compressor #+(compressor-command compressor) @@ -1264,6 +1286,7 @@ (define %default-options (debug . 0) (verbosity . 1) (symlinks . ()) + (entry-point-argument . ()) (compressor . ,(first %compressors)))) (define %formats @@ -1299,7 +1322,9 @@ (define (required-option symbol) rest)))) (define %docker-format-options - (list (required-option 'image-tag))) + (list (required-option 'image-tag) + (option '(#\A "entry-point-argument") #t #f + entry-point-argument-spec-option-parser))) (define (show-docker-format-options) (display (G_ " @@ -1308,7 +1333,12 @@ (define (show-docker-format-options) (define (show-docker-format-options/detailed) (display (G_ " --image-tag=NAME - Use the given NAME for the Docker image repository")) + Use the given NAME for the Docker image repository + + -A, --entry-point-argument=COMMAND/PARAMETER + Value(s) to use for the Docker EntryPoint arguments. + Multiple instances are accepted. This is only valid + in conjunction with the --entry-point option")) (newline) (exit 0)) @@ -1619,7 +1649,9 @@ (define (process-file-arg opts name) (extra-options (match pack-format ('docker (list #:image-tag - (assoc-ref opts 'image-tag))) + (assoc-ref opts 'image-tag) + #:entry-point-argument + (assoc-ref opts 'entry-point-argument))) ('deb (list #:control-file (process-file-arg opts 'control-file) -- cgit v1.2.3 From 0cf75c9b2f23869201144917cea7f6ad49683d3d Mon Sep 17 00:00:00 2001 From: Oleg Pykhalov Date: Tue, 26 Dec 2023 03:54:12 +0300 Subject: guix: pack: Build layered images. * guix/scripts/pack.scm (docker-image, guix-pack, %default-options, %docker-format-options, show-docker-format-options/detailed): Handle '--max-layers' option. * doc/guix.texi (Invoking guix pack): Document this. Change-Id: I90660b2421fcdde891f003469fe2e2edaac7da41 --- doc/guix.texi | 26 +++++++++++++++++++++- guix/scripts/pack.scm | 60 +++++++++++++++++++++++++++++++++++---------------- tests/pack.scm | 50 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 20 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 27ebed137d..96035bd97c 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -56,7 +56,7 @@ Copyright @copyright{} 2017 Andy Wingo@* Copyright @copyright{} 2017, 2018, 2019, 2020, 2023 Arun Isaac@* Copyright @copyright{} 2017 nee@* Copyright @copyright{} 2018 Rutger Helling@* -Copyright @copyright{} 2018, 2021 Oleg Pykhalov@* +Copyright @copyright{} 2018, 2021, 2023 Oleg Pykhalov@* Copyright @copyright{} 2018 Mike Gerwitz@* Copyright @copyright{} 2018 Pierre-Antoine Rouby@* Copyright @copyright{} 2018, 2019 Gábor Boskovits@* @@ -7441,6 +7441,30 @@ appear multiple times on the command line. guix pack -f docker --entry-point=bin/guile --entry-point-argument="--help" guile @end example +@cindex maximum layers argument, for docker images +@item --max-layers=@code{n} +Specifies the maximum number of Docker image layers allowed when +building an image. + +@example +guix pack -f docker --max-layers=100 guile +@end example + +This option allows you to limit the number of layers in a Docker image. +Docker images are comprised of multiple layers, and each layer adds to +the overall size and complexity of the image. By setting a maximum +number of layers, you can control the following effects: + +@itemize +@item Disk Usage: +Increasing the number of layers can help optimize the disk space +required to store multiple images built with a similar package graph. + +@item Pulling: +When transferring images between different nodes or systems, having more +layers can reduce the time required to pull the image. +@end itemize + @item --expression=@var{expr} @itemx -e @var{expr} Consider the package @var{expr} evaluates to. diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 4c0a602eb1..d0acc6cfd8 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -9,6 +9,7 @@ ;;; Copyright © 2020 Eric Bavier ;;; Copyright © 2022 Alex Griffin ;;; Copyright © 2023 Graham James Addis +;;; Copyright © 2023 Oleg Pykhalov ;;; ;;; This file is part of GNU Guix. ;;; @@ -48,6 +49,7 @@ (define-module (guix scripts pack) #:use-module (guix scripts build) #:use-module (guix transformations) #:use-module ((guix self) #:select (make-config.scm)) + #:use-module ((guix docker) #:select (%docker-image-max-layers)) #:use-module (gnu compression) #:use-module (gnu packages) #:use-module (gnu packages bootstrap) @@ -204,10 +206,10 @@ (define (symlink-spec-option-parser opt name arg result) arg)))) (define (entry-point-argument-spec-option-parser opt name arg result) - "A SRFI-37 opion parser for the --entry-point-argument option. The spec -takes multiple occurances. The entries are used in the exec form for the -docker entry-point. The values are used as parameters in conjunction with -the --entry-point option which is used as the first value in the exec form." + "A SRFI-37 option parser for the --entry-point-argument option. The spec +takes multiple occurrences. The entries are used in the exec form for the +docker entry-point. The values are used as parameters in conjunction with the +--entry-point option which is used as the first value in the exec form." (let ((entry-point-argument (assoc-ref result 'entry-point-argument))) (alist-cons 'entry-point-argument (append entry-point-argument (list arg)) @@ -517,12 +519,15 @@ (define* (docker-image name profile localstatedir? (symlinks '()) (archiver tar) - (extra-options '())) - "Return a derivation to construct a Docker image of PROFILE. The -image is a tarball conforming to the Docker Image Specification, compressed -with COMPRESSOR. It can be passed to 'docker load'. If TARGET is true, it -must a be a GNU triplet and it is used to derive the architecture metadata in -the image. EXTRA-OPTIONS may contain the IMAGE-TAG keyword argument." + (extra-options '()) + max-layers) + "Return a derivation to construct a Docker image of PROFILE. The image is a +tarball conforming to the Docker Image Specification, compressed with +COMPRESSOR. It can be passed to 'docker load'. If TARGET is true, it must a +be a GNU triplet and it is used to derive the architecture metadata in the +image. EXTRA-OPTIONS may contain the IMAGE-TAG keyword argument. If +MAX-LAYERS is not false, the image will be splitted in up to MAX-LAYERS +layers." (define database (and localstatedir? (file-append (store-database (list profile)) @@ -576,18 +581,24 @@ (define directives (define (form-entry-point prefix entry-point entry-point-argument) ;; Construct entry-point parameter for build-docker-image. The ;; first entry is constructed by prefixing the entry-point with - ;; the supplied index subsequent entries are taken from the + ;; the supplied index, subsequent entries are taken from the ;; --entry-point-argument options. (and=> entry-point (lambda (entry-point) (cons* (string-append prefix "/" entry-point) - entry-point-argument)))) + entry-point-argument)))) - (setenv "PATH" #+(file-append archiver "/bin")) + (setenv "PATH" + (string-join `(#+(file-append archiver "/bin") + #+@(if max-layers + (list (file-append gzip "/bin")) + '())) + ":")) (let-keywords '#$extra-options #f ((image-tag #f) - (entry-point-argument #f)) + (entry-point-argument #f) + (max-layers #f)) (build-docker-image #$output (map store-info-item @@ -609,7 +620,8 @@ (define (form-entry-point prefix entry-point entry-point-argument) #:compressor #+(compressor-command compressor) #:creation-time - (make-time time-utc 0 1))))))) + (make-time time-utc 0 1) + #:max-layers max-layers)))))) (gexp->derivation (string-append name ".tar" (compressor-extension compressor)) @@ -1287,6 +1299,7 @@ (define %default-options (verbosity . 1) (symlinks . ()) (entry-point-argument . ()) + (max-layers . ,%docker-image-max-layers) (compressor . ,(first %compressors)))) (define %formats @@ -1324,7 +1337,11 @@ (define (required-option symbol) (define %docker-format-options (list (required-option 'image-tag) (option '(#\A "entry-point-argument") #t #f - entry-point-argument-spec-option-parser))) + entry-point-argument-spec-option-parser) + (option '("max-layers") #t #f + (lambda (opt name arg result) + (alist-cons 'max-layers (string->number* arg) + result))))) (define (show-docker-format-options) (display (G_ " @@ -1336,9 +1353,12 @@ (define (show-docker-format-options/detailed) Use the given NAME for the Docker image repository -A, --entry-point-argument=COMMAND/PARAMETER - Value(s) to use for the Docker EntryPoint arguments. + Value(s) to use for the Docker ENTRYPOINT arguments. Multiple instances are accepted. This is only valid - in conjunction with the --entry-point option")) + in conjunction with the --entry-point option + + --max-layers=N + Number of image layers")) (newline) (exit 0)) @@ -1651,7 +1671,9 @@ (define (process-file-arg opts name) (list #:image-tag (assoc-ref opts 'image-tag) #:entry-point-argument - (assoc-ref opts 'entry-point-argument))) + (assoc-ref opts 'entry-point-argument) + #:max-layers + (assoc-ref opts 'max-layers))) ('deb (list #:control-file (process-file-arg opts 'control-file) diff --git a/tests/pack.scm b/tests/pack.scm index ac78817a70..55445ea1e9 100644 --- a/tests/pack.scm +++ b/tests/pack.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2017-2021, 2023 Ludovic Courtès ;;; Copyright © 2018 Ricardo Wurmus ;;; Copyright © 2021, 2023 Maxim Cournoyer +;;; Copyright © 2023 Oleg Pykhalov ;;; ;;; This file is part of GNU Guix. ;;; @@ -29,6 +30,7 @@ (define-module (test-pack) #:use-module (guix gexp) #:use-module (guix modules) #:use-module (guix utils) + #:use-module ((guix build utils) #:select (%store-directory)) #:use-module (gnu packages) #:use-module ((gnu packages base) #:select (libc-utf8-locales-for-target)) #:use-module (gnu packages bootstrap) @@ -250,6 +252,54 @@ (define bin (mkdir #$output))))))) (built-derivations (list check)))) + (unless store (test-skip 1)) + (test-assertm "docker-layered-image + localstatedir" + (mlet* %store-monad + ((guile (set-guile-for-build (default-guile))) + (profile -> (profile + (content (packages->manifest (list %bootstrap-guile))) + (hooks '()) + (locales? #f))) + (tarball (docker-image "docker-pack" profile + #:symlinks '(("/bin/Guile" -> "bin/guile")) + #:localstatedir? #t + #:max-layers 100)) + (check (gexp->derivation + "check-tarball" + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils) + (ice-9 match)) + + (define bin + (string-append "." #$profile "/bin")) + + (define store + (string-append "." #$(%store-directory))) + + (setenv "PATH" (string-append #$%tar-bootstrap "/bin")) + (mkdir "base") + (with-directory-excursion "base" + (invoke "tar" "xvf" #$tarball)) + + (match (find-files "base" "layer.tar") + ((layers ...) + (for-each (lambda (layer) + (invoke "tar" "xvf" layer) + (invoke "chmod" "--recursive" "u+w" store)) + layers))) + + (when + (and (file-exists? (string-append bin "/guile")) + (file-exists? "var/guix/db/db.sqlite") + (file-is-directory? "tmp") + (string=? (string-append #$%bootstrap-guile "/bin") + (readlink bin)) + (string=? (string-append #$profile "/bin/guile") + (readlink "bin/Guile"))) + (mkdir #$output))))))) + (built-derivations (list check)))) + (unless store (test-skip 1)) (test-assertm "squashfs-image + localstatedir" (mlet* %store-monad -- cgit v1.2.3 From 9f44ff2bb47c964d53905cea17c4bda758cce509 Mon Sep 17 00:00:00 2001 From: David Elsing Date: Thu, 21 Dec 2023 22:01:50 +0000 Subject: import: crate: Optionally import dev-dependencies recursively. If --recursive-dev-dependencies is specified, development dependencies are also included for all recursively imported packages. * doc/guix.texi (Invoking guix import): Mention --recursive-dev-dependencies. * guix/import/crate.scm (crate-recursive-import): Add recursive-dev-dependencies? argument. * guix/scripts/import/crate.scm (show-help, guix-import-crate): Add "--recursive-dev-dependencies". * tests/crate.scm: Test both #f and #t for #:recursive-dev-dependencies? in the 'cargo-recursive-import' test. (test-root-dependencies): Add intermediate-c as dev-dependency. (test-intermediate-c-crate, test-intermediate-c-dependencies): New variables. Signed-off-by: Efraim Flashner Change-Id: Iae89794681155d77f128733120e60f03bc297717 --- doc/guix.texi | 4 + guix/import/crate.scm | 7 +- guix/scripts/import/crate.scm | 12 ++- tests/crate.scm | 228 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 244 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 96035bd97c..544f86a6ac 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14585,6 +14585,10 @@ Additional options include: Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix. +@item --recursive-dev-dependencies +If @option{--recursive-dev-dependencies} is specified, also the recursively +imported packages contain their development dependencies, which are recursively +imported as well. @end table @item elm diff --git a/guix/import/crate.scm b/guix/import/crate.scm index 07874bdb26..db5461312f 100644 --- a/guix/import/crate.scm +++ b/guix/import/crate.scm @@ -328,14 +328,17 @@ (define (sort-map-dependencies deps) (append cargo-inputs cargo-development-inputs))) (values #f '()))) -(define* (crate-recursive-import crate-name #:key version) +(define* (crate-recursive-import + crate-name #:key version recursive-dev-dependencies?) (recursive-import crate-name #:repo->guix-package (let ((crate->guix-package* (memoize crate->guix-package))) (lambda* params ;; download development dependencies only for the top level package - (let ((include-dev-deps? (equal? (car params) crate-name))) + (let ((include-dev-deps? + (or (equal? (car params) crate-name) + recursive-dev-dependencies?))) (apply crate->guix-package* (append params `(#:include-dev-deps? ,include-dev-deps?)))))) #:version version diff --git a/guix/scripts/import/crate.scm b/guix/scripts/import/crate.scm index 038faa87db..b13b6636a6 100644 --- a/guix/scripts/import/crate.scm +++ b/guix/scripts/import/crate.scm @@ -5,6 +5,7 @@ ;;; Copyright © 2019, 2020 Martin Becze ;;; Copyright © 2021 Sarah Morgensen ;;; Copyright © 2023 Simon Tournier +;;; Copyright © 2023 David Elsing ;;; ;;; This file is part of GNU Guix. ;;; @@ -47,6 +48,9 @@ (define (show-help) Import and convert the crates.io package for PACKAGE-NAME.\n")) (display (G_ " -r, --recursive import packages recursively")) + (display (G_ " + --recursive-dev-dependencies + include dev-dependencies recursively")) (newline) (display (G_ " -h, --help display this help and exit")) @@ -67,6 +71,9 @@ (define %options (option '(#\r "recursive") #f #f (lambda (opt name arg result) (alist-cons 'recursive #t result))) + (option '("recursive-dev-dependencies") #f #f + (lambda (opt name arg result) + (alist-cons 'recursive-dev-dependencies #t result))) %standard-import-options)) @@ -92,7 +99,10 @@ (define-values (name version) (package-name->name+version spec)) (match (if (assoc-ref opts 'recursive) - (crate-recursive-import name #:version version) + (crate-recursive-import + name #:version version + #:recursive-dev-dependencies? + (assoc-ref opts 'recursive-dev-dependencies)) (crate->guix-package name #:version version #:include-dev-deps? #t)) ((or #f '()) (leave (G_ "failed to download meta-data for package '~a'~%") diff --git a/tests/crate.scm b/tests/crate.scm index 5aea5efaf3..1b9ad88358 100644 --- a/tests/crate.scm +++ b/tests/crate.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2019, 2020, 2022 Ludovic Courtès ;;; Copyright © 2020 Martin Becze ;;; Copyright © 2023 Efraim Flashner +;;; Copyright © 2023 David Elsing ;;; ;;; This file is part of GNU Guix. ;;; @@ -40,10 +41,11 @@ (define-module (test-crate) ;; ;; root-1.0.0 ;; root-1.0.4 -;; intermediate-a 1.0.42 -;; intermeidate-b ^1.0.0 +;; intermediate-a 1.0.42 +;; intermediate-b ^1.0.0 ;; leaf-alice ^0.7 -;; leaf-bob ^3 +;; leaf-bob ^3 +;; intermediate-c 1 (dev-dependency) ;; ;; intermediate-a-1.0.40 ;; intermediate-a-1.0.42 @@ -55,6 +57,9 @@ (define-module (test-crate) ;; intermediate-b-1.2.3 ;; leaf-bob 3.0.1 ;; +;; intermediate-c-1.0.1 +;; leaf-alice 0.7.5 (dev-dependency) +;; ;; leaf-alice-0.7.3 ;; leaf-alice-0.7.5 ;; @@ -164,6 +169,11 @@ (define test-root-dependencies \"crate_id\": \"leaf-bob\", \"kind\": \"normal\", \"req\": \"^3\" + }, + { + \"crate_id\": \"intermediate-c\", + \"kind\": \"dev\", + \"req\": \"1\" } ] }") @@ -262,6 +272,40 @@ (define test-intermediate-b-dependencies ] }") +(define test-intermediate-c-crate + "{ + \"crate\": { + \"max_version\": \"1.0.1\", + \"name\": \"intermediate-c\", + \"description\": \"summary\", + \"homepage\": \"http://example.com\", + \"repository\": \"http://example.com\", + \"keywords\": [\"dummy\", \"test\"], + \"categories\": [\"test\"], + \"actual_versions\": [ + { \"id\": 234290, + \"num\": \"1.0.1\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/intermediate-c/1.0.1/dependencies\" + }, + \"yanked\": false + } + ] + } +}") + +(define test-intermediate-c-dependencies + "{ + \"dependencies\": [ + { + \"crate_id\": \"leaf-alice\", + \"kind\": \"dev\", + \"req\": \"0.7.5\" + } + ] +}") + (define test-leaf-alice-crate "{ \"crate\": { @@ -430,6 +474,15 @@ (define have-guile-semver? (open-input-string "empty file\n")) ("https://crates.io/api/v1/crates/intermediate-b/1.2.3/dependencies" (open-input-string test-intermediate-b-dependencies)) + ("https://crates.io/api/v1/crates/intermediate-c" + (open-input-string test-intermediate-c-crate)) + ("https://crates.io/api/v1/crates/intermediate-c/1.0.1/download" + (set! test-source-hash + (bytevector->nix-base32-string + (sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/intermediate-c/1.0.1/dependencies" + (open-input-string test-intermediate-c-dependencies)) ("https://crates.io/api/v1/crates/leaf-alice" (open-input-string test-leaf-alice-crate)) ("https://crates.io/api/v1/crates/leaf-alice/0.7.5/download" @@ -452,7 +505,27 @@ (define have-guile-semver? (match (crate-recursive-import "root") ;; rust-intermediate-b has no dependency on the rust-leaf-alice ;; package, so this is a valid ordering - (((define-public 'rust-leaf-alice-0.7 + (((define-public 'rust-intermediate-c-1 + (package + (name "rust-intermediate-c") + (version "1.0.1") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-c" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:skip-build? #t))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-alice-0.7 (package (name "rust-leaf-alice") (version "0.7.5") @@ -562,11 +635,158 @@ (define-public 'rust-root-1 ('unquote rust-intermediate-b-1)) ("rust-leaf-alice" ('unquote 'rust-leaf-alice-0.7)) + ("rust-leaf-bob" + ('unquote rust-leaf-bob-3))) + #:cargo-development-inputs + (("rust-intermediate-c" + ('unquote rust-intermediate-c-1)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0))))) + #t) + (x + (pk 'fail x #f))) + (match (crate-recursive-import "root" + #:recursive-dev-dependencies? #t) + ;; rust-intermediate-b has no dependency on the rust-leaf-alice + ;; package, so this is a valid ordering + (((define-public 'rust-intermediate-c-1 + (package + (name "rust-intermediate-c") + (version "1.0.1") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-c" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:cargo-development-inputs + (("rust-leaf-alice" + ('unquote rust-leaf-alice-0.7)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-alice-0.7 + (package + (name "rust-leaf-alice") + (version "0.7.5") + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-alice" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-bob-3 + (package + (name "rust-leaf-bob") + (version "3.0.1") + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-bob" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-intermediate-b-1 + (package + (name "rust-intermediate-b") + (version "1.2.3") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-b" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:cargo-inputs + (("rust-leaf-bob" + ('unquote rust-leaf-bob-3)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-intermediate-a-1 + (package + (name "rust-intermediate-a") + (version "1.0.42") + (source + (origin + (method url-fetch) + (uri (crate-uri "intermediate-a" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:cargo-inputs + (("rust-intermediate-b" + ('unquote rust-intermediate-b-1)) + ("rust-leaf-alice" + ('unquote 'rust-leaf-alice-0.7)) ("rust-leaf-bob" ('unquote rust-leaf-bob-3)))))) (home-page "http://example.com") (synopsis "summary") (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-root-1 + (package + (name "rust-root") + (version "1.0.4") + (source + (origin + (method url-fetch) + (uri (crate-uri "root" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:cargo-inputs + (("rust-intermediate-a" + ('unquote rust-intermediate-a-1)) + ("rust-intermediate-b" + ('unquote rust-intermediate-b-1)) + ("rust-leaf-alice" + ('unquote 'rust-leaf-alice-0.7)) + ("rust-leaf-bob" + ('unquote rust-leaf-bob-3))) + #:cargo-development-inputs + (("rust-intermediate-c" + ('unquote rust-intermediate-c-1)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") (license (list license:expat license:asl2.0))))) #t) (x -- cgit v1.2.3 From b26926189e5bf253093050f9a73f2d9d7555cc3e Mon Sep 17 00:00:00 2001 From: David Elsing Date: Thu, 21 Dec 2023 22:01:52 +0000 Subject: guix: import: Optionally import necessary yanked crates. * doc/guix.texi (Invoking guix import): Mention '--allow-yanked'. * guix/import/crate.scm (make-crate-sexp): Add yanked? argument. For yanked packages, use the full version suffixed by "-yanked" for generated variable names and add a comment and package property. (crate->guix-package): Add allow-yanked? argument and if it is set to #t, allow importing yanked crates if no other version matching the requirements exists. [find-package-version]: Packages previously marked as yanked are only included if allow-yanked? is #t and then take the lowest priority. [find-crate-version]: If allow-yanked? is #t, also consider yanked versions with the lowest priority. [dependency-name+version]: Rename to ... [dependency-name+version+yanked] ...this. Honor allow-yanked? and choose between an existing package and an upstream package. Exit with an error message if no version fulfilling the requirement is found. [version*]: Exit with an error message if the crate version is not found. (cargo-recursive-import): Add allow-yanked? argument. * guix/read-print.scm: Export . * guix/scripts/import/crate.scm: Add "--allow-yanked". * tests/crate.scm: Add test 'crate-recursive-import-only-yanked-available'. [sort-map-dependencies]: Adjust accordingly. [remove-yanked-info]: New variable. Adjust test 'crate-recursive-import-honors-existing-packages'. (test-bar-dependencies): Add yanked dev-dependencies. (test-leaf-bob-crate): Add yanked versions. (rust-leaf-bob-3.0.2-yanked): New variable. Signed-off-by: Efraim Flashner Change-Id: I175d89b39774e6b57dcd1f05bf68718d23866bb7 --- doc/guix.texi | 3 + guix/import/crate.scm | 139 ++++++++++++++++++++++-------- guix/read-print.scm | 1 + guix/scripts/import/crate.scm | 14 ++- tests/crate.scm | 193 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 310 insertions(+), 40 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 544f86a6ac..395545bed7 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14589,6 +14589,9 @@ in Guix. If @option{--recursive-dev-dependencies} is specified, also the recursively imported packages contain their development dependencies, which are recursively imported as well. +@item --allow-yanked +If no non-yanked version of a crate is available, use the latest yanked +version instead instead of aborting. @end table @item elm diff --git a/guix/import/crate.scm b/guix/import/crate.scm index db5461312f..c57bd0bc6a 100644 --- a/guix/import/crate.scm +++ b/guix/import/crate.scm @@ -26,12 +26,15 @@ (define-module (guix import crate) #:use-module (guix base32) #:use-module (guix build-system cargo) + #:use-module (guix diagnostics) #:use-module (gcrypt hash) #:use-module (guix http-client) + #:use-module (guix i18n) #:use-module (guix import json) #:use-module (guix import utils) #:use-module (guix memoization) #:use-module (guix packages) + #:use-module (guix read-print) #:use-module (guix upstream) #:use-module (guix utils) #:use-module (gnu packages) @@ -41,6 +44,7 @@ (define-module (guix import crate) #:use-module (srfi srfi-1) #:use-module (srfi srfi-2) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-69) #:use-module (srfi srfi-71) #:export (crate->guix-package guix-package->crate-name @@ -100,7 +104,7 @@ (define-json-mapping make-crate-dependency ;; Autoload Guile-Semver so we only have a soft dependency. (module-autoload! (current-module) - '(semver) '(string->semver semver->string semversemver semver->string semversemver-range semver-range-contains?)) @@ -165,16 +169,18 @@ (define (version->semver-prefix version) (list-matches "^(0+\\.){,2}[0-9]+" version)))) (define* (make-crate-sexp #:key name version cargo-inputs cargo-development-inputs - home-page synopsis description license build?) + home-page synopsis description license build? yanked?) "Return the `package' s-expression for a rust package with the given NAME, VERSION, CARGO-INPUTS, CARGO-DEVELOPMENT-INPUTS, HOME-PAGE, SYNOPSIS, DESCRIPTION, and LICENSE." (define (format-inputs inputs) (map (match-lambda - ((name version) + ((name version yanked) (list (crate-name->package-name name) - (version->semver-prefix version)))) + (if yanked + (string-append version "-yanked") + (version->semver-prefix version))))) inputs)) (let* ((port (http-fetch (crate-uri name version))) @@ -184,6 +190,9 @@ (define (format-inputs inputs) (pkg `(package (name ,guix-name) (version ,version) + ,@(if yanked? + `(,(comment "; This version was yanked!\n" #t)) + '()) (source (origin (method url-fetch) (uri (crate-uri ,name version)) @@ -191,6 +200,9 @@ (define (format-inputs inputs) (sha256 (base32 ,(bytevector->nix-base32-string (port-sha256 port)))))) + ,@(if yanked? + `((properties '((crate-version-yanked? . #t)))) + '()) (build-system cargo-build-system) ,@(maybe-arguments (append (if build? '() @@ -207,7 +219,10 @@ (define (format-inputs inputs) ((license) license) (_ `(list ,@license))))))) (close-port port) - (package->definition pkg (version->semver-prefix version)))) + (package->definition pkg + (if yanked? + (string-append version "-yanked") + (version->semver-prefix version))))) (define (string->license string) (filter-map (lambda (license) @@ -218,13 +233,14 @@ (define (string->license string) 'unknown-license!))) (string-split string (string->char-set " /")))) -(define* (crate->guix-package crate-name #:key version include-dev-deps? - #:allow-other-keys) +(define* (crate->guix-package + crate-name + #:key version include-dev-deps? allow-yanked? #:allow-other-keys) "Fetch the metadata for CRATE-NAME from crates.io, and return the `package' s-expression corresponding to that package, or #f on failure. When VERSION is specified, convert it into a semver range and attempt to fetch the latest version matching this semver range; otherwise fetch the latest -version of CRATE-NAME. If INCLUDE-DEV-DEPS is true then this will also +version of CRATE-NAME. If INCLUDE-DEV-DEPS is true then this will also look up the development dependencs for the given crate." (define (semver-range-contains-string? range version) @@ -243,63 +259,112 @@ (define version-number (or version (crate-latest-version crate)))) - ;; find the highest existing package that fulfills the semver + ;; Find the highest existing package that fulfills the semver . + ;; Packages previously marked as yanked take lower priority. (define (find-package-version name range) (let* ((semver-range (string->semver-range range)) - (versions + (package-versions (sort - (filter (lambda (version) - (semver-range-contains? semver-range version)) + (filter (match-lambda ((semver yanked) + (and + (or allow-yanked? (not yanked)) + (semver-range-contains? semver-range semver)))) (map (lambda (pkg) - (string->semver (package-version pkg))) + (let ((version (package-version pkg))) + (list + (string->semver version) + (assoc-ref (package-properties pkg) + 'crate-version-yanked?)))) (find-packages-by-name (crate-name->package-name name)))) - semverstring (last versions))))) - - ;; Find the highest version of a crate that fulfills the semver - ;; and hasn't been yanked. + (match-lambda* (((semver1 yanked1) (semver2 yanked2)) + (or (and yanked1 (not yanked2)) + (and (eq? yanked1 yanked2) + (semverstring semver) yanked))))) + + ;; Find the highest version of a crate that fulfills the semver . + ;; If no matching non-yanked version has been found and allow-yanked? is #t, + ;; also consider yanked packages. (define (find-crate-version crate range) (let* ((semver-range (string->semver-range range)) (versions (sort (filter (lambda (entry) (and - (not (crate-version-yanked? (second entry))) + (or allow-yanked? + (not (crate-version-yanked? (second entry)))) (semver-range-contains? semver-range (first entry)))) (map (lambda (ver) (list (string->semver (crate-version-number ver)) ver)) (crate-versions crate))) - (match-lambda* (((semver _) ...) - (apply semversemver (first existing-version)) + (string->semver (crate-version-number ver))) + (begin + (warning (G_ "~A: version ~a is no longer yanked~%") + name (first existing-version)) + (cons name existing-version)) + (list name + (crate-version-number ver) + (crate-version-yanked? ver))) + (begin + (warning (G_ "~A: using existing version ~a, which was yanked~%") + name (first existing-version)) + (cons name existing-version))) + (begin + (unless ver + (leave (G_ "~A: no version found for requirement ~a~%") name req)) + (if (crate-version-yanked? ver) + (warning (G_ "~A: imported version ~a was yanked~%") + name (crate-version-number ver))) + (list name + (crate-version-number ver) + (crate-version-yanked? ver)))))))) (define version* (and crate - (find-crate-version crate version-number))) + (or (find-crate-version crate version-number) + (leave (G_ "~A: version ~a not found~%") crate-name version-number)))) ;; sort and map the dependencies to a list containing ;; pairs of (name version) (define (sort-map-dependencies deps) - (sort (map dependency-name+version + (sort (map dependency-name+version+yanked deps) - (match-lambda* (((name _) ...) + (match-lambda* (((name _ _) ...) (apply string-ci (crate-version-license version*) string->license)) - (append cargo-inputs cargo-development-inputs))) + (append + (remove-yanked-info cargo-inputs) + (remove-yanked-info cargo-development-inputs)))) (values #f '()))) (define* (crate-recursive-import - crate-name #:key version recursive-dev-dependencies?) + crate-name #:key version recursive-dev-dependencies? allow-yanked?) (recursive-import crate-name #:repo->guix-package @@ -340,7 +408,8 @@ (define* (crate-recursive-import (or (equal? (car params) crate-name) recursive-dev-dependencies?))) (apply crate->guix-package* - (append params `(#:include-dev-deps? ,include-dev-deps?)))))) + (append params `(#:include-dev-deps? ,include-dev-deps? + #:allow-yanked? ,allow-yanked?)))))) #:version version #:guix-name crate-name->package-name)) diff --git a/guix/read-print.scm b/guix/read-print.scm index 690f5dacdd..6421b79737 100644 --- a/guix/read-print.scm +++ b/guix/read-print.scm @@ -46,6 +46,7 @@ (define-module (guix read-print) page-break page-break? + comment comment? comment->string diff --git a/guix/scripts/import/crate.scm b/guix/scripts/import/crate.scm index b13b6636a6..082a973aee 100644 --- a/guix/scripts/import/crate.scm +++ b/guix/scripts/import/crate.scm @@ -51,6 +51,10 @@ (define (show-help) (display (G_ " --recursive-dev-dependencies include dev-dependencies recursively")) + (display (G_ " + --allow-yanked + allow importing yanked crates if no alternative + satisfying the version requirement exists")) (newline) (display (G_ " -h, --help display this help and exit")) @@ -74,6 +78,9 @@ (define %options (option '("recursive-dev-dependencies") #f #f (lambda (opt name arg result) (alist-cons 'recursive-dev-dependencies #t result))) + (option '("allow-yanked") #f #f + (lambda (opt name arg result) + (alist-cons 'allow-yanked #t result))) %standard-import-options)) @@ -102,8 +109,11 @@ (define-values (name version) (crate-recursive-import name #:version version #:recursive-dev-dependencies? - (assoc-ref opts 'recursive-dev-dependencies)) - (crate->guix-package name #:version version #:include-dev-deps? #t)) + (assoc-ref opts 'recursive-dev-dependencies) + #:allow-yanked? (assoc-ref opts 'allow-yanked)) + (crate->guix-package + name #:version version #:include-dev-deps? #t + #:allow-yanked? (assoc-ref opts 'allow-yanked))) ((or #f '()) (leave (G_ "failed to download meta-data for package '~a'~%") (if version diff --git a/tests/crate.scm b/tests/crate.scm index e779f738b3..ce2f08aade 100644 --- a/tests/crate.scm +++ b/tests/crate.scm @@ -28,6 +28,7 @@ (define-module (test-crate) #:use-module ((gcrypt hash) #:select ((sha256 . gcrypt-sha256))) #:use-module (guix packages) + #:use-module (guix read-print) #:use-module (guix tests) #:use-module (gnu packages) #:use-module (ice-9 iconv) @@ -42,6 +43,8 @@ (define-module (test-crate) ;; leaf-alice 0.7.5 ;; bar-1.0.0 ;; leaf-bob 3.0.1 +;; leaf-bob 3.0.2 (dev-dependency) +;; leaf-bob 4.0.0 (dev-dependency) ;; ;; root-1.0.0 ;; root-1.0.4 @@ -68,6 +71,8 @@ (define-module (test-crate) ;; leaf-alice-0.7.5 ;; ;; leaf-bob-3.0.1 +;; leaf-bob-3.0.2 (yanked) +;; leaf-bob-4.0.0 (yanked) (define test-foo-crate @@ -150,6 +155,16 @@ (define test-bar-dependencies \"crate_id\": \"leaf-bob\", \"kind\": \"normal\", \"req\": \"3.0.1\" + }, + { + \"crate_id\": \"leaf-bob\", + \"kind\": \"dev\", + \"req\": \"^3.0.2\" + }, + { + \"crate_id\": \"leaf-bob\", + \"kind\": \"dev\", + \"req\": \"^4.0.0\" } ] }") @@ -398,6 +413,22 @@ (define test-leaf-bob-crate \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.1/dependencies\" }, \"yanked\": false + }, + { \"id\": 234281, + \"num\": \"3.0.2\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/leaf-bob/3.0.2/dependencies\" + }, + \"yanked\": true + }, + { \"id\": 234282, + \"num\": \"4.0.0\", + \"license\": \"MIT OR Apache-2.0\", + \"links\": { + \"dependencies\": \"/api/v1/crates/leaf-bob/4.0.0/dependencies\" + }, + \"yanked\": true } ] } @@ -863,6 +894,18 @@ (define rust-leaf-bob-3 (description #f) (license #f))) +(define rust-leaf-bob-3.0.2-yanked + (package + (name "rust-leaf-bob") + (version "3.0.2") + (source #f) + (properties '((crate-version-yanked? . #t))) + (build-system #f) + (home-page #f) + (synopsis #f) + (description #f) + (license #f))) + (unless have-guile-semver? (test-skip 1)) (test-assert "crate-recursive-import-honors-existing-packages" (mock @@ -870,7 +913,7 @@ (define rust-leaf-bob-3 (lambda* (name #:optional version) (match name ("rust-leaf-bob" - (list rust-leaf-bob-3)) + (list rust-leaf-bob-3 rust-leaf-bob-3.0.2-yanked)) (_ '())))) (mock ((guix http-client) http-fetch @@ -894,8 +937,16 @@ (define rust-leaf-bob-3 (open-input-string "empty file\n")) ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/dependencies" (open-input-string test-leaf-bob-dependencies)) + ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/dependencies" + (open-input-string test-leaf-bob-dependencies)) (_ (error "Unexpected URL: " url))))) - (match (crate-recursive-import "bar") + (match (crate-recursive-import "bar" + #:allow-yanked? #t) (((define-public 'rust-bar-1 (package (name "rust-bar") @@ -913,7 +964,12 @@ (define rust-leaf-bob-3 (arguments ('quasiquote (#:cargo-inputs (("rust-leaf-bob" - ('unquote 'rust-leaf-bob-3)))))) + ('unquote 'rust-leaf-bob-3))) + #:cargo-development-inputs + (("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3.0.2-yanked)) + ("rust-leaf-bob" + ('unquote 'rust-leaf-bob-4.0.0-yanked)))))) (home-page "http://example.com") (synopsis "summary") (description "summary") @@ -922,4 +978,135 @@ (define rust-leaf-bob-3 (x (pk 'fail x #f)))))) +(unless have-guile-semver? (test-skip 1)) +(test-assert "crate-import-only-yanked-available" + (mock + ((guix http-client) http-fetch + (lambda (url . rest) + (match url + ("https://crates.io/api/v1/crates/bar" + (open-input-string test-bar-crate)) + ("https://crates.io/api/v1/crates/bar/1.0.0/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/bar/1.0.0/dependencies" + (open-input-string test-bar-dependencies)) + ("https://crates.io/api/v1/crates/leaf-bob" + (open-input-string test-leaf-bob-crate)) + ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/leaf-bob/3.0.1/dependencies" + (open-input-string test-leaf-bob-dependencies)) + ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/leaf-bob/3.0.2/dependencies" + (open-input-string test-leaf-bob-dependencies)) + ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/download" + (set! test-source-hash + (bytevector->nix-base32-string + (gcrypt-sha256 (string->bytevector "empty file\n" "utf-8")))) + (open-input-string "empty file\n")) + ("https://crates.io/api/v1/crates/leaf-bob/4.0.0/dependencies" + (open-input-string test-leaf-bob-dependencies)) + (_ (error "Unexpected URL: " url))))) + (match (crate-recursive-import "bar" + #:recursive-dev-dependencies? #t + #:allow-yanked? #t) + (((define-public 'rust-leaf-bob-4.0.0-yanked + (package + (name "rust-leaf-bob") + (version "4.0.0") + ($ "; This version was yanked!\n" #t) + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-bob" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (properties ('quote (('crate-version-yanked? . #t)))) + (build-system cargo-build-system) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-bob-3.0.2-yanked + (package + (name "rust-leaf-bob") + (version "3.0.2") + ($ "; This version was yanked!\n" #t) + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-bob" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (properties ('quote (('crate-version-yanked? . #t)))) + (build-system cargo-build-system) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-leaf-bob-3 + (package + (name "rust-leaf-bob") + (version "3.0.1") + (source + (origin + (method url-fetch) + (uri (crate-uri "leaf-bob" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0)))) + (define-public 'rust-bar-1 + (package + (name "rust-bar") + (version "1.0.0") + (source + (origin + (method url-fetch) + (uri (crate-uri "bar" version)) + (file-name + (string-append name "-" version ".tar.gz")) + (sha256 + (base32 + (? string? hash))))) + (build-system cargo-build-system) + (arguments + ('quasiquote (#:cargo-inputs + (("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3))) + #:cargo-development-inputs + (("rust-leaf-bob" + ('unquote 'rust-leaf-bob-3.0.2-yanked)) + ("rust-leaf-bob" + ('unquote 'rust-leaf-bob-4.0.0-yanked)))))) + (home-page "http://example.com") + (synopsis "summary") + (description "summary") + (license (list license:expat license:asl2.0))))) + #t) + (x + (pk 'fail (pretty-print-with-comments (current-output-port) x) #f))))) + (test-end "crate") -- cgit v1.2.3 From cd7763350ac3d4af3c37382f659c17d35ee43690 Mon Sep 17 00:00:00 2001 From: Nikolaos Chatzikonstantinou Date: Thu, 28 Dec 2023 17:20:28 -0500 Subject: doc: Fix typos and add readonly option to qemu invocation. * doc/guix.texi: Fix typos and add readonly option to qemu invocation. Signed-off-by: Mathieu Othacehe Change-Id: I7b686e8ff45532e96fe370f0f344977cdf218bbe --- doc/guix.texi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 395545bed7..811edd0bf7 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -2936,7 +2936,7 @@ Boot the USB installation image in an VM: qemu-system-x86_64 -m 1024 -smp 1 -enable-kvm \ -nic user,model=virtio-net-pci -boot menu=on,order=d \ -drive file=guix-system.img \ - -drive media=cdrom,file=guix-system-install-@value{VERSION}.@var{system}.iso + -drive media=cdrom,readonly=on,file=guix-system-install-@value{VERSION}.@var{system}.iso @end example @code{-enable-kvm} is optional, but significantly improves performance, @@ -17610,7 +17610,7 @@ mounted.}. @findex file-system-label File system labels are created using the @code{file-system-label} -procedure, UUIDs are created using @code{uuid}, and @file{/dev} node are +procedure, UUIDs are created using @code{uuid}, and @file{/dev} nodes are plain strings. Here's an example of a file system referred to by its label, as shown by the @command{e2label} command: @@ -43511,7 +43511,7 @@ utilizing the configuration mechanism described in the previous chapter (@pxref{Defining Services}), but for user's dotfiles and packages. It works both on Guix System and foreign distros and allows users to declare all the packages and services that should be installed and -configured for the user. Once a user has written a file containing +configured for the user. Once a user has written a file containing a @code{home-environment} record, such a configuration can be @dfn{instantiated} by an unprivileged user with the @command{guix home} command (@pxref{Invoking guix home}). @@ -43834,8 +43834,8 @@ be used here, too. Make sure that modules containing the specified packages are imported with @code{use-modules}. To find a package or information about its module use @command{guix search} (@pxref{Invoking guix package}). Alternatively, @code{specification->package} can be -used to get the package record from string without importing related -module. +used to get the package record from a string without importing its +related module. @end defvar There are few more essential services, but users are not expected to -- cgit v1.2.3 From d082312ef7adfea69c79d30ef947817b39832161 Mon Sep 17 00:00:00 2001 From: Tomas Volf Date: Thu, 11 Jan 2024 18:35:39 +0100 Subject: mapped-devices: Allow unlocking by a key file. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requiring the user to input their password in order to unlock a device is not always reasonable, so having an option to unlock the device using a key file is a nice quality of life change. * gnu/system/mapped-devices.scm (open-luks-device): Add #:key-file argument. (luks-device-mapping-with-options): New procedure. * doc/guix.texi (Mapped Devices): Describe the new procedure. Change-Id: I1de4e045f8c2c11f9a94f1656e839c785b0c11c4 Signed-off-by: Ludovic Courtès --- doc/guix.texi | 25 ++++++++++++++++ gnu/system/mapped-devices.scm | 67 +++++++++++++++++++++++++++---------------- 2 files changed, 67 insertions(+), 25 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index 811edd0bf7..c216d1b4a6 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -123,6 +123,7 @@ Copyright @copyright{} 2023 Foundation Devices, Inc.@* Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* Copyright @copyright{} 2023 Graham James Addis@* +Copyright @copyright{} 2023 Tomas Volf@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -17992,6 +17993,30 @@ command from the package with the same name. It relies on the @code{dm-crypt} Linux kernel module. @end defvar +@deffn {Procedure} luks-device-mapping-with-options [#:key-file] +Return a @code{luks-device-mapping} object, which defines LUKS block +device encryption using the @command{cryptsetup} command from the +package with the same name. It relies on the @code{dm-crypt} Linux +kernel module. + +If @code{key-file} is provided, unlocking is first attempted using that +key file. This has an advantage of not requiring a password entry, so +it can be used (for example) to unlock RAID arrays automatically on +boot. If key file unlock fails, password unlock is attempted as well. +Key file is not stored in the store and needs to be available at the +given location at the time of the unlock attempt. + +@lisp +;; Following definition would be equivalent to running: +;; cryptsetup open --key-file /crypto.key /dev/sdb1 data +(mapped-device + (source "/dev/sdb1) + (target "data) + (type (luks-device-mapping-with-options + #:key-file "/crypto.key"))) +@end lisp +@end deffn + @defvar raid-device-mapping This defines a RAID device, which is assembled using the @code{mdadm} command from the package with the same name. It requires a Linux kernel diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm index e6b8970c12..c19a818453 100644 --- a/gnu/system/mapped-devices.scm +++ b/gnu/system/mapped-devices.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2014-2022 Ludovic Courtès ;;; Copyright © 2016 Andreas Enge ;;; Copyright © 2017, 2018 Mark H Weaver +;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; ;;; This file is part of GNU Guix. ;;; @@ -64,6 +65,7 @@ (define-module (gnu system mapped-devices) check-device-initrd-modules ;XXX: needs a better place luks-device-mapping + luks-device-mapping-with-options raid-device-mapping lvm-device-mapping)) @@ -188,7 +190,7 @@ (define missing ;;; Common device mappings. ;;; -(define (open-luks-device source targets) +(define* (open-luks-device source targets #:key key-file) "Return a gexp that maps SOURCE to TARGET as a LUKS device, using 'cryptsetup'." (with-imported-modules (source-module-closure @@ -198,7 +200,8 @@ (define (open-luks-device source targets) ((target) #~(let ((source #$(if (uuid? source) (uuid-bytevector source) - source))) + source)) + (keyfile #$key-file)) ;; XXX: 'use-modules' should be at the top level. (use-modules (rnrs bytevectors) ;bytevector? ((gnu build file-systems) @@ -215,29 +218,35 @@ (define (open-luks-device source targets) ;; 'cryptsetup open' requires standard input to be a tty to allow ;; for interaction but shepherd sets standard input to /dev/null; ;; thus, explicitly request a tty. - (zero? (system*/tty - #$(file-append cryptsetup-static "/sbin/cryptsetup") - "open" "--type" "luks" - - ;; Note: We cannot use the "UUID=source" syntax here - ;; because 'cryptsetup' implements it by searching the - ;; udev-populated /dev/disk/by-id directory but udev may - ;; be unavailable at the time we run this. - (if (bytevector? source) - (or (let loop ((tries-left 10)) - (and (positive? tries-left) - (or (find-partition-by-luks-uuid source) - ;; If the underlying partition is - ;; not found, try again after - ;; waiting a second, up to ten - ;; times. FIXME: This should be - ;; dealt with in a more robust way. - (begin (sleep 1) - (loop (- tries-left 1)))))) - (error "LUKS partition not found" source)) - source) - - #$target))))))) + (let ((partition + ;; Note: We cannot use the "UUID=source" syntax here + ;; because 'cryptsetup' implements it by searching the + ;; udev-populated /dev/disk/by-id directory but udev may + ;; be unavailable at the time we run this. + (if (bytevector? source) + (or (let loop ((tries-left 10)) + (and (positive? tries-left) + (or (find-partition-by-luks-uuid source) + ;; If the underlying partition is + ;; not found, try again after + ;; waiting a second, up to ten + ;; times. FIXME: This should be + ;; dealt with in a more robust way. + (begin (sleep 1) + (loop (- tries-left 1)))))) + (error "LUKS partition not found" source)) + source))) + ;; We want to fallback to the password unlock if the keyfile fails. + (or (and keyfile + (zero? (system*/tty + #$(file-append cryptsetup-static "/sbin/cryptsetup") + "open" "--type" "luks" + "--key-file" keyfile + partition #$target))) + (zero? (system*/tty + #$(file-append cryptsetup-static "/sbin/cryptsetup") + "open" "--type" "luks" + partition #$target))))))))) (define (close-luks-device source targets) "Return a gexp that closes TARGET, a LUKS device." @@ -276,6 +285,14 @@ (define luks-device-mapping (close close-luks-device) (check check-luks-device))) +(define* (luks-device-mapping-with-options #:key key-file) + "Return a luks-device-mapping object with open modified to pass the arguments +into the open-luks-device procedure." + (mapped-device-kind + (inherit luks-device-mapping) + (open (λ (source targets) (open-luks-device source targets + #:key-file key-file))))) + (define (open-raid-device sources targets) "Return a gexp that assembles SOURCES (a list of devices) to the RAID device TARGET (e.g., \"/dev/md0\"), using 'mdadm'." -- cgit v1.2.3 From 086850e5b2b4a1744565fe83624d256524b64a49 Mon Sep 17 00:00:00 2001 From: Tomas Volf Date: Thu, 11 Jan 2024 18:35:40 +0100 Subject: bootloader: grub: Add support for loading an additional initrd. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to be able to provide decryption keys for the LUKS device, they need to be available in the initial ram disk. However they cannot be stored inside the usual initrd, since it is stored in the store and being a world-readable (as files in the store are) is not a desired property for a initrd containing decryption keys. This commit adds an option to load additional initrd during the boot, one that is not stored inside the store and therefore can contain secrets. Since only grub supports encrypted /boot, only grub is modified to use the extra-initrd. There is no use case for the other bootloaders. * doc/guix.texi (Bootloader Configuration): Describe the new extra-initrd field. * gnu/bootloader.scm (): Add extra-initrd field. * gnu/bootloader/grub.scm (make-grub-configuration): Use the extra-initrd field. Signed-off-by: Ludovic Courtès Change-Id: I995989bb623bb594ccdafbf4a1a6de941bd4189f --- doc/guix.texi | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ gnu/bootloader.scm | 6 +++++- gnu/bootloader/grub.scm | 7 +++++-- 3 files changed, 59 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index c216d1b4a6..a66005ee9d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41070,6 +41070,55 @@ This option in enabled by default. In some cases involving the @code{u-boot} bootloader, where the device tree has already been loaded in RAM, it can be handy to disable the option by setting it to @code{#f}. + +@item @code{extra-initrd} (default: @code{#f}) +File name of an additional initrd to load during the boot. It may or +may not point to a file in the store, but the main use case is for +out-of-store files containing secrets. + +In order to be able to provide decryption keys for the LUKS device, they +need to be available in the initial ram disk. However they cannot be +stored inside the usual initrd, since it is stored in the store and +being a world-readable (as files in the store are) is not a desired +property for a initrd containing decryption keys. You can therefore use +this field to instruct GRUB to also load a manually created initrd not +stored in the store. + +For any use case not involving secrets, you should use regular initrd +(@pxref{operating-system Reference, @code{initrd}}) instead. + +Suitable image can be created for example like this: + +@example +echo /key-file.bin | cpio -oH newc >/key-file.cpio +chmod 0000 /key-file.cpio +@end example + +After it is created, you can use it in this manner: + +@lisp +;; Operating system with encrypted boot partition +(operating-system + ... + (bootloader (bootloader-configuration + (bootloader grub-efi-bootloader) + (targets '("/boot/efi")) + ;; Load the initrd with a key file + (extra-initrd "/key-file.cpio"))) + (mapped-devices + (list (mapped-device + (source (uuid "12345678-1234-1234-1234-123456789abc")) + (target "my-root") + (type (luks-device-mapping-with-options + ;; And use it to unlock the root device + #:key-file "/key-file.bin")))))) +@end lisp + +Be careful when using this option, since pointing to a file that is not +readable by the grub while booting will cause the boot to fail and +require a manual edit of the initrd line in the grub menu. + +Currently only supported by GRUB. @end table @end deftp diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index ba06de7618..f32e90e79d 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2022 Josselin Poiret ;;; Copyright © 2022 Reza Alizadeh Majd +;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; ;;; This file is part of GNU Guix. ;;; @@ -77,6 +78,7 @@ (define-module (gnu bootloader) bootloader-configuration-serial-unit bootloader-configuration-serial-speed bootloader-configuration-device-tree-support? + bootloader-configuration-extra-initrd %bootloaders lookup-bootloader-by-name @@ -279,7 +281,9 @@ (define-record-type* (serial-speed bootloader-configuration-serial-speed (default #f)) ;integer | #f (device-tree-support? bootloader-configuration-device-tree-support? - (default #t))) ;boolean + (default #t)) ;boolean + (extra-initrd bootloader-configuration-extra-initrd + (default #f))) ;string | #f (define-deprecated (bootloader-configuration-target config) bootloader-configuration-targets diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm index 5f3fcd7074..2723eda5f4 100644 --- a/gnu/bootloader/grub.scm +++ b/gnu/bootloader/grub.scm @@ -9,6 +9,7 @@ ;;; Copyright © 2020 Stefan ;;; Copyright © 2022 Karl Hallsby ;;; Copyright © 2022 Denis 'GNUtoo' Carikli +;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; ;;; This file is part of GNU Guix. ;;; @@ -386,7 +387,8 @@ (define (menu-entry->gexp entry) store-directory-prefix)) (initrd (normalize-file (menu-entry-initrd entry) device-mount-point - store-directory-prefix))) + store-directory-prefix)) + (extra-initrd (bootloader-configuration-extra-initrd config))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for LINUX and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a @@ -397,11 +399,12 @@ (define (menu-entry->gexp entry) #~(format port "menuentry ~s { ~a linux ~a ~a - initrd ~a + initrd ~a ~a }~%" #$label #$(grub-root-search device linux) #$linux (string-join (list #$@arguments)) + (or #$extra-initrd "") #$initrd))) (multiboot-kernel (let* ((kernel (menu-entry-multiboot-kernel entry)) -- cgit v1.2.3 From cb3f833aaa5326e653b128bfd7b13d553f7c2a47 Mon Sep 17 00:00:00 2001 From: Efraim Flashner Date: Mon, 15 Jan 2024 12:15:46 +0200 Subject: doc: Fix mistakes in the manual. Recommended by Christian Miller. * doc/guix.texi (Packages with Multiple Outputs): Replace 'a packages' with 'a package'. (Invoking guix time-machine): Don't assume knowledge and give an explicit link to Back to the Future. (Invoking guix pack): Remove doubled word. (Build Systems): Same. (Debugging Build Failures): 'inspect' is not a command to be run. (Invoking guix import): Remove doubled word. (Invoking guix size): Remove stray word. (Invoking guix processes): Replace 'guix environment' with 'guix shell'. (Base Services): Add missing word. (Networking Setup): Adjust a/an usage. (Networking Services): Remove stray symbol. Add space between two words. (Desktop Services): Remove stray symbol from example. (Database Services): Document default postgresql version. (Web Services): Adjust indentation. (Audio Services): Add missing newline. (Miscellaneous Services): Switch 'get' to 'gets'. (Bootloader Configuration): Remove stray symbol. (Secure Shell): Remove marks around accepted values. (Installing Debugging Files): Replace 'is' with 'it'. (Full-Source Bootstrap): Remove doubled word. (Preparing to Use the Bootstrap Binaries): Same. Change-Id: Ifbf2677dff7642c6531384145363d7611286e48b --- doc/guix.texi | 64 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'doc') diff --git a/doc/guix.texi b/doc/guix.texi index a66005ee9d..ac17f91f7d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4355,7 +4355,7 @@ There are several such multiple-output packages in the GNU distribution. Other conventional output names include @code{lib} for libraries and possibly header files, @code{bin} for stand-alone programs, and @code{debug} for debugging information (@pxref{Installing Debugging -Files}). The outputs of a packages are listed in the third column of +Files}). The outputs of a package are listed in the third column of the output of @command{guix package --list-available} (@pxref{Invoking guix package}). @@ -5003,7 +5003,8 @@ environment} command to spawn an environment in a container running @command{guile} (@command{guix environment} has since been subsumed by @command{guix shell}; @pxref{Invoking guix shell}). It's like driving a DeLorean@footnote{If you don't know what a DeLorean is, consider -traveling back to the 1980's.}! The first @command{guix time-machine} +traveling back to the 1980's. (@uref{https://www.imdb.com/title/tt0088763/, +Back to the Future (1985)})}! The first @command{guix time-machine} invocation can be expensive: it may have to download or even build a large number of packages; the result is cached though and subsequent commands targeting the same commit are almost instantaneous. @@ -7162,7 +7163,7 @@ What if the recipient of your pack does not have root privileges on their machine, and thus cannot unpack it in the root file system? In that case, you will want to use the @option{--relocatable} option (see below). This option produces @dfn{relocatable binaries}, meaning they -they can be placed anywhere in the file system hierarchy: in the example +can be placed anywhere in the file system hierarchy: in the example above, users can unpack your tarball in their home directory and directly run @file{./opt/gnu/bin/guile}. @@ -10194,8 +10195,8 @@ It also generates font metrics (i.e., @file{.tfm} files) out of Metafont files whenever possible. Likewise, it can also create TeX formats (i.e., @file{.fmt} files) listed in the @code{#:create-formats} argument, and generate a symbolic link from @file{bin/} directory to any -script located in located in @file{texmf-dist/scripts/}, provided its -file name is listed in @code{#:link-scripts} argument. +script located in @file{texmf-dist/scripts/}, provided its file name is +listed in @code{#:link-scripts} argument. The build system adds @code{texlive-bin} from @code{(gnu packages tex)} to the native inputs. It can be overridden with the @@ -13916,8 +13917,8 @@ happen because the daemon runs builds in containers where, unlike in our environment above, network access is missing, @file{/bin/sh} does not exist, etc. (@pxref{Build Environment Setup}). -In such cases, you may need to run inspect the build process from within -a container similar to the one the build daemon creates: +In such cases, you may need to inspect the build process from within a +container similar to the one the build daemon creates: @example $ guix build -K foo @@ -14295,8 +14296,7 @@ should be checked closely. If Perl is available in the store, then the @code{corelist} utility will be used to filter core modules out of the list of dependencies. -The command command below imports metadata for the Acme::Boolean Perl -module: +The command below imports metadata for the Acme::Boolean Perl module: @example guix import cpan Acme::Boolean @@ -15689,7 +15689,7 @@ Coreutils}). When the given packages are @emph{not} in the store, @command{guix size} reports information based on the available substitutes -(@pxref{Substitutes}). This makes it possible it to profile disk usage of +(@pxref{Substitutes}). This makes it possible to profile the disk usage of store items that are not even on disk, only available remotely. You can also specify several package names: @@ -16793,7 +16793,7 @@ ChildCommand: guix offload x86_64-linux 7200 1 28800 @end example In this example we see that @command{guix-daemon} has three clients: -@command{guix environment}, @command{guix publish}, and the Cuirass continuous +@command{guix shell}, @command{guix publish}, and the Cuirass continuous integration tool; their process identifier (PID) is given by the @code{ClientPID} field. The @code{SessionPID} field gives the PID of the @command{guix-daemon} sub-process of this particular session. @@ -19956,7 +19956,7 @@ in users, including: Special variation of @code{pam-mount} to mount @code{XDG_RUNTIME_DIR} @end itemize -Here is example of switching from @code{mingetty-service-type} to +Here is an example of switching from @code{mingetty-service-type} to @code{greetd-service-type}, and how different terminals could be: @lisp @@ -20921,8 +20921,7 @@ package, which allows NetworkManager to manage VPNs @i{via} OpenVPN. This is the service type to run @url{https://01.org/connman,Connman}, a network connection manager. -Its value must be an -@code{connman-configuration} record as in this example: +Its value must be a @code{connman-configuration} record as in this example: @lisp (service connman-service-type @@ -21150,7 +21149,7 @@ The WiFi channel to use. @item @code{driver} (default: @code{"nl80211"}) The driver interface type. @code{"nl80211"} is used with all Linux mac80211 drivers. Use @code{"none"} if building hostapd as a standalone -RADIUS server that does # not control any wireless/wired driver. +RADIUS server that does not control any wireless/wired driver. @item @code{extra-settings} (default: @code{""}) Extra settings to append as-is to the hostapd configuration file. See @@ -22412,7 +22411,7 @@ private keys in it}. See the output of @code{yggdrasil -genconf} for a quick overview of valid keys and their default values. @item @code{autoconf?} (default: @code{#f}) -Whether to use automatic mode. Enabling it makes Yggdrasil use adynamic IP +Whether to use automatic mode. Enabling it makes Yggdrasil use a dynamic IP and peer with IPv6 neighbors. @item @code{log-level} (default: @code{'info}) @@ -24926,7 +24925,7 @@ List of possible UUIDs: @code{671b10b5-42c0-4696-9227-eb28d1b049d6}: BlueZ Experimental Simultaneous Central and Peripheral, @item -@code{"15c0a148-c273-11ea-b3de-0242ac130004}: BlueZ Experimental LL privacy, +@code{15c0a148-c273-11ea-b3de-0242ac130004}: BlueZ Experimental LL privacy, @item @code{330859bc-7506-492d-9370-9a6f0614037f}: BlueZ Experimental Bluetooth Quality Report, @@ -25588,7 +25587,7 @@ Data type representing the configuration for the @code{postgresql-service-type}. @table @asis -@item @code{postgresql} +@item @code{postgresql} (default: @code{postgresql-10}) PostgreSQL package to use for the service. @item @code{port} (default: @code{5432}) @@ -31071,7 +31070,7 @@ the configuration. (httpd-virtualhost "*:80" (list (string-join '("ServerName www.example.com" - "DocumentRoot /srv/http/www.example.com") + "DocumentRoot /srv/http/www.example.com") "\n"))))) @end lisp @end defvar @@ -35149,6 +35148,7 @@ Owner of the @command{mympd} process. 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. @@ -40258,7 +40258,7 @@ Backend to use to detect changes in the @code{log-path}. The default is @file{/etc/fail2ban/jail.conf} file of the @code{fail2ban} package. @item @code{max-retry} (type: maybe-integer) -The number of failures before a host get banned (e.g. @code{(max-retry +The number of failures before a host gets banned (e.g. @code{(max-retry 5)}). @item @code{max-matches} (type: maybe-integer) @@ -41219,7 +41219,7 @@ Of course, these options can be combined: '("console=com0" "noide") @end lisp -+@item @code{multiboot-modules} (default: @code{'()}) +@item @code{multiboot-modules} (default: @code{'()}) The list of commands for loading Multiboot modules. For example: @lisp @@ -44638,19 +44638,19 @@ running on this machine, then it @emph{may} take this file into account: this is what @command{sshd} does by default, but be aware that it can also be configured to ignore it. -@item @code{add-keys-to-agent} (default: @code{``no''}) +@item @code{add-keys-to-agent} (default: @code{no}) This string specifies whether keys should be automatically added to a -running ssh-agent. If this option is set to @code{``yes''} and a key is +running ssh-agent. If this option is set to @code{yes} and a key is loaded from a file, the key and its passphrase are added to the agent with the default lifetime, as if by @code{ssh-add}. If this option is -set to @code{``ask''}, @code{ssh} will require confirmation. If this -option is set to @code{``confirm''}, each use of the key must be -confirmed. If this option is set to @code{``no''}, no keys are added to +set to @code{ask}, @code{ssh} will require confirmation. If this +option is set to @code{confirm}, each use of the key must be +confirmed. If this option is set to @code{no}, no keys are added to the agent. Alternately, this option may be specified as a time interval to specify the key's lifetime in @code{ssh-agent}, after which it will -automatically be removed. The argument must be @code{``no''}, -@code{``yes''}, @code{``confirm''} (optionally followed by a time -interval), @code{``ask''} or a time interval. +automatically be removed. The argument must be @code{no}, +@code{yes}, @code{confirm} (optionally followed by a time +interval), @code{ask} or a time interval. @end table @end deftp @@ -46726,7 +46726,7 @@ missing. @node Separate Debug Info @section Separate Debug Info -The problem with debugging information is that is takes up a fair amount +The problem with debugging information is that it takes up a fair amount of disk space. For example, debugging information for the GNU C Library weighs in at more than 60 MiB@. Thus, as a user, keeping all the debugging info of all the installed programs is usually not an option. @@ -47209,7 +47209,7 @@ traditional bootstrap of the rest of the Guix System. @c ./pre-inst-env guix graph -e '(@@ (gnu packages commencement) gcc-core-mesboot0)' | sed -re 's,((bootstrap-seeds|guile-bootstrap).*shape =) box,\1 ellipse,' > doc/images/gcc-core-mesboot0-graph.dot @image{images/gcc-core-mesboot0-graph,6in,,Dependency graph of gcc-core-mesboot0} -Work is ongoing to to bring these bootstraps to the @code{arm-linux} and +Work is ongoing to bring these bootstraps to the @code{arm-linux} and @code{aarch64-linux} architectures and to the Hurd. If you are interested, join us on @samp{#bootstrappable} on the Libera.Chat @@ -47380,7 +47380,7 @@ bootstrap GCC with a sequence of assemblers, interpreters, and compilers of increasing complexity, which could be built from source starting from a simple and auditable assembler. -Our first major achievement is the replacement of of GCC, the GNU C Library +Our first major achievement is the replacement of GCC, the GNU C Library and Binutils by MesCC-Tools (a simple hex linker and macro assembler) and Mes (@pxref{Top, GNU Mes Reference Manual,, mes, GNU Mes}, a Scheme interpreter and C compiler in Scheme). Neither MesCC-Tools nor Mes can be fully -- cgit v1.2.3