* [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data. @ 2024-09-12 16:58 Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (3 more replies) 0 siblings, 4 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-12 16:58 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> Looking up bootloaders by name is broken because (extlinux) bootloaders share a name. Also, bootloader-configuration data is significant to bootloader installation, so it shouldn't just use the default values. Installation can rely on the provenance service instead, which should be present for the vast majority of systems. * guix/scripts/system.scm (install-bootloader-from-os, install-bootloader-from-provenance): Add procedures. (reinstall-bootloader): Remove procedure. (switch-to-system-generation, process-command): Use install-bootloader-from-provenance. Change-Id: I5713a43ad4f9f32a129d980db06d70de16b03f27 --- Hello, This requires patches from #69343. #72457 is big and I thought it would be nice to separately review whatever possible, hence the new issue. This is [PATCH v5 01/15] from issue #72457, but with a modified commit description and the addition of an install-bootloader-from-os procedure, to reduce nesting and only define local variables when relevant. The (gnu tests reconfigure) tests all pass, though I myself cannot roll-back or switch-generations for unrelated reasons. So please let me know if this patch creates any trouble with the aformentioned and if you have ideas for additional (gnu tests reconfigure) tests. Thanks, Herman gnu/bootloader.scm | 2 ++ guix/scripts/system.scm | 72 +++++++++++++++-------------------------- 2 files changed, 28 insertions(+), 46 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index f32e90e79d..61311b32cb 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -7,6 +7,8 @@ ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> ;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org> ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 0f7d864e06..d14dfd8d81 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -88,6 +88,7 @@ (define-module (guix scripts system) #:use-module (srfi srfi-37) #:use-module (ice-9 format) #:use-module (ice-9 match) + #:use-module (ice-9 receive) #:use-module (rnrs bytevectors) #:export (guix-system read-operating-system @@ -377,61 +378,39 @@ (define (switch-to-system-generation store spec) (activate (string-append generation "/activate"))) (if number (begin - (reinstall-bootloader store number) + (install-bootloader-from-provenance store number) (switch-to-generation* %system-profile number) (unless-file-not-found (primitive-load activate))) (leave (G_ "cannot switch to system generation '~a'~%") spec)))) -(define* (system-bootloader-name #:optional (system %system-profile)) - "Return the bootloader name stored in SYSTEM's \"parameters\" file." - (let ((params (unless-file-not-found - (read-boot-parameters-file system)))) - (boot-parameters-bootloader-name params))) - -(define (reinstall-bootloader store number) - "Re-install bootloader for existing system profile generation NUMBER. -STORE is an open connection to the store." - (let* ((generation (generation-file-name %system-profile number)) - ;; Detect the bootloader used in %system-profile. - (bootloader (lookup-bootloader-by-name (system-bootloader-name))) - - ;; Use the detected bootloader with default configuration. - ;; It will be enough to allow the system to boot. - (bootloader-config (bootloader-configuration - (bootloader bootloader))) - - ;; Make the specified system generation the default entry. - (chosen-alternative (generation->boot-alternative - %system-profile number)) - (params (boot-alternative-parameters chosen-alternative)) - (locale (boot-parameters-locale params)) - (store-crypto-devices (boot-parameters-store-crypto-devices params)) - (store-directory-prefix - (boot-parameters-store-directory-prefix params)) - (old-generations - (delv number (reverse (generation-numbers %system-profile)))) - (previous-boot-alternatives (profile->boot-alternatives - %system-profile old-generations)) - (entries (list (boot-parameters->menu-entry params))) - (old-entries (map boot-parameters->menu-entry - (map boot-alternative-parameters - previous-boot-alternatives)))) +(define (install-bootloader-from-os store number os) + "Re-install an old bootloader defined in <operating-system> record OS, +for system profile generation NUMBER, with store STORE." + (let* ((os (read-operating-system os)) + (bootloader-config (operating-system-bootloader os)) + (numbers (generation-numbers %system-profile)) + (numbers (delv number (reverse numbers))) + (old (profile->boot-alternatives %system-profile numbers)) + (bootcfg (operating-system-bootcfg os old))) (run-with-store store - (mlet* %store-monad - ((bootcfg (lower-object - ((bootloader-configuration-file-generator bootloader) - bootloader-config entries - #:locale locale - #:store-crypto-devices store-crypto-devices - #:store-directory-prefix store-directory-prefix - #:old-entries old-entries))) - (drvs -> (list bootcfg))) + (mlet* %store-monad ((bootcfg (lower-object bootcfg)) + (drvs -> (list bootcfg))) (mbegin %store-monad (built-derivations drvs) ;; Only install bootloader configuration file. (install-bootloader local-eval bootloader-config bootcfg #:run-installer? #f)))))) +(define (install-bootloader-from-provenance store number) + "Re-install an old bootloader using provenance data for system profile +generation NUMBER with store STORE." + (receive (_ os) + (system-provenance (generation-file-name %system-profile number)) + (if os + (install-bootloader-from-os store number os) + (leave (G_ "cannot rollback to generation '~a': no provenance~%") + number)))) + \f ;;; ;;; Graphs. @@ -1413,10 +1392,11 @@ (define-syntax-rule (with-store* store exp ...) (let ((pattern (match args (() #f) ((pattern) pattern) - (x (leave (G_ "wrong number of arguments~%")))))) + (_ (leave (G_ "wrong number of arguments~%"))))) + (number (generation-number %system-profile))) (with-store* store (delete-matching-generations store %system-profile pattern) - (reinstall-bootloader store (generation-number %system-profile))))) + (install-bootloader-from-provenance store number)))) ((switch-generation) (let ((pattern (match args ((pattern) pattern) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite. 2024-09-12 16:58 [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 01/15] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (14 more replies) 2024-09-21 10:57 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (2 subsequent siblings) 3 siblings, 15 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Hello, Patch #1 is now patch #5. This patches series adds the procedures, macros and record used in #72457. I am not sure how to test these on their own. Feel free to write some small tests, if you think of any. If I failed to described a change or did it poorly, please let me know. Patch #11 and patches with fewer changes can be merged out of order. Yesterday I had trouble using control@debbugs.gnu.org to block one issue on another. So if you could make this issue block on #69343, and #72457 block on this, I would appreciate that. Cheers, Herman Herman Rimm (3): guix: utils: Add flatten and flat-map from haunt. guix: records: Add wrap-element procedure. gnu: bootloader: Match records outside the module. Lilah Tascheter (12): gnu: bootloader: Remove deprecated bootloader-configuration field. gnu: system: Remove useless boot parameters. gnu: tests: reconfigure: Remove bootloader install test. guix: scripts: Remove unused code. guix: scripts: Rewrite reinstall-bootloader to use provenance data. gnu: bootloader: Add bootloader-target record and infastructure. gnu: bootloader: Add bootloader-configurations->gexp. gnu: bootloader: Add device-subvol field to menu-entry record. gnu: build: bootloader: Add efi-bootnums procedure. gnu: bootloader: Install any bootloader to ESP. gnu: system: boot: Add procedure. teams: Add bootloading team. doc/guix.texi | 34 +-- etc/teams.scm | 10 + gnu/bootloader.scm | 504 +++++++++++++++++++++++++++++++++----- gnu/build/bootloader.scm | 161 +++++++----- gnu/build/image.scm | 23 +- gnu/image.scm | 4 + gnu/system.scm | 7 - gnu/system/boot.scm | 14 +- gnu/system/image.scm | 22 +- gnu/tests/reconfigure.scm | 86 +------ guix/records.scm | 7 + guix/scripts/system.scm | 96 +++----- guix/ui.scm | 9 + guix/utils.scm | 26 ++ tests/boot-parameters.scm | 18 +- 15 files changed, 677 insertions(+), 344 deletions(-) base-commit: 9292d35ab63055e3752e698710a1a408cc7de7fd -- 2.45.2 ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 01/15] gnu: bootloader: Remove deprecated bootloader-configuration field. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 02/15] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via ` (13 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (warn-target-field-deprecation): Delete sanitizer. (bootloader-configuration)[target]: Remove deprecated field. (bootloader-configuration-target): Delete procedure. (bootloader-configuration-targets): Do not use target field. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index f32e90e79d..865521e6e5 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -66,7 +66,6 @@ (define-module (gnu bootloader) bootloader-configuration bootloader-configuration? bootloader-configuration-bootloader - bootloader-configuration-target ;deprecated bootloader-configuration-targets bootloader-configuration-menu-entries bootloader-configuration-default-entry @@ -244,24 +243,14 @@ (define-record-type* <bootloader> ;; The <bootloader-configuration> record contains bootloader independant ;; configuration used to fill bootloader configuration file. -(define-with-syntax-properties (warn-target-field-deprecation - (value properties)) - (when value - (warning (source-properties->location properties) - (G_ "the 'target' field is deprecated, please use 'targets' \ -instead~%"))) - value) (define-record-type* <bootloader-configuration> bootloader-configuration make-bootloader-configuration bootloader-configuration? (bootloader - bootloader-configuration-bootloader) ;<bootloader> + bootloader-configuration-bootloader) ;<bootloader> (targets %bootloader-configuration-targets (default #f)) ;list of strings - (target %bootloader-configuration-target ;deprecated - (default #f) - (sanitize warn-target-field-deprecation)) (menu-entries bootloader-configuration-menu-entries (default '())) ;list of <menu-entry> (default-entry bootloader-configuration-default-entry @@ -285,14 +274,9 @@ (define-record-type* <bootloader-configuration> (extra-initrd bootloader-configuration-extra-initrd (default #f))) ;string | #f -(define-deprecated (bootloader-configuration-target config) - bootloader-configuration-targets - (%bootloader-configuration-target config)) (define (bootloader-configuration-targets config) (or (%bootloader-configuration-targets config) - ;; TODO: Remove after the deprecated 'target' field is removed. - (list (%bootloader-configuration-target config)) ;; XXX: At least the GRUB installer (see (gnu bootloader grub)) has this ;; peculiar behavior of installing fonts and GRUB modules when DEVICE is #f, ;; hence the default value of '(#f) rather than '(). -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 02/15] gnu: system: Remove useless boot parameters. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 01/15] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 03/15] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via ` (12 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/system.scm (operating-system-boot-parameters, operating-system-boot-parameters-file): Delete bootloader-menu-entries. * gnu/system/boot.scm (boot-parameters)[bootloader-menu-entries]: Delete field. (read-boot-parameters): Don't read bootloader-menu-entries. * tests/boot-parameters.scm (%grub-boot-parameters, test-read-boot-parameters, test-read-boot-parameters): Don't include bootloader-menu-entries. ("read, bootloader-menu-entries, default value"): Delete test. Change-Id: I46d9cff4604dbfcf654b0820fdb77e72aecffbb4 --- gnu/system.scm | 7 ------- gnu/system/boot.scm | 8 -------- tests/boot-parameters.scm | 18 +++++------------- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/gnu/system.scm b/gnu/system.scm index 25afa96295..a3eee5aa24 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -1298,8 +1298,6 @@ (define* (operating-system-boot-parameters os root-device (initrd initrd) (multiboot-modules multiboot-modules) (bootloader-name bootloader-name) - (bootloader-menu-entries - (bootloader-configuration-menu-entries (operating-system-bootloader os))) (locale locale) (store-device (ensure-not-/dev (file-system-device store))) (store-directory-prefix (btrfs-store-subvolume-file-name file-systems)) @@ -1341,11 +1339,6 @@ (define* (operating-system-boot-parameters-file os) #$(boot-parameters-multiboot-modules params))) #~()) (bootloader-name #$(boot-parameters-bootloader-name params)) - (bootloader-menu-entries - #$(map menu-entry->sexp - (or (and=> (operating-system-bootloader os) - bootloader-configuration-menu-entries) - '()))) (locale #$(boot-parameters-locale params)) (store (device diff --git a/gnu/system/boot.scm b/gnu/system/boot.scm index 833caef496..a898ab9549 100644 --- a/gnu/system/boot.scm +++ b/gnu/system/boot.scm @@ -54,7 +54,6 @@ (define-module (gnu system boot) boot-parameters-label boot-parameters-root-device boot-parameters-bootloader-name - boot-parameters-bootloader-menu-entries boot-parameters-store-crypto-devices boot-parameters-store-device boot-parameters-store-directory-prefix @@ -112,8 +111,6 @@ (define-record-type* <boot-parameters> ;; partition. (root-device boot-parameters-root-device) (bootloader-name boot-parameters-bootloader-name) - (bootloader-menu-entries ;list of <menu-entry> - boot-parameters-bootloader-menu-entries) (store-device boot-parameters-store-device) (store-mount-point boot-parameters-store-mount-point) (store-directory-prefix boot-parameters-store-directory-prefix) @@ -174,11 +171,6 @@ (define (read-boot-parameters port) ((_ args) args) (#f 'grub))) ; for compatibility reasons. - (bootloader-menu-entries - (match (assq 'bootloader-menu-entries rest) - ((_ entries) (map sexp->menu-entry entries)) - (#f '()))) - ;; In the past, we would store the directory name of linux instead of ;; the absolute file name of its image. Detect that and correct it. (kernel (if (string=? kernel (direct-store-path kernel)) diff --git a/tests/boot-parameters.scm b/tests/boot-parameters.scm index 2e7976aa6c..e1dc4620c3 100644 --- a/tests/boot-parameters.scm +++ b/tests/boot-parameters.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2019, 2020 Miguel Ángel Arruga Vivas <rosen644835@gmail.com> ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -34,6 +35,7 @@ (define-module (test-boot-parameters) #:use-module (guix gexp) #:use-module (guix store) #:use-module (guix tests) + #:use-module (ice-9 format) #:use-module (srfi srfi-34) #:use-module (srfi srfi-64) #:use-module (rnrs bytevectors)) @@ -64,7 +66,6 @@ (define %root-path "/") (define %grub-boot-parameters (boot-parameters (bootloader-name 'grub) - (bootloader-menu-entries '()) (root-device %default-root-device) (label %default-label) (kernel %default-kernel) @@ -107,7 +108,6 @@ (define* (test-read-boot-parameters #:key (version %boot-parameters-version) (bootloader-name 'grub) - (bootloader-menu-entries '()) (label %default-label) (root-device (quote-uuid %default-root-device)) (kernel %default-kernel) @@ -127,7 +127,7 @@ (define* (test-read-boot-parameters (cond ((eq? 'false val) (format #false fmt #false)) (val (format #false fmt val)) (else ""))) - (format #false "(boot-parameters~a~a~a~a~a~a~a~a~a~a)" + (format #f "(boot-parameters~@{~a~})" (sexp-or-nothing " (version ~S)" version) (sexp-or-nothing " (label ~S)" label) (sexp-or-nothing " (root-device ~S)" root-device) @@ -135,7 +135,7 @@ (define* (test-read-boot-parameters (sexp-or-nothing " (kernel-arguments ~S)" kernel-arguments) (sexp-or-nothing " (initrd ~S)" initrd) (if with-store - (format #false " (store~a~a~a~a)" + (format #f " (store~@{~a~})" (sexp-or-nothing " (device ~S)" store-device) (sexp-or-nothing " (mount-point ~S)" store-mount-point) @@ -145,9 +145,7 @@ (define* (test-read-boot-parameters store-crypto-devices)) "") (sexp-or-nothing " (locale ~S)" locale) - (sexp-or-nothing " (bootloader-name ~a)" bootloader-name) - (sexp-or-nothing " (bootloader-menu-entries ~S)" - bootloader-menu-entries))) + (sexp-or-nothing " (bootloader-name ~a)" bootloader-name))) (let ((str (generate-boot-parameters))) (call-with-input-string str read-boot-parameters))) @@ -170,7 +168,6 @@ (define* (test-read-boot-parameters (test-assert "read, construction, optional fields" (and (test-read-boot-parameters #:bootloader-name #false) - (test-read-boot-parameters #:bootloader-menu-entries #false) (test-read-boot-parameters #:kernel-arguments #false) (test-read-boot-parameters #:with-store #false) (test-read-boot-parameters #:store-device #false) @@ -223,11 +220,6 @@ (define* (test-read-boot-parameters (boot-parameters-bootloader-name (test-read-boot-parameters #:bootloader-name #false))) -(test-eq "read, bootloader-menu-entries, default value" - '() - (boot-parameters-bootloader-menu-entries - (test-read-boot-parameters #:bootloader-menu-entries #false))) - (test-eq "read, kernel-arguments, default value" '() (boot-parameters-kernel-arguments -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 03/15] gnu: tests: reconfigure: Remove bootloader install test. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 01/15] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 02/15] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 04/15] guix: scripts: Remove unused code Herman Rimm via Guix-patches via ` (11 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/tests/reconfigure.scm (%test-install-bootloader): Delete variable. (run-install-bootloader-test): Delete procedure. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/tests/reconfigure.scm | 86 +-------------------------------------- 1 file changed, 1 insertion(+), 85 deletions(-) diff --git a/gnu/tests/reconfigure.scm b/gnu/tests/reconfigure.scm index bcc7645fa3..8aa5311171 100644 --- a/gnu/tests/reconfigure.scm +++ b/gnu/tests/reconfigure.scm @@ -30,8 +30,7 @@ (define-module (gnu tests reconfigure) #:use-module (guix scripts system reconfigure) #:use-module (guix store) #:export (%test-switch-to-system - %test-upgrade-services - %test-install-bootloader)) + %test-upgrade-services)) ;;; Commentary: ;;; @@ -178,83 +177,6 @@ (define* (run-upgrade-services-test) (disable (upgrade-services-program '() '() '(dummy) '()))) (test enable disable)))) -(define* (run-install-bootloader-test) - "Run a test of an OS running INSTALL-BOOTLOADER-PROGRAM, which installs a -bootloader's configuration file." - (define os - (marionette-operating-system - (simple-operating-system) - #:imported-modules '((gnu services herd) - (guix combinators)))) - - (define vm (virtual-machine - (operating-system os) - (volatile? #f))) - - (define (test script) - (with-imported-modules '((gnu build marionette)) - #~(begin - (use-modules (gnu build marionette) - (ice-9 regex) - (srfi srfi-1) - (srfi srfi-64)) - - (define marionette - (make-marionette (list #$vm))) - - ;; Return the system generation paths that have GRUB menu entries. - (define (generations-in-grub-cfg marionette) - (let ((grub-cfg (marionette-eval - '(begin - (use-modules (rnrs io ports)) - (call-with-input-file "/boot/grub/grub.cfg" - get-string-all)) - marionette))) - (map (lambda (parameter) - (second (string-split (match:substring parameter) #\=))) - (list-matches "system=[^ ]*" grub-cfg)))) - - (test-runner-current (system-test-runner #$output)) - (test-begin "install-bootloader") - - (test-assert "no prior menu entry for system generation" - (not (member #$os (generations-in-grub-cfg marionette)))) - - (test-assert "script successfully evaluated" - (marionette-eval - '(primitive-load #$script) - marionette)) - - (test-assert "menu entry created for system generation" - (member #$os (generations-in-grub-cfg marionette))) - - (test-end)))) - - (let* ((bootloader ((compose bootloader-configuration-bootloader - operating-system-bootloader) - os)) - ;; The typical use-case for 'install-bootloader-program' is to read - ;; the boot parameters for the existing menu entries on the system, - ;; parse them with 'boot-parameters->menu-entry', and pass the - ;; results to 'operating-system-bootcfg'. However, to obtain boot - ;; parameters, we would need to start the marionette, which we should - ;; ideally avoid doing outside of the 'test' G-Expression. Thus, we - ;; generate a bootloader configuration for the script as if there - ;; were no existing menu entries. In the grand scheme of things, this - ;; matters little -- these tests should not make assertions about the - ;; behavior of 'operating-system-bootcfg'. - (bootcfg (operating-system-bootcfg os '())) - (bootcfg-file (bootloader-configuration-file bootloader))) - (gexp->derivation - "install-bootloader" - ;; Due to the read-only nature of the virtual machines used in the system - ;; test suite, the bootloader installer script is omitted. 'grub-install' - ;; would attempt to write directly to the virtual disk if the - ;; installation script were run. - (test - (install-bootloader-program #f #f #f bootcfg bootcfg-file '(#f) "/"))))) - - (define %test-switch-to-system (system-test (name "switch-to-system") @@ -267,9 +189,3 @@ (define %test-upgrade-services (description "Upgrade the Shepherd by unloading obsolete services and loading new services.") (value (run-upgrade-services-test)))) - -(define %test-install-bootloader - (system-test - (name "install-bootloader") - (description "Install a bootloader and its configuration file.") - (value (run-install-bootloader-test)))) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 04/15] guix: scripts: Remove unused code. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (2 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 03/15] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 05/15] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via ` (10 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> * guix/scripts/system.scm (bootloader-installer-script): Delete. Change-Id: Ic1e0a523c814e4f1bf44b2721f5658f00066b0ab --- guix/scripts/system.scm | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 0f7d864e06..83a4de39d0 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -757,28 +757,6 @@ (define (maybe-suggest-running-guix-pull) (warning (G_ "Consider running 'guix pull' before 'reconfigure'.~%")) (warning (G_ "Failing to do that may downgrade your system!~%")))) -(define (bootloader-installer-script installer - bootloader device target) - "Return a file calling INSTALLER gexp with given BOOTLOADER, DEVICE -and TARGET arguments." - (scheme-file "bootloader-installer" - (with-imported-modules '((gnu build bootloader) - (guix build utils)) - #~(begin - (use-modules (gnu build bootloader) - (guix build utils) - (ice-9 binary-ports) - (srfi srfi-34) - (srfi srfi-35)) - - (guard (c ((message-condition? c) ;XXX: i18n - (format (current-error-port) "error: ~a~%" - (condition-message c)) - (exit 1))) - (#$installer #$bootloader #$device #$target) - (info (G_ "bootloader successfully installed on '~a'~%") - #$device)))))) - (define (local-eval exp) "Evaluate EXP, a G-Expression, in-place." (mlet* %store-monad ((lowered (lower-gexp exp)) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 05/15] guix: scripts: Rewrite reinstall-bootloader to use provenance data. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (3 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 04/15] guix: scripts: Remove unused code Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 06/15] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via ` (9 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> Looking up bootloaders by name is broken because (extlinux) bootloaders share a name. Also, bootloader-configuration data is significant to bootloader installation, so it shouldn't just use the default values. Installation can rely on the provenance service instead, which should be present for the vast majority of systems. * gnu/bootloader.scm (%bootloaders): Delete variable. (lookup-bootloader-by-name, bootloader-modules): Delete procedures. * guix/scripts/system.scm (install-bootloader-from-os, install-bootloader-from-provenance): Add procedures. (reinstall-bootloader): Remove procedure. (switch-to-system-generation, process-command): Use install-bootloader-from-provenance. Change-Id: I5713a43ad4f9f32a129d980db06d70de16b03f27 --- gnu/bootloader.scm | 26 --------------- guix/scripts/system.scm | 74 ++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 72 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 865521e6e5..3ea50a4004 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -26,7 +26,6 @@ (define-module (gnu bootloader) #:use-module (gnu system file-systems) #:use-module (gnu system uuid) - #:use-module (guix discovery) #:use-module (guix gexp) #:use-module (guix profiles) #:use-module (guix records) @@ -79,8 +78,6 @@ (define-module (gnu bootloader) bootloader-configuration-device-tree-support? bootloader-configuration-extra-initrd - %bootloaders - lookup-bootloader-by-name efi-bootloader-chain)) @@ -287,29 +284,6 @@ (define (bootloader-configuration-targets config) ;;; Bootloaders. ;;; -(define (bootloader-modules) - "Return the list of bootloader modules." - (all-modules (map (lambda (entry) - `(,entry . "gnu/bootloader")) - %load-path) - #:warn warn-about-load-error)) - -(define %bootloaders - ;; The list of publically-known bootloaders. - (delay (fold-module-public-variables (lambda (obj result) - (if (bootloader? obj) - (cons obj result) - result)) - '() - (bootloader-modules)))) - -(define (lookup-bootloader-by-name name) - "Return the bootloader called NAME." - (or (find (lambda (bootloader) - (eq? name (bootloader-name bootloader))) - (force %bootloaders)) - (leave (G_ "~a: no such bootloader~%") name))) - (define (efi-bootloader-profile packages files hooks) "Creates a profile from the lists of PACKAGES and FILES from the store. This profile is meant to be used by the bootloader-installer. diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 83a4de39d0..d23f9153e5 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -11,6 +11,8 @@ ;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re> ;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2022 Tobias Geerinckx-Rice <me@tobias.gr> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -88,6 +90,7 @@ (define-module (guix scripts system) #:use-module (srfi srfi-37) #:use-module (ice-9 format) #:use-module (ice-9 match) + #:use-module (ice-9 receive) #:use-module (rnrs bytevectors) #:export (guix-system read-operating-system @@ -377,61 +380,39 @@ (define (switch-to-system-generation store spec) (activate (string-append generation "/activate"))) (if number (begin - (reinstall-bootloader store number) + (install-bootloader-from-provenance store number) (switch-to-generation* %system-profile number) (unless-file-not-found (primitive-load activate))) (leave (G_ "cannot switch to system generation '~a'~%") spec)))) -(define* (system-bootloader-name #:optional (system %system-profile)) - "Return the bootloader name stored in SYSTEM's \"parameters\" file." - (let ((params (unless-file-not-found - (read-boot-parameters-file system)))) - (boot-parameters-bootloader-name params))) - -(define (reinstall-bootloader store number) - "Re-install bootloader for existing system profile generation NUMBER. -STORE is an open connection to the store." - (let* ((generation (generation-file-name %system-profile number)) - ;; Detect the bootloader used in %system-profile. - (bootloader (lookup-bootloader-by-name (system-bootloader-name))) - - ;; Use the detected bootloader with default configuration. - ;; It will be enough to allow the system to boot. - (bootloader-config (bootloader-configuration - (bootloader bootloader))) - - ;; Make the specified system generation the default entry. - (chosen-alternative (generation->boot-alternative - %system-profile number)) - (params (boot-alternative-parameters chosen-alternative)) - (locale (boot-parameters-locale params)) - (store-crypto-devices (boot-parameters-store-crypto-devices params)) - (store-directory-prefix - (boot-parameters-store-directory-prefix params)) - (old-generations - (delv number (reverse (generation-numbers %system-profile)))) - (previous-boot-alternatives (profile->boot-alternatives - %system-profile old-generations)) - (entries (list (boot-parameters->menu-entry params))) - (old-entries (map boot-parameters->menu-entry - (map boot-alternative-parameters - previous-boot-alternatives)))) +(define (install-bootloader-from-os store number os) + "Re-install an old bootloader defined in <operating-system> record OS, +for system profile generation NUMBER, with store STORE." + (let* ((os (read-operating-system os)) + (bootloader-config (operating-system-bootloader os)) + (numbers (generation-numbers %system-profile)) + (numbers (delv number (reverse numbers))) + (old (profile->boot-alternatives %system-profile numbers)) + (bootcfg (operating-system-bootcfg os old))) (run-with-store store - (mlet* %store-monad - ((bootcfg (lower-object - ((bootloader-configuration-file-generator bootloader) - bootloader-config entries - #:locale locale - #:store-crypto-devices store-crypto-devices - #:store-directory-prefix store-directory-prefix - #:old-entries old-entries))) - (drvs -> (list bootcfg))) + (mlet* %store-monad ((bootcfg (lower-object bootcfg)) + (drvs -> (list bootcfg))) (mbegin %store-monad (built-derivations drvs) ;; Only install bootloader configuration file. (install-bootloader local-eval bootloader-config bootcfg #:run-installer? #f)))))) +(define (install-bootloader-from-provenance store number) + "Re-install an old bootloader using provenance data for system profile +generation NUMBER with store STORE." + (receive (_ os) + (system-provenance (generation-file-name %system-profile number)) + (if os + (install-bootloader-from-os store number os) + (leave (G_ "cannot rollback to generation '~a': no provenance~%") + number)))) + \f ;;; ;;; Graphs. @@ -1391,10 +1372,11 @@ (define (process-command command args opts) (let ((pattern (match args (() #f) ((pattern) pattern) - (x (leave (G_ "wrong number of arguments~%")))))) + (_ (leave (G_ "wrong number of arguments~%"))))) + (number (generation-number %system-profile))) (with-store* store (delete-matching-generations store %system-profile pattern) - (reinstall-bootloader store (generation-number %system-profile))))) + (install-bootloader-from-provenance store number)))) ((switch-generation) (let ((pattern (match args ((pattern) pattern) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 06/15] guix: utils: Add flatten and flat-map from haunt. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (4 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 05/15] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 07/15] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via ` (8 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Cc: Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice * guix/utils.scm (flatten, flat-map): Add procedures. Change-Id: I1d7d49fd02115e3de09ed69bcf5f55a10423162e --- guix/utils.scm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index d8ce6ed886..e37c2d8770 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -139,6 +139,9 @@ (define-module (guix utils) with-environment-variables arguments-from-environment-variable + flatten + flat-map + config-directory cache-directory @@ -1027,6 +1030,29 @@ (define (with-atomic-file-output file proc) (false-if-exception (delete-file template)) (close-port out))))) +;; TODO: bring over other utility procedures from (haunt utils). +(define* (flatten lst #:optional depth) + "Return a list that recursively concatenates the sub-lists of LST, +up to DEPTH levels deep. When DEPTH is #f, the entire tree is +flattened." + (if (and (number? depth) (zero? depth)) + lst + (fold-right (match-lambda* + (((sub-list ...) memo) + (append (flatten sub-list (and depth (1- depth))) + memo)) + ((elem memo) + (cons elem memo))) + '() + lst))) + +(define (flat-map proc . lsts) + "Apply PROC to each element of each list in LSTS and return a new +list in which nested lists are concatenated into the result. + +For example, the list (1 2 (3)) would be flattened to (1 2 3)." + (flatten (apply map proc lsts) 1)) + (define* (xdg-directory variable suffix #:key (ensure? #t)) "Return the name of the XDG directory that matches VARIABLE and SUFFIX, after making sure that it exists if ENSURE? is true. VARIABLE is an -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 07/15] guix: records: Add wrap-element procedure. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (5 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 06/15] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 08/15] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via ` (7 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Cc: Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice * guix/records.scm (wrap-element): Add procedure. Change-Id: If121c5d856e815776830282a0701a73e5ae2a7e7 --- guix/records.scm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/guix/records.scm b/guix/records.scm index c084441441..b521a59257 100644 --- a/guix/records.scm +++ b/guix/records.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012-2024 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2018 Mark H Weaver <mhw@netris.org> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -31,6 +32,8 @@ (define-module (guix records) alist->record object->fields recutils->alist + wrap-element + match-record match-record-lambda)) @@ -606,6 +609,10 @@ (define (recutils->alist port) (else (error "unmatched line" line)))))))) +(define (wrap-element x) + "Sanitize a record field value X to a list." + (if (list? x) x (list x))) + \f ;;; ;;; Pattern matching. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 08/15] gnu: bootloader: Add bootloader-target record and infastructure. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (6 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 07/15] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 09/15] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via ` (6 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (bootloader-target): New record. (&target-error): New condition. (pathcat, get-target-of-type, parent-of, unfold-pathcat, target-base?, type-major?, ensure, ensure-target-types, ensure-majors, gbegin): New procedures. (define-literal, with-targets, :path, :devpath, :device, :fs, :label, :uuid): New macros. * guix/ui.scm (call-with-error-handling)[target-error?]: Handle target-errors. Change-Id: I3f07c9096dd8b91c04449b6360b3b7d21640da14 --- gnu/bootloader.scm | 229 ++++++++++++++++++++++++++++++++++++++++++++- guix/ui.scm | 9 ++ 2 files changed, 233 insertions(+), 5 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 3ea50a4004..0c24996205 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -7,6 +7,7 @@ ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> ;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org> ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -24,19 +25,28 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu bootloader) + #:autoload (gnu build file-systems) + (read-partition-label read-partition-uuid + find-partition-by-label find-partition-by-uuid) #:use-module (gnu system file-systems) #:use-module (gnu system uuid) - #:use-module (guix gexp) - #:use-module (guix profiles) - #:use-module (guix records) + #:autoload (guix build syscalls) + (mounts mount-source mount-point mount-type) #:use-module (guix deprecation) - #:use-module ((guix ui) #:select (warn-about-load-error)) #:use-module (guix diagnostics) + #:use-module (guix gexp) #:use-module (guix i18n) + #:use-module (guix modules) + #:use-module (guix profiles) + #:use-module (guix records) + #:use-module (guix utils) + #:use-module (ice-9 match) + #:use-module (ice-9 receive) + #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) - #:use-module (ice-9 match) #:export (menu-entry menu-entry? menu-entry-label @@ -62,6 +72,25 @@ (define-module (gnu bootloader) bootloader-configuration-file bootloader-configuration-file-generator + bootloader-target + bootloader-target? + bootloader-target-type + bootloader-target-expected? + bootloader-target-path + bootloader-target-offset + bootloader-target-device + bootloader-target-file-system + bootloader-target-label + bootloader-target-uuid + + target-error? + target-error-type + target-error-targets + + gbegin + :path :devpath :device :fs :label :uuid + with-targets + bootloader-configuration bootloader-configuration? bootloader-configuration-bootloader @@ -232,6 +261,196 @@ (define-record-type* <bootloader> (configuration-file bootloader-configuration-file) (configuration-file-generator bootloader-configuration-file-generator)) +\f +;;; +;;; Bootloader target record. +;;; + +;; <bootloader-target> represents different kinds of targets in a +;; normalized form. + +(define-record-type* <bootloader-target> + bootloader-target make-bootloader-target bootloader-target? + (type bootloader-target-type) ; symbol + (expected? bootloader-target-expected? (default #f)) ; bool + + (path bootloader-target-path (default #f)) ; string|#f + (offset bootloader-target-offset (thunked) ; symbol|#f + (default (and (bootloader-target-path this-record) + (not (eq? (bootloader-target-type this-record) 'root)) + 'root))) + (device bootloader-target-device (default #f)) ; string|#f + (file-system bootloader-target-file-system (default #f)) ; string|#f + (label bootloader-target-label (default #f)) ; string|#f + (uuid bootloader-target-uuid (default #f))) ; uuid|#f + +(define-condition-type &target-error &error target-error? + (type target-error-type) + (targets target-error-targets)) + +(define (pathcat p1 p2) + (string-append (string-trim-right p1 #\/) "/" (string-trim p2 #\/))) + +(define* (get-target-of-type type targets #:optional require?) + "Finds a target in TARGETS of type TYPE, returns REQUIRE? if #false, +or provides an error otherwise." + (define (type? target) + (eq? type (bootloader-target-type target))) + (match (filter type? targets) + ((target _ ...) target) + (_ (and require? + (raise + (condition + (&message (message (G_ "required, but not provided"))) + (&target-error (type type) (targets targets)))))))) + +(define (parent-of target targets) + "Resolve the parent of TARGET in TARGETS, return #f if orphan." + (and=> (bootloader-target-offset target) + (cut get-target-of-type <> targets #t))) + +(define (unfold-pathcat target targets) + "Find the full VFS path of TARGET." + (let ((quit (lambda (t) (not (and=> t bootloader-target-path)))) + (parent-of (cut parent-of <> targets))) + (reduce pathcat #f + (unfold quit bootloader-target-path parent-of target)))) + +(define (target-base? t) + (or (not t) (match-record t <bootloader-target> + (expected? offset device label uuid) + (or device label uuid (not offset) expected?)))) + +(define (type-major? target) (memq target '(root esp disk))) + +(define (ensure types targets end) + (let* ((used-in (cute unfold end identity (cut parent-of <> targets) <>)) + (cons-in (lambda (t) (cons t (used-in t)))) + (ensure (map (cut get-target-of-type <> targets #t) types))) + (filter identity (apply append (map cons-in ensure))))) + +(define* (ensure-target-types types targets #:optional (base? #f)) + "Ensures all TYPES are provided in TARGETS. Returns #t iff every ensured +target and its requirements are fully provided. Errors out when a required TYPE +isn't provided. When BASE?, only ensure path requirements up to a device." + (not (any bootloader-target-expected? + (ensure types targets (if base? target-base? not))))) + +(define (ensure-majors types targets) + "Errors out when a required TYPE isn't provided, or when use of multiple major +targets is detected." + (let* ((all (map bootloader-target-type (ensure types targets target-base?))) + (majors (delete-duplicates (filter type-major? all) eq?))) + (if (< (length majors) 2) #t + (raise (condition (&message (message (G_ "multiple major targets used"))) + (&target-error (type majors) (targets targets))))))) + + + +(define (gbegin . gex) + "Sequence provided g-expressions." + (case (length gex) ((0) #f) ((1) (car gex)) (else #~(begin #$@gex)))) + +;; syntax matching on free literals breaks easily, so bind them +(define-syntax-rule (define-literal id) (define-syntax id (syntax-rules ()))) +(define-literal :path) +(define-literal :devpath) +(define-literal :device) +(define-literal :fs) +(define-literal :label) +(define-literal :uuid) + +(define-syntax with-targets + (cut syntax-case <> () + ((_ targets-expr block ...) + (let* ((genvars (compose generate-temporaries make-list)) + (targets (car (genvars 1)))) + (define (resolve in target base) + (with-syntax ((target target) (base base) (targets targets)) + (syntax-case in + (:path :devpath :device :fs :label :uuid) + ((name _) (not (identifier? #'name)) + #`(_ (syntax-error "binds must be to identifiers" #,in))) + ((name :device) #'(name (bootloader-target-device base))) + ((name :label) #'(name (bootloader-target-label base))) + ((name :uuid) #'(name (bootloader-target-uuid base))) + ((name :fs) #'(name (bootloader-target-file-system base))) + ((name :path) #'(name (unfold-pathcat target targets))) + ((name :devpath) + #'(name (if (target-base? target) + "/" + (pathcat "/" (bootloader-target-path target))))) + (_ #`(_ (syntax-error "invalid binding spec" #,in)))))) + + (define (binds spec) + (syntax-case spec (=>) + ((type => binds ...) + (with-syntax (((target base) (genvars 2)) (targets targets)) + (append + #`((get (lambda (t) (get-target-of-type t targets #t))) + (target (get type)) + (base (if (target-base? target) + target + (get (bootloader-target-offset target))))) + (map (cut resolve <> #'target #'base) #'(binds ...))))) + (_ #f))) + + (define blocks + (cut syntax-case <> () + ((spec ... expr) + (let* ((path? (cut syntax-case <> (:path) ((_ :path) #t) (_ #f))) + (qualified? (cut syntax-case <> (=>) + ((_ => spec ...) (any path? #'(spec ...))) + (_ #f))) + (specs #'(spec ...)) + (lets (apply append (filter-map binds specs))) + (type (cut syntax-case <> (=>) + ((t => _ ...) #'t) (t #'t)))) + (receive (full part) (partition qualified? specs) + #`(and (ensure-majors (list #,@(map type specs)) #,targets) + (ensure-target-types (list #,@(map type part)) + #,targets #t) + (ensure-target-types (list #,@(map type full)) + #,targets #f) + (let* #,lets expr))))) + (bad #'(syntax-error "malformed block" bad)))) + "Using the list TARGETS, evaluate and sequence each BLOCK to produce a +gexp. BLOCK is a set of SPECs followed by an EXPR (evaluating to a gexp). +Each SPEC denotes a type of target to guard EXPR on their existance and +full-qualification. This procedure is linear in regard to BLOCKs. + +SPEC may be of the following forms: +@itemize +@item 'TYPE Requires TYPE to be fully present or promised. Errors otherwise. +@item ('TYPE => (VAR COMPONENT) ...): As type, but also binds variables. TYPE's + COMPONENT is bound to the variable VAR as described below. +@end itemize + +Available COMPONENTs are: +@itemize +@item :path (fully-qualified) +@item :devpath (relative from device) +@item :device (auto-detected from uuid and label if not user-provided) +@item :fs +@item :label +@item :uuid +@end itemize + +Note that installers may be called multiple times with different targets being +fully-qualified. To ensure that targets aren't installed multiple times, make sure +that each BLOCK ensures at least one major target, either directly or indirectly. +Likewise, at most one major target should be ensured per BLOCK, under the same +conditions. Major targets originate from disk image handling, and are currently: +@itemize +@item disk +@item root +@item esp +@end itemize" + #`(let ((#,targets targets-expr)) + (apply gbegin (filter identity + (list #,@(map blocks #'(block ...)))))))) + (bad #'(syntax-error "must provide targets" bad)))) + \f ;;; ;;; Bootloader configuration record. diff --git a/guix/ui.scm b/guix/ui.scm index 966f0611f6..0b1455cb3c 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -19,6 +19,7 @@ ;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com> ;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info> ;;; Copyright © 2022 Liliana Marie Prikler <liliana.prikler@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -36,6 +37,8 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix ui) ;import in user interfaces only + #:use-module ((gnu bootloader) + #:select (target-error? target-error-type target-error-targets)) #:use-module (guix i18n) #:use-module (guix colors) #:use-module (guix diagnostics) @@ -861,6 +864,12 @@ (define (call-with-error-handling thunk) (invoke-error-stop-signal c) (cons (invoke-error-program c) (invoke-error-arguments c)))) + ((target-error? c) + (leave (G_ "bootloader-target '~a'~@[: ~a~] ~ + among the following targets:~%~{~y~}") + (target-error-type c) + (and (message-condition? c) (condition-message c)) + (target-error-targets c))) ((formatted-message? c) (apply report-error -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 09/15] gnu: bootloader: Add bootloader-configurations->gexp. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (7 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 08/15] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 10/15] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via ` (5 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (bootloader)[default-targets]: Add field. (target-overrides, normalize, bootloader-configuration->gexp, bootloader-configurations->gexp): New procedures. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 0c24996205..c77de6f55e 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -67,6 +67,7 @@ (define-module (gnu bootloader) bootloader? bootloader-name bootloader-package + bootloader-default-targets bootloader-installer bootloader-disk-image-installer bootloader-configuration-file @@ -107,6 +108,8 @@ (define-module (gnu bootloader) bootloader-configuration-device-tree-support? bootloader-configuration-extra-initrd + bootloader-configuration->gexp + bootloader-configurations->gexp efi-bootloader-chain)) @@ -255,6 +258,7 @@ (define-record-type* <bootloader> bootloader? (name bootloader-name) (package bootloader-package) + (default-targets bootloader-default-targets (default '())) (installer bootloader-installer) (disk-image-installer bootloader-disk-image-installer (default #f)) @@ -498,6 +502,110 @@ (define (bootloader-configuration-targets config) ;; hence the default value of '(#f) rather than '(). (list #f))) +\f +;;; +;;; Bootloader installation paths. +;;; + +(define (target-overrides . layers) + (let* ((types (flat-map (cute map bootloader-target-type <>) layers)) + ;; TODO: use loop instead of fold for early termination. + (pred (lambda (type layer found) + (or found (get-target-of-type type layer)))) + (find (lambda (type) (fold (cute pred type <> <>) #f layers)))) + (filter identity (map find (delete-duplicates types))))) + +(define (normalize targets) + "Augments TARGETS with filesystem information at runtime, allowing +users to specify a lot less information. Puts TARGETS into a normal +form, where each path is fully specified up to a device offset." + (define (mass m) + `((,(mount-source m) . ,m) + (,(mount-point m) . ,m))) + + (define (accessible=> d f) + (and d (access? d R_OK) (f d))) + + (define (fixuuid target) + (match-record target <bootloader-target> (uuid file-system) + (let ((type (cond ((not file-system) 'dce) + ((member file-system '("vfat" "fat32")) 'fat) + ((string=? file-system "ntfs") 'ntfs) + ((string=? file-system "iso9660") 'iso9660) + (else 'dce)))) + (bootloader-target (inherit target) + (uuid (cond ((uuid? uuid) uuid) + ((bytevector? uuid) (bytevector->uuid uuid type)) + ((string? uuid) (string->uuid uuid type)) + (else #f))))))) + + (define (arborify target targets) + (let* ((up (lambda (t) (and t (parent-of t targets)))) + (proto (unfold target-base? identity up (up target) list)) + (chain (reverse (cons target proto)))) + (bootloader-target + (inherit target) + (offset (and=> (car chain) bootloader-target-type)) + (path (reduce pathcat #f (map bootloader-target-path (cdr chain))))))) + + (let ((amounts (delay (apply append (map mass (mounts)))))) + (define (assoc-mnt f) + (lambda (v) (and=> (assoc-ref (force amounts) v) f))) + + (define (scrape target) + (match-record target <bootloader-target> + (expected? path offset device label uuid file-system) + (if expected? target + (bootloader-target + (inherit target) + (device (or device + (false-if-exception + (or (and=> uuid find-partition-by-uuid) + (and=> label find-partition-by-label))) + (and path ((assoc-mnt mount-source) + (unfold-pathcat target targets))))) + (label (or label (accessible=> device read-partition-label))) + (uuid (or uuid (accessible=> device read-partition-uuid))) + (file-system (or file-system (and=> device (assoc-mnt mount-type)))) + (offset (and path offset)) + (path (or path (and=> device (assoc-mnt mount-point)))))))) + + (let ((mid (map (compose fixuuid scrape) targets))) + (map (cut arborify <> mid) mid)))) + +(define* (bootloader-configuration->gexp bootloader-config args #:key + (root-offset "/") (overrides '())) + "Returns a gexp to install BOOTLOADER-CONFIG to its targets, passing ARGS +to each installer alongside the additional #:bootloader-config keyword +arguments. Target OVERRIDES are applied and all path targets have ROOT-OFFSET +applied. The following keyword arguments are expected in ARGS: +@enumerate +@item current-boot-alternative +@item old-boot-alternatives +@item locale (from bootmeta) +@item store-directory-prefix (from bootmeta) +@item store-crypto-devices (from bootmeta) +@end enumerate" + (let* ((bootloader (bootloader-configuration-bootloader bootloader-config)) + (installer (bootloader-installer bootloader)) + (auto-targets (list (bootloader-target + (type 'root) + (path root-offset) + (offset #f)))) + (targets (target-overrides + overrides + (bootloader-configuration-targets bootloader-config) + auto-targets + (bootloader-default-targets bootloader))) + (conf (bootloader-configuration + (inherit bootloader-config) + (targets (normalize targets))))) + (apply installer #:bootloader-config conf args))) + +(define (bootloader-configurations->gexp bootloader-configs . rest) + (apply gbegin (filter-map (cut apply bootloader-configuration->gexp <> rest) + bootloader-configs))) + \f ;;; ;;; Bootloaders. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 10/15] gnu: bootloader: Add device-subvol field to menu-entry record. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (8 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 09/15] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 11/15] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via ` (4 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (menu-entry-device-subvol): Add and export field. (normalize-file): Add procedure. (device->sexp): Match device-subvol and include in S-expression. (sexp->menu-entry): Try match device-subvol and include in menu-entry. * gnu/system/boot.scm (boot-parameters->menu-entry): Add device-subvol value to menu-entry. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 51 ++++++++++++++++++++++++++++++++++----------- gnu/system/boot.scm | 2 ++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index c77de6f55e..f1352122a9 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -51,15 +51,17 @@ (define-module (gnu bootloader) menu-entry? menu-entry-label menu-entry-device + menu-entry-device-mount-point + menu-entry-device-subvol menu-entry-linux menu-entry-linux-arguments menu-entry-initrd - menu-entry-device-mount-point menu-entry-multiboot-kernel menu-entry-multiboot-arguments menu-entry-multiboot-modules menu-entry-chain-loader + normalize-file menu-entry->sexp sexp->menu-entry @@ -126,6 +128,8 @@ (define-record-type* <menu-entry> (default #f)) (device-mount-point menu-entry-device-mount-point (default #f)) + (device-subvol menu-entry-device-subvol + (default #f)) (linux menu-entry-linux (default #f)) (linux-arguments menu-entry-linux-arguments @@ -142,6 +146,18 @@ (define-record-type* <menu-entry> (chain-loader menu-entry-chain-loader (default #f))) ; string, path of efi file +(define (normalize-file entry file) + "Normalize a file FILE stored in a menu entry into one suitable for a +bootloader. Realizes device-mount-point and device-subvol." + (match-menu-entry entry (device-mount-point device-subvol) + ;; Avoid using cut procedure from SRFI-26 inside G-exp. + (let ((mount (and=> device-mount-point (cut string-trim <> #\/)))) + #~(let* ((file (string-trim #$file #\/)) + (file (if (and #$mount (string-prefix? #$mount file)) + (substring file (string-length #$mount)) + file))) + (string-append (or #$device-subvol "") "/" file))))) + (define (report-menu-entry-error menu-entry) (raise (condition @@ -169,7 +185,7 @@ (define (menu-entry->sexp entry) `(label ,(file-system-label->string label))) (_ device))) (match entry - (($ <menu-entry> label device mount-point + (($ <menu-entry> label device mount-point subvol (? identity linux) linux-arguments (? identity initrd) #f () () #f) `(menu-entry (version 0) @@ -178,8 +194,9 @@ (define (menu-entry->sexp entry) (device-mount-point ,mount-point) (linux ,linux) (linux-arguments ,linux-arguments) - (initrd ,initrd))) - (($ <menu-entry> label device mount-point #f () #f + (initrd ,initrd) + (device-subvol ,subvol))) + (($ <menu-entry> label device mount-point subvol #f () #f (? identity multiboot-kernel) multiboot-arguments multiboot-modules #f) `(menu-entry (version 0) @@ -188,19 +205,23 @@ (define (menu-entry->sexp entry) (device-mount-point ,mount-point) (multiboot-kernel ,multiboot-kernel) (multiboot-arguments ,multiboot-arguments) - (multiboot-modules ,multiboot-modules))) - (($ <menu-entry> label device mount-point #f () #f #f () () + (multiboot-modules ,multiboot-modules) + (device-subvol ,subvol))) + (($ <menu-entry> label device mount-point subvol #f () #f #f () () (? identity chain-loader)) `(menu-entry (version 0) (label ,label) (device ,(device->sexp device)) (device-mount-point ,mount-point) - (chain-loader ,chain-loader))) + (chain-loader ,chain-loader) + (device-subvol ,subvol))) (_ (report-menu-entry-error entry)))) (define (sexp->menu-entry sexp) "Turn SEXP, an sexp as returned by 'menu-entry->sexp', into a <menu-entry> record." + ;; XXX: The match ORs shadow subvol. + (define subvol #f) (define (sexp->device device-sexp) (match device-sexp (('uuid type uuid-string) @@ -213,35 +234,41 @@ (define (sexp->menu-entry sexp) ('label label) ('device device) ('device-mount-point mount-point) ('linux linux) ('linux-arguments linux-arguments) - ('initrd initrd) _ ...) + ('initrd initrd) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (linux linux) (linux-arguments linux-arguments) (initrd initrd))) (('menu-entry ('version 0) ('label label) ('device device) - ('device-mount-point mount-point) + ('device-mount-point mount-point) ('device-subvol subvol) ('multiboot-kernel multiboot-kernel) ('multiboot-arguments multiboot-arguments) - ('multiboot-modules multiboot-modules) _ ...) + ('multiboot-modules multiboot-modules) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (multiboot-kernel multiboot-kernel) (multiboot-arguments multiboot-arguments) (multiboot-modules multiboot-modules))) (('menu-entry ('version 0) ('label label) ('device device) - ('device-mount-point mount-point) - ('chain-loader chain-loader) _ ...) + ('device-mount-point mount-point) ('device-subvol subvol) + ('chain-loader chain-loader) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (chain-loader chain-loader))))) \f diff --git a/gnu/system/boot.scm b/gnu/system/boot.scm index a898ab9549..8a183ebe3a 100644 --- a/gnu/system/boot.scm +++ b/gnu/system/boot.scm @@ -16,6 +16,7 @@ ;;; Copyright © 2021 raid5atemyhomework <raid5atemyhomework@protonmail.com> ;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu> ;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -332,6 +333,7 @@ (define (boot-parameters->menu-entry conf) (label (boot-parameters-label conf)) (device (boot-parameters-store-device conf)) (device-mount-point (boot-parameters-store-mount-point conf)) + (device-subvol (boot-parameters-store-directory-prefix conf)) (linux (and (not multiboot?) kernel)) (linux-arguments (if (not multiboot?) (boot-parameters-kernel-arguments conf) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 11/15] gnu: build: bootloader: Add efi-bootnums procedure. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (9 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 10/15] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 12/15] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via ` (3 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/build/bootloader.scm (atomic-copy, efi-bootnums): Add procedures. (in-temporary-directory): Add macro. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/build/bootloader.scm | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm index af6063a884..3934e03aee 100644 --- a/gnu/build/bootloader.scm +++ b/gnu/build/bootloader.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> ;;; Copyright © 2022 Timothy Sample <samplet@ngyro.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -20,13 +21,25 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu build bootloader) + #:autoload (guix build syscalls) (free-disk-space) #:use-module (guix build utils) #:use-module (guix utils) #:use-module (ice-9 binary-ports) + #:use-module (guix diagnostics) + #:use-module (guix i18n) #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (ice-9 popen) + #:use-module (ice-9 receive) + #:use-module (ice-9 regex) #:use-module (rnrs io ports) #:use-module (rnrs io simple) - #:export (write-file-on-device + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-35) + #:export (atomic-copy + in-temporary-directory + write-file-on-device install-efi-loader)) \f @@ -34,6 +47,21 @@ (define-module (gnu build bootloader) ;;; Writing utils. ;;; +(define (atomic-copy from to) + (let ((pivot (string-append to ".new"))) + (copy-file from pivot) + (rename-file pivot to))) + +(define-syntax-rule (in-temporary-directory blocks ...) + "Run BLOCKS while chdir'd into a temporary directory." + ;; Under POSIX.1-2008, mkdtemp must make the dir with 700 perms. + (let* ((tmp (or (getenv "TMPDIR") "/tmp")) + (dir (mkdtemp (string-append tmp "/guix-bootloader.XXXXXX"))) + (cwd (getcwd))) + (dynamic-wind (lambda () (chdir dir)) + (lambda () blocks ...) + (lambda () (chdir cwd) (delete-file-recursively dir))))) + (define (write-file-on-device file size device offset) "Write SIZE bytes from FILE to DEVICE starting at OFFSET." (call-with-input-file file @@ -56,6 +84,24 @@ (define (write-file-on-device file size device offset) ;;; EFI bootloader. ;;; +;; XXX: Parsing efibootmgr output may be kinda jank. A better way may exist. +(define (efi-bootnums efibootmgr) + "Returns '(path . bootnum) pairs for each EFI boot entry. bootnum is +a string, and path is backslash-deliminated and relative to the ESP." + (let* ((pipe (open-pipe* OPEN_READ efibootmgr)) + (text (get-string-all pipe)) + (status (status:exit-val (close-pipe pipe))) + (bootnum-pattern + "^Boot([0-9a-fA-F]+).*[^A-Za-z]File\\(([^)]+)\\)$")) + (unless (zero? status) + (raise-exception + (formatted-message (G_ "efibootmgr exited with error code ~a") status))) + (fold-matches (make-regexp bootnum-pattern regexp/newline) text '() + (lambda (match acc) + (let* ((path (match:substring match 2)) + (bootnum (match:substring match 1))) + (cons (cons path bootnum) acc)))))) + (define* (install-efi grub grub-config esp #:key targets) "Write a self-contained GRUB EFI loader to the mounted ESP using GRUB-CONFIG. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 12/15] gnu: bootloader: Install any bootloader to ESP. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (10 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 11/15] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 13/15] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via ` (2 subsequent siblings) 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Florian Pelz, Ludovic Courtès, Maxim Cournoyer From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (efi-arch, install-efi): New procedures. (%efi-supported-systems, lazy-efibootmgr): New variables. (bootloader-configuration)[efi-removable?, 32bit?]: New fields. (match-bootloader-configuration, match-menu-entry): New macros. * gnu/build/bootloader.scm (install-efi-loader): Delete procedure. (install-efi): Rewrite to support installation of any efi bootloader. * gnu/build/image.scm (initialize-efi32-partition): Deprecate. (initialize-efi-partitition): Only create EFI directory. * gnu/image.scm (partition)[target]: New field in order to support dynamic provision of image partitions as bootloader targets. * gnu/system/image.scm (root-partition, esp-partition): Use target field. * gnu/system/image.scm (esp32-partition, efi32-disk-partition, efi32-raw-image-type): Deprecate. * doc/guix.texi (Creating System Images)[image Reference]<partition Reference>: Add target field. [Instantiate an Image]: Update examples and update formatting. <efi32-disk-image, efi32-raw-image-type>: Delete. <pinebook-pro-image-type, rock64-image-type>: Reword slightly. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- doc/guix.texi | 34 ++++++------ gnu/bootloader.scm | 56 ++++++++++++++++++- gnu/build/bootloader.scm | 115 ++++++++++++++++++++------------------- gnu/build/image.scm | 23 ++------ gnu/image.scm | 4 ++ gnu/system/image.scm | 22 +++----- 6 files changed, 150 insertions(+), 104 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index f7fb4b4cc3..eb24ab9798 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -130,6 +130,7 @@ Copyright @copyright{} 2024 Dariqq@* Copyright @copyright{} 2024 Denis 'GNUtoo' Carikli@* Copyright @copyright{} 2024 Fabio Natali@* +Copyright @copyright{} 2024 Lilah Tascheter@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -47950,6 +47951,12 @@ partition Reference this flag set, usually the root one. The @code{'esp} flag identifies a UEFI System Partition. +@item @code{target} (default: @var{#f}) +If provided, this partition provides itself as a bootloader target +(@pxref{Bootloader Configuration}). Most commonly, this is used to provide the +@code{'root} and @code{'esp} targets, with the root partition and EFI System +Partition, respectively, though this can provide any target necessary. + @item @code{initializer} (default: @code{#false}) The partition initializer procedure as a gexp. This procedure is called to populate a partition. If no initializer is passed, the @@ -47998,6 +48005,7 @@ Instantiate an Image (label "GNU-ESP") (file-system "vfat") (flags '(esp)) + (target 'esp) (initializer (gexp initialize-efi-partition))) (partition (size (* 50 MiB)) @@ -48014,15 +48022,17 @@ Instantiate an Image (label root-label) (file-system "ext4") (flags '(boot)) + (target 'root) (initializer (gexp initialize-root-partition)))))) @end lisp -Note that the first and third partitions use generic initializers -procedures, initialize-efi-partition and initialize-root-partition -respectively. The initialize-efi-partition installs a GRUB EFI loader -that is loading the GRUB bootloader located in the root partition. The -initialize-root-partition instantiates a complete system as defined by -the @code{%simple-os} operating-system. +Note that the first and third partitions use generic initializer +procedures, @code{initialize-efi-partition} and +@code{initialize-root-partition} respectively. +@code{initialize-efi-partition} simply creates the directory structure +for an EFI bootloader to install itself to. +@code{initialize-root-partition} instantiates a complete system as +defined by the @code{%simple-os} operating-system. You can now run: @@ -48079,10 +48089,6 @@ Instantiate an Image @code{i686} machines, supporting BIOS or UEFI booting. @end defvar -@defvar efi32-disk-image -Same as @code{efi-disk-image} but with a 32 bits EFI partition. -@end defvar - @defvar iso9660-image An ISO-9660 image composed of a single bootable partition. This image can also be used on most @code{x86_64} and @code{i686} machines. @@ -48173,10 +48179,6 @@ image-type Reference Build an image based on the @code{efi-disk-image} image. @end defvar -@defvar efi32-raw-image-type -Build an image based on the @code{efi32-disk-image} image. -@end defvar - @defvar qcow2-image-type Build an image based on the @code{mbr-disk-image} image but with the @code{compressed-qcow2} image format. @@ -48204,14 +48206,14 @@ image-type Reference @defvar pinebook-pro-image-type Build an image that is targeting the Pinebook Pro machine. The MBR image contains a single partition starting at a @code{9MiB} offset. The -@code{u-boot-pinebook-pro-rk3399-bootloader} bootloader will be +@code{u-boot-pinebook-pro-rk3399-bootloader} bootloader can be installed in this gap. @end defvar @defvar rock64-image-type Build an image that is targeting the Rock64 machine. The MBR image contains a single partition starting at a @code{16MiB} offset. The -@code{u-boot-rock64-rk3328-bootloader} bootloader will be installed in +@code{u-boot-rock64-rk3328-bootloader} bootloader can be installed in this gap. @end defvar diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index f1352122a9..6b08e61492 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -100,6 +100,8 @@ (define-module (gnu bootloader) bootloader-configuration-targets bootloader-configuration-menu-entries bootloader-configuration-default-entry + bootloader-configuration-efi-removable? + bootloader-configuration-32bit? bootloader-configuration-timeout bootloader-configuration-keyboard-layout bootloader-configuration-theme @@ -113,6 +115,9 @@ (define-module (gnu bootloader) bootloader-configuration->gexp bootloader-configurations->gexp + %efi-supported-systems + efi-arch + install-efi efi-bootloader-chain)) \f @@ -502,6 +507,10 @@ (define-record-type* <bootloader-configuration> (default '())) ;list of <menu-entry> (default-entry bootloader-configuration-default-entry (default 0)) ;integer + (efi-removable? bootloader-configuration-efi-removable? + (default #f)) ;bool + (32bit? bootloader-configuration-32bit? + (default #f)) ;bool (timeout bootloader-configuration-timeout (default 5)) ;seconds as integer (keyboard-layout bootloader-configuration-keyboard-layout @@ -635,9 +644,54 @@ (define (bootloader-configurations->gexp bootloader-configs . rest) \f ;;; -;;; Bootloaders. +;;; Bootloader installation to ESP. ;;; +;; systems currently supported by efi-arch. should be used for packages relying +;; on it. +(define %efi-supported-systems + '("i686-linux" "x86_64-linux" "armhf-linux" "aarch64-linux" "riscv64-linux")) + +(define* (efi-arch #:key (target (or (%current-target-system) (%current-system))) + (32? #f)) + "Returns the UEFI architecture name for the current target, in lowercase." + (cond ((target-x86-32? target) "ia32") + ((target-x86-64? target) (if 32? "ia32" "x64")) + ((target-arm32? target) "arm") + ((target-aarch64? target) (if 32? "arm" "aa64")) + ((target-riscv64? target) (if 32? "riscv32" "riscv64")) + (else (raise (formatted-message (G_ "no UEFI standard arch for ~a!") + target))))) + +(define (lazy-efibootmgr) + "Lazy-loaded efibootmgr package, in order to prevent circular refs." + (module-ref (resolve-interface '(gnu packages linux)) 'efibootmgr)) + +(define (install-efi bootloader-config plan) + "Returns a gexp installing PLAN to the ESP, as denoted by the 'vendir target. +PLAN is a gexp of a list of '(BUILDER DEST-BASENAME . LABEL) triples, that +should be in boot order. If the user selects a removable bootloader, only the +first entry in PLAN is used." + (match-record bootloader-config <bootloader-configuration> + (targets efi-removable? 32bit?) + (if efi-removable? + ;; Hard code the output location to a well-known path recognized by + ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour": + ;; http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf + (with-targets targets + (('esp => (path :path)) + #~(let ((boot #$(string-append path "/EFI/BOOT")) + (arch #$(string-upcase (efi-arch #:32? 32bit?))) + (builder (car (car #$plan)))) + (mkdir-p boot) + ;; Only realize the first planspec. + (builder (string-append boot "/BOOT" arch ".EFI"))))) + ;; Install normally if not configured as removable. + (with-targets targets + (('vendir => (vendir :path) (loader :devpath) (disk :device)) + #~(install-efi #+(file-append (lazy-efibootmgr) "/sbin/efibootmgr") + #$vendir #$loader #$disk #$plan)))))) + (define (efi-bootloader-profile packages files hooks) "Creates a profile from the lists of PACKAGES and FILES from the store. This profile is meant to be used by the bootloader-installer. diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm index 3934e03aee..064466bd33 100644 --- a/gnu/build/bootloader.scm +++ b/gnu/build/bootloader.scm @@ -23,8 +23,6 @@ (define-module (gnu build bootloader) #:autoload (guix build syscalls) (free-disk-space) #:use-module (guix build utils) - #:use-module (guix utils) - #:use-module (ice-9 binary-ports) #:use-module (guix diagnostics) #:use-module (guix i18n) #:use-module (ice-9 format) @@ -40,7 +38,7 @@ (define-module (gnu build bootloader) #:export (atomic-copy in-temporary-directory write-file-on-device - install-efi-loader)) + install-efi)) \f ;;; @@ -102,57 +100,62 @@ (define (efi-bootnums efibootmgr) (bootnum (match:substring match 1))) (cons (cons path bootnum) acc)))))) -(define* (install-efi grub grub-config esp #:key targets) - "Write a self-contained GRUB EFI loader to the mounted ESP using -GRUB-CONFIG. - -If TARGETS is set, use its car as the GRUB image format and its cdr as -the output filename. Otherwise, use defaults for the host platform." - (let* ((system %host-type) - ;; Hard code the output location to a well-known path recognized by - ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour": - ;; http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf - (grub-mkstandalone (string-append grub "/bin/grub-mkstandalone")) - (efi-directory (string-append esp "/EFI/BOOT")) - ;; Map grub target names to boot file names. - (efi-targets (or targets - (cond ((string-prefix? "x86_64" system) - '("x86_64-efi" . "BOOTX64.EFI")) - ((string-prefix? "i686" system) - '("i386-efi" . "BOOTIA32.EFI")) - ((string-prefix? "armhf" system) - '("arm-efi" . "BOOTARM.EFI")) - ((string-prefix? "aarch64" system) - '("arm64-efi" . "BOOTAA64.EFI")))))) - ;; grub-mkstandalone requires a TMPDIR to prepare the firmware image. - (setenv "TMPDIR" esp) - - (mkdir-p efi-directory) - (invoke grub-mkstandalone "-O" (car efi-targets) - "-o" (string-append efi-directory "/" - (cdr efi-targets)) - ;; Graft the configuration file onto the image. - (string-append "boot/grub/grub.cfg=" grub-config)))) - -(define* (install-efi-loader grub-efi esp #:key targets) - "Install in ESP directory the given GRUB-EFI bootloader. Configure it to -load the Grub bootloader located in the 'Guix_image' root partition. - -If TARGETS is set, use its car as the GRUB image format and its cdr as -the output filename. Otherwise, use defaults for the host platform." - (let ((grub-config "grub.cfg")) - (call-with-output-file grub-config - (lambda (port) - ;; Create a tiny configuration file telling the embedded grub where to - ;; load the real thing. XXX This is quite fragile, and can prevent - ;; the image from booting when there's more than one volume with this - ;; label present. Reproducible almost-UUIDs could reduce the risk - ;; (not eliminate it). - (format port - "insmod part_msdos~@ - insmod part_gpt~@ - search --set=root --label Guix_image~@ - configfile /boot/grub/grub.cfg~%"))) - (install-efi grub-efi grub-config esp #:targets targets) - (delete-file grub-config))) +(define (install-efi efibootmgr vendir loader* disk plan) + "See also install-efi in (gnu bootloader)." + (let* ((loader (string-map (match-lambda (#\/ #\\) (x x)) loader*)) + (bootnums (filter (compose (cut string-prefix? loader <>) car) + (efi-bootnums efibootmgr))) + (plan-files (map cadr plan))) + (define (size file) (if (file-exists? file) (stat:size (stat file)) 0)) + (define (vendirof file) (string-append vendir "/" file)) + (define (loaderof file) (string-append loader "\\" file)) + (define (delete-boot num file) + (invoke efibootmgr "--quiet" "--bootnum" num "--delete-bootnum") + (when (file-exists? file) (delete-file file))) + (mkdir-p vendir) + ;; Delete old entries first, to clear up space. + (for-each (lambda (spec) ; '(path . bootnum) + (let* ((s (substring (car spec) (string-length loader))) + (file (substring s (if (string-prefix? "\\" s) 1 0)))) + (unless (member file plan-files) + (delete-boot (cdr spec) (vendirof file))))) + bootnums) + ;; New and updated entries. + (in-temporary-directory + (for-each + (lambda (spec) + (let* ((builder (car spec)) (name (cadr spec)) + (dest (vendirof name)) (loadest (loaderof name)) + (rest (reverse (cdr (member name plan-files))))) + ;; Build to a temporary file so we can check its size. + (builder name) + ;; Disk space is usually limited on ESPs. + ;; Try to clear space as we install new bootloaders. + (if (while (> (- (size name) (size dest)) (free-disk-space vendir)) + (let ((del (find (compose file-exists? vendirof) rest))) + (if del (delete-file (vendirof del)) (break #t)))) + (begin + (and=> (assoc-ref bootnums loadest) (cut delete-boot <> dest)) + (warning (G_ "ESP too small for bootloader ~a!~%") name)) + ;; The ESP is too small for atomic copy. + (begin + (copy-file name dest) + (unless (assoc loadest bootnums) + (invoke + efibootmgr "--quiet" "--create-only" "--label" + (cddr spec) "--disk" disk "--loader" loadest)))) + (delete-file name))) + plan)) + ;; Verify that at least the first entry was installed. + (unless (file-exists? (vendirof (cadr (car plan)))) + ;; Extremely fatal error so we use leave instead of raise. + (leave (G_ "not enough space in ESP to install bootloader! + SYSTEM WILL NOT BOOT UNLESS THIS IS FIXED!~%"))) + ;; Some UEFI systems will refuse to acknowledge the existence of boot + ;; entries unless they're in bootorder, so just shove everything in there. + (invoke + efibootmgr "--quiet" "--bootorder" + ;; Recall efi-bootnums to get a fresh list with new installs. + (let ((num (cute assoc-ref (efi-bootnums efibootmgr) <>))) ; cute is eager + (string-join (filter-map (compose num loaderof) plan-files) ","))))) diff --git a/gnu/build/image.scm b/gnu/build/image.scm index 6ca0a428e0..1b2d4da814 100644 --- a/gnu/build/image.scm +++ b/gnu/build/image.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2022 Pavel Shlyak <p.shlyak@pantherx.org> ;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -28,6 +29,7 @@ (define-module (gnu build image) #:use-module (guix build store-copy) #:use-module (guix build syscalls) #:use-module (guix build utils) + #:use-module (guix deprecation) #:use-module (guix store database) #:use-module (guix utils) #:use-module (gnu build bootloader) @@ -181,23 +183,10 @@ (define* (register-closure prefix closure #:prefix prefix #:registration-time %epoch))))) -(define* (initialize-efi-partition root - #:key - grub-efi - #:allow-other-keys) - "Install in ROOT directory, an EFI loader using GRUB-EFI." - (install-efi-loader grub-efi root)) - -(define* (initialize-efi32-partition root - #:key - grub-efi32 - #:allow-other-keys) - "Install in ROOT directory, an EFI 32bit loader using GRUB-EFI32." - (install-efi-loader grub-efi32 root - #:targets (cond ((target-x86?) - '("i386-efi" . "BOOTIA32.EFI")) - ((target-arm?) - '("arm-efi" . "BOOTARM.EFI"))))) +(define (initialize-efi-partition root . rest) + (mkdir-p (string-append root "/EFI"))) + +(define-deprecated/alias initialize-efi32-partition initialize-efi-partition) (define* (initialize-root-partition root #:key diff --git a/gnu/image.scm b/gnu/image.scm index 7fb06dec10..c6cc264147 100644 --- a/gnu/image.scm +++ b/gnu/image.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2020, 2022 Mathieu Othacehe <othacehe@gnu.org> ;;; Copyright © 2023 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -35,6 +36,7 @@ (define-module (gnu image) partition-label partition-uuid partition-flags + partition-target partition-initializer image @@ -131,6 +133,8 @@ (define-record-type* <partition> partition make-partition (flags partition-flags (default '()) ;list of symbols (sanitize validate-partition-flags)) + (target partition-target ; bootloader target type: symbol | #f + (default #f)) (initializer partition-initializer (default #false))) ;gexp | #false diff --git a/gnu/system/image.scm b/gnu/system/image.scm index b0c96c60f0..8ac91800ad 100644 --- a/gnu/system/image.scm +++ b/gnu/system/image.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2022 Alex Griffin <a@ajgrf.com> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2023 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -23,6 +24,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu system image) + #:use-module (guix deprecation) #:use-module (guix diagnostics) #:use-module (guix discovery) #:use-module (guix gexp) @@ -133,12 +135,10 @@ (define esp-partition ;; FAT-ness is based on file system size (16 in this case). (file-system "vfat") (flags '(esp)) - (initializer (gexp initialize-efi-partition)))) + (target 'esp) + (initializer #~initialize-efi-partition))) -(define esp32-partition - (partition - (inherit esp-partition) - (initializer (gexp initialize-efi32-partition)))) +(define-deprecated/alias esp32-partition esp-partition) (define root-partition (partition @@ -149,6 +149,7 @@ (define root-partition ;; with U-Boot. (file-system-options (list "-O" "^metadata_csum,^64bit")) (flags '(boot)) + (target 'root) (initializer (gexp initialize-root-partition)))) (define mbr-disk-image @@ -173,11 +174,7 @@ (define efi-disk-image (partition-table-type 'gpt) (partitions (list esp-partition root-partition)))) -(define efi32-disk-image - (image-without-os - (format 'disk-image) - (partition-table-type 'gpt) - (partitions (list esp32-partition root-partition)))) +(define-deprecated/alias efi32-disk-image efi-disk-image) (define iso9660-image (image-without-os @@ -238,10 +235,7 @@ (define efi-raw-image-type (name 'efi-raw) (constructor (cut image-with-os efi-disk-image <>)))) -(define efi32-raw-image-type - (image-type - (name 'efi32-raw) - (constructor (cut image-with-os efi32-disk-image <>)))) +(define-deprecated/alias efi32-raw-image-type efi-raw-image-type) (define qcow2-image-type (image-type -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 13/15] gnu: bootloader: Match records outside the module. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (11 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 12/15] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 14/15] gnu: system: boot: Add procedure Herman Rimm via Guix-patches via 2024-09-20 10:38 ` [bug#73202] [PATCH v2 15/15] teams: Add bootloading team Herman Rimm via Guix-patches via 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202 * gnu/bootloader.scm (match-bootloader-configuration, match-menu-entry): Add macros. Change-Id: I42cb7541045314c37ffef98fe6efe7f46acd9d9b --- gnu/bootloader.scm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 6b08e61492..b1ed187aa2 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org> ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -115,6 +116,9 @@ (define-module (gnu bootloader) bootloader-configuration->gexp bootloader-configurations->gexp + match-bootloader-configuration + match-menu-entry + %efi-supported-systems efi-arch install-efi @@ -642,6 +646,20 @@ (define (bootloader-configurations->gexp bootloader-configs . rest) (apply gbegin (filter-map (cut apply bootloader-configuration->gexp <> rest) bootloader-configs))) +;; In lieu of exporting bootloader-configuration and menu-entry RTDs. +(define-syntax match-bootloader-configuration + (syntax-rules () + "Bind each BOOTLOADER-CONFIGURATION field in FIELDS." + ((_ bootloader-configuration (fields ...) body ...) + (match-record bootloader-configuration <bootloader-configuration> + (fields ...) body ...)))) + +(define-syntax match-menu-entry + (syntax-rules () + "Bind each MENU-ENTRY field in FIELDS." + ((_ menu-entry (fields ...) body ...) + (match-record menu-entry <menu-entry> (fields ...) body ...)))) + \f ;;; ;;; Bootloader installation to ESP. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 14/15] gnu: system: boot: Add procedure. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (12 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 13/15] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via @ 2024-09-20 10:37 ` Herman Rimm via Guix-patches via 2024-09-20 10:38 ` [bug#73202] [PATCH v2 15/15] teams: Add bootloading team Herman Rimm via Guix-patches via 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/system/boot.scm (boot-alternative->menu-entry): New procedure. Change-Id: Id68fb3d39e6d9aca9267f3884cf54f2e7a08b353 --- gnu/system/boot.scm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gnu/system/boot.scm b/gnu/system/boot.scm index 8a183ebe3a..2040984cbf 100644 --- a/gnu/system/boot.scm +++ b/gnu/system/boot.scm @@ -81,6 +81,7 @@ (define-module (gnu system boot) epoch->date-string decorated-boot-label boot-parameters->menu-entry + boot-alternative->menu-entry ensure-not-/dev system-linux-image-file-name)) @@ -347,6 +348,9 @@ (define (boot-parameters->menu-entry conf) (boot-parameters-multiboot-modules conf) '()))))) +(define boot-alternative->menu-entry + (compose boot-parameters->menu-entry boot-alternative-parameters)) + (define (ensure-not-/dev device) "If DEVICE starts with a slash, return #f. This is meant to filter out Linux device names such as /dev/sda, and to preserve GRUB device names and -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 15/15] teams: Add bootloading team. 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via ` (13 preceding siblings ...) 2024-09-20 10:37 ` [bug#73202] [PATCH v2 14/15] gnu: system: boot: Add procedure Herman Rimm via Guix-patches via @ 2024-09-20 10:38 ` Herman Rimm via Guix-patches via 14 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-20 10:38 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> Might as well, to help ease the transition. * etc/teams.scm (bootloaders): New team. (Lilah Tascheter): Create and add to above. Change-Id: I63620f4e3151bb8e3d0bdf619fc70501af6397a0 --- etc/teams.scm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/etc/teams.scm b/etc/teams.scm index 9239021b39..2150a7aad1 100755 --- a/etc/teams.scm +++ b/etc/teams.scm @@ -328,6 +328,12 @@ (define-team embedded #:scope (list "gnu/packages/bootloaders.scm" "gnu/packages/firmware.scm"))) +(define-team bootloaders + (team 'bootloaders + #:name "Bootloaders" + #:scope (list "gnu/bootloader.scm" + (make-regexp* "^gnu/bootloader/")))) + (define-team rust (team 'rust #:name "Rust" @@ -749,6 +755,10 @@ (define-member (person "André Batista" "nandre@riseup.net") mozilla) +(define-member (person "Lilah Tascheter" + "lilah@lunabee.space") + bootloaders) + \f (define (find-team name) (or (hash-ref %teams (string->symbol name)) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite. 2024-09-12 16:58 [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via @ 2024-09-21 10:57 ` Herman Rimm via Guix-patches via 2024-09-25 20:58 ` Lilah Tascheter via Guix-patches 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-10-03 20:32 ` [bug#73202] [PATCH] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 3 siblings, 1 reply; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-21 10:57 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter Hello, I posted revision v5 of #69343. If you would like to apply v2 of this issue on it, use git am -3 and pick the conflicting change made by patch #5 as is. Also note that the changes made by patch #14 are now included in v5 of #69343. Cheers, Herman ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite. 2024-09-21 10:57 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via @ 2024-09-25 20:58 ` Lilah Tascheter via Guix-patches 0 siblings, 0 replies; 41+ messages in thread From: Lilah Tascheter via Guix-patches @ 2024-09-25 20:58 UTC (permalink / raw) To: 73202; +Cc: Herman Rimm hey herman! > use git am -3 fails on a clean pull/am due to lack of commit blobs. I'm not quite sure how to fix that myself, would you be able to just re-send the rebased patch series? thanks! ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field. 2024-09-12 16:58 [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-09-21 10:57 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via @ 2024-09-26 10:08 ` Herman Rimm via Guix-patches via 2024-09-26 10:08 ` [bug#73202] [PATCH v3 02/14] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via ` (12 more replies) 2024-10-03 20:32 ` [bug#73202] [PATCH] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 3 siblings, 13 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:08 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (warn-target-field-deprecation): Delete sanitizer. (bootloader-configuration)[target]: Remove deprecated field. (bootloader-configuration-target): Delete procedure. (bootloader-configuration-targets): Do not use target field. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index f32e90e79d..865521e6e5 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -66,7 +66,6 @@ (define-module (gnu bootloader) bootloader-configuration bootloader-configuration? bootloader-configuration-bootloader - bootloader-configuration-target ;deprecated bootloader-configuration-targets bootloader-configuration-menu-entries bootloader-configuration-default-entry @@ -244,24 +243,14 @@ (define-record-type* <bootloader> ;; The <bootloader-configuration> record contains bootloader independant ;; configuration used to fill bootloader configuration file. -(define-with-syntax-properties (warn-target-field-deprecation - (value properties)) - (when value - (warning (source-properties->location properties) - (G_ "the 'target' field is deprecated, please use 'targets' \ -instead~%"))) - value) (define-record-type* <bootloader-configuration> bootloader-configuration make-bootloader-configuration bootloader-configuration? (bootloader - bootloader-configuration-bootloader) ;<bootloader> + bootloader-configuration-bootloader) ;<bootloader> (targets %bootloader-configuration-targets (default #f)) ;list of strings - (target %bootloader-configuration-target ;deprecated - (default #f) - (sanitize warn-target-field-deprecation)) (menu-entries bootloader-configuration-menu-entries (default '())) ;list of <menu-entry> (default-entry bootloader-configuration-default-entry @@ -285,14 +274,9 @@ (define-record-type* <bootloader-configuration> (extra-initrd bootloader-configuration-extra-initrd (default #f))) ;string | #f -(define-deprecated (bootloader-configuration-target config) - bootloader-configuration-targets - (%bootloader-configuration-target config)) (define (bootloader-configuration-targets config) (or (%bootloader-configuration-targets config) - ;; TODO: Remove after the deprecated 'target' field is removed. - (list (%bootloader-configuration-target config)) ;; XXX: At least the GRUB installer (see (gnu bootloader grub)) has this ;; peculiar behavior of installing fonts and GRUB modules when DEVICE is #f, ;; hence the default value of '(#f) rather than '(). base-commit: db3ec7f65bd04741f1d97a9a3bbd3d96f12caa52 -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 02/14] gnu: system: Remove useless boot parameters. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via @ 2024-09-26 10:08 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 03/14] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via ` (11 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:08 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/system.scm (operating-system-boot-parameters, operating-system-boot-parameters-file): Delete bootloader-menu-entries. * gnu/system/boot.scm (boot-parameters)[bootloader-menu-entries]: Delete field. (read-boot-parameters): Don't read bootloader-menu-entries. * tests/boot-parameters.scm (%grub-boot-parameters, test-read-boot-parameters, test-read-boot-parameters): Don't include bootloader-menu-entries. ("read, bootloader-menu-entries, default value"): Delete test. Change-Id: I46d9cff4604dbfcf654b0820fdb77e72aecffbb4 --- gnu/system.scm | 7 ------- gnu/system/boot.scm | 8 -------- tests/boot-parameters.scm | 18 +++++------------- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/gnu/system.scm b/gnu/system.scm index 25afa96295..a3eee5aa24 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -1298,8 +1298,6 @@ (define* (operating-system-boot-parameters os root-device (initrd initrd) (multiboot-modules multiboot-modules) (bootloader-name bootloader-name) - (bootloader-menu-entries - (bootloader-configuration-menu-entries (operating-system-bootloader os))) (locale locale) (store-device (ensure-not-/dev (file-system-device store))) (store-directory-prefix (btrfs-store-subvolume-file-name file-systems)) @@ -1341,11 +1339,6 @@ (define* (operating-system-boot-parameters-file os) #$(boot-parameters-multiboot-modules params))) #~()) (bootloader-name #$(boot-parameters-bootloader-name params)) - (bootloader-menu-entries - #$(map menu-entry->sexp - (or (and=> (operating-system-bootloader os) - bootloader-configuration-menu-entries) - '()))) (locale #$(boot-parameters-locale params)) (store (device diff --git a/gnu/system/boot.scm b/gnu/system/boot.scm index de312c7208..54e5673a54 100644 --- a/gnu/system/boot.scm +++ b/gnu/system/boot.scm @@ -51,7 +51,6 @@ (define-module (gnu system boot) boot-parameters-label boot-parameters-root-device boot-parameters-bootloader-name - boot-parameters-bootloader-menu-entries boot-parameters-store-crypto-devices boot-parameters-store-device boot-parameters-store-directory-prefix @@ -110,8 +109,6 @@ (define-record-type* <boot-parameters> ;; partition. (root-device boot-parameters-root-device) (bootloader-name boot-parameters-bootloader-name) - (bootloader-menu-entries ;list of <menu-entry> - boot-parameters-bootloader-menu-entries) (store-device boot-parameters-store-device) (store-mount-point boot-parameters-store-mount-point) (store-directory-prefix boot-parameters-store-directory-prefix) @@ -172,11 +169,6 @@ (define (read-boot-parameters port) ((_ args) args) (#f 'grub))) ; for compatibility reasons. - (bootloader-menu-entries - (match (assq 'bootloader-menu-entries rest) - ((_ entries) (map sexp->menu-entry entries)) - (#f '()))) - ;; In the past, we would store the directory name of linux instead of ;; the absolute file name of its image. Detect that and correct it. (kernel (if (string=? kernel (direct-store-path kernel)) diff --git a/tests/boot-parameters.scm b/tests/boot-parameters.scm index 2e7976aa6c..e1dc4620c3 100644 --- a/tests/boot-parameters.scm +++ b/tests/boot-parameters.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2019, 2020 Miguel Ángel Arruga Vivas <rosen644835@gmail.com> ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -34,6 +35,7 @@ (define-module (test-boot-parameters) #:use-module (guix gexp) #:use-module (guix store) #:use-module (guix tests) + #:use-module (ice-9 format) #:use-module (srfi srfi-34) #:use-module (srfi srfi-64) #:use-module (rnrs bytevectors)) @@ -64,7 +66,6 @@ (define %root-path "/") (define %grub-boot-parameters (boot-parameters (bootloader-name 'grub) - (bootloader-menu-entries '()) (root-device %default-root-device) (label %default-label) (kernel %default-kernel) @@ -107,7 +108,6 @@ (define* (test-read-boot-parameters #:key (version %boot-parameters-version) (bootloader-name 'grub) - (bootloader-menu-entries '()) (label %default-label) (root-device (quote-uuid %default-root-device)) (kernel %default-kernel) @@ -127,7 +127,7 @@ (define* (test-read-boot-parameters (cond ((eq? 'false val) (format #false fmt #false)) (val (format #false fmt val)) (else ""))) - (format #false "(boot-parameters~a~a~a~a~a~a~a~a~a~a)" + (format #f "(boot-parameters~@{~a~})" (sexp-or-nothing " (version ~S)" version) (sexp-or-nothing " (label ~S)" label) (sexp-or-nothing " (root-device ~S)" root-device) @@ -135,7 +135,7 @@ (define* (test-read-boot-parameters (sexp-or-nothing " (kernel-arguments ~S)" kernel-arguments) (sexp-or-nothing " (initrd ~S)" initrd) (if with-store - (format #false " (store~a~a~a~a)" + (format #f " (store~@{~a~})" (sexp-or-nothing " (device ~S)" store-device) (sexp-or-nothing " (mount-point ~S)" store-mount-point) @@ -145,9 +145,7 @@ (define* (test-read-boot-parameters store-crypto-devices)) "") (sexp-or-nothing " (locale ~S)" locale) - (sexp-or-nothing " (bootloader-name ~a)" bootloader-name) - (sexp-or-nothing " (bootloader-menu-entries ~S)" - bootloader-menu-entries))) + (sexp-or-nothing " (bootloader-name ~a)" bootloader-name))) (let ((str (generate-boot-parameters))) (call-with-input-string str read-boot-parameters))) @@ -170,7 +168,6 @@ (define* (test-read-boot-parameters (test-assert "read, construction, optional fields" (and (test-read-boot-parameters #:bootloader-name #false) - (test-read-boot-parameters #:bootloader-menu-entries #false) (test-read-boot-parameters #:kernel-arguments #false) (test-read-boot-parameters #:with-store #false) (test-read-boot-parameters #:store-device #false) @@ -223,11 +220,6 @@ (define* (test-read-boot-parameters (boot-parameters-bootloader-name (test-read-boot-parameters #:bootloader-name #false))) -(test-eq "read, bootloader-menu-entries, default value" - '() - (boot-parameters-bootloader-menu-entries - (test-read-boot-parameters #:bootloader-menu-entries #false))) - (test-eq "read, kernel-arguments, default value" '() (boot-parameters-kernel-arguments -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 03/14] gnu: tests: reconfigure: Remove bootloader install test. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-09-26 10:08 ` [bug#73202] [PATCH v3 02/14] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 04/14] guix: scripts: Remove unused code Herman Rimm via Guix-patches via ` (10 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/tests/reconfigure.scm (%test-install-bootloader): Delete variable. (run-install-bootloader-test): Delete procedure. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/tests/reconfigure.scm | 86 +-------------------------------------- 1 file changed, 1 insertion(+), 85 deletions(-) diff --git a/gnu/tests/reconfigure.scm b/gnu/tests/reconfigure.scm index bcc7645fa3..8aa5311171 100644 --- a/gnu/tests/reconfigure.scm +++ b/gnu/tests/reconfigure.scm @@ -30,8 +30,7 @@ (define-module (gnu tests reconfigure) #:use-module (guix scripts system reconfigure) #:use-module (guix store) #:export (%test-switch-to-system - %test-upgrade-services - %test-install-bootloader)) + %test-upgrade-services)) ;;; Commentary: ;;; @@ -178,83 +177,6 @@ (define* (run-upgrade-services-test) (disable (upgrade-services-program '() '() '(dummy) '()))) (test enable disable)))) -(define* (run-install-bootloader-test) - "Run a test of an OS running INSTALL-BOOTLOADER-PROGRAM, which installs a -bootloader's configuration file." - (define os - (marionette-operating-system - (simple-operating-system) - #:imported-modules '((gnu services herd) - (guix combinators)))) - - (define vm (virtual-machine - (operating-system os) - (volatile? #f))) - - (define (test script) - (with-imported-modules '((gnu build marionette)) - #~(begin - (use-modules (gnu build marionette) - (ice-9 regex) - (srfi srfi-1) - (srfi srfi-64)) - - (define marionette - (make-marionette (list #$vm))) - - ;; Return the system generation paths that have GRUB menu entries. - (define (generations-in-grub-cfg marionette) - (let ((grub-cfg (marionette-eval - '(begin - (use-modules (rnrs io ports)) - (call-with-input-file "/boot/grub/grub.cfg" - get-string-all)) - marionette))) - (map (lambda (parameter) - (second (string-split (match:substring parameter) #\=))) - (list-matches "system=[^ ]*" grub-cfg)))) - - (test-runner-current (system-test-runner #$output)) - (test-begin "install-bootloader") - - (test-assert "no prior menu entry for system generation" - (not (member #$os (generations-in-grub-cfg marionette)))) - - (test-assert "script successfully evaluated" - (marionette-eval - '(primitive-load #$script) - marionette)) - - (test-assert "menu entry created for system generation" - (member #$os (generations-in-grub-cfg marionette))) - - (test-end)))) - - (let* ((bootloader ((compose bootloader-configuration-bootloader - operating-system-bootloader) - os)) - ;; The typical use-case for 'install-bootloader-program' is to read - ;; the boot parameters for the existing menu entries on the system, - ;; parse them with 'boot-parameters->menu-entry', and pass the - ;; results to 'operating-system-bootcfg'. However, to obtain boot - ;; parameters, we would need to start the marionette, which we should - ;; ideally avoid doing outside of the 'test' G-Expression. Thus, we - ;; generate a bootloader configuration for the script as if there - ;; were no existing menu entries. In the grand scheme of things, this - ;; matters little -- these tests should not make assertions about the - ;; behavior of 'operating-system-bootcfg'. - (bootcfg (operating-system-bootcfg os '())) - (bootcfg-file (bootloader-configuration-file bootloader))) - (gexp->derivation - "install-bootloader" - ;; Due to the read-only nature of the virtual machines used in the system - ;; test suite, the bootloader installer script is omitted. 'grub-install' - ;; would attempt to write directly to the virtual disk if the - ;; installation script were run. - (test - (install-bootloader-program #f #f #f bootcfg bootcfg-file '(#f) "/"))))) - - (define %test-switch-to-system (system-test (name "switch-to-system") @@ -267,9 +189,3 @@ (define %test-upgrade-services (description "Upgrade the Shepherd by unloading obsolete services and loading new services.") (value (run-upgrade-services-test)))) - -(define %test-install-bootloader - (system-test - (name "install-bootloader") - (description "Install a bootloader and its configuration file.") - (value (run-install-bootloader-test)))) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 04/14] guix: scripts: Remove unused code. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-09-26 10:08 ` [bug#73202] [PATCH v3 02/14] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 03/14] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 05/14] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via ` (9 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> * guix/scripts/system.scm (bootloader-installer-script): Delete. Change-Id: Ic1e0a523c814e4f1bf44b2721f5658f00066b0ab --- guix/scripts/system.scm | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 0fd153a278..881f2de104 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -754,28 +754,6 @@ (define (maybe-suggest-running-guix-pull) (warning (G_ "Consider running 'guix pull' before 'reconfigure'.~%")) (warning (G_ "Failing to do that may downgrade your system!~%")))) -(define (bootloader-installer-script installer - bootloader device target) - "Return a file calling INSTALLER gexp with given BOOTLOADER, DEVICE -and TARGET arguments." - (scheme-file "bootloader-installer" - (with-imported-modules '((gnu build bootloader) - (guix build utils)) - #~(begin - (use-modules (gnu build bootloader) - (guix build utils) - (ice-9 binary-ports) - (srfi srfi-34) - (srfi srfi-35)) - - (guard (c ((message-condition? c) ;XXX: i18n - (format (current-error-port) "error: ~a~%" - (condition-message c)) - (exit 1))) - (#$installer #$bootloader #$device #$target) - (info (G_ "bootloader successfully installed on '~a'~%") - #$device)))))) - (define (local-eval exp) "Evaluate EXP, a G-Expression, in-place." (mlet* %store-monad ((lowered (lower-gexp exp)) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 05/14] guix: scripts: Rewrite reinstall-bootloader to use provenance data. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (2 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 04/14] guix: scripts: Remove unused code Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 06/14] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via ` (8 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Lilah Tascheter, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> Looking up bootloaders by name is broken because (extlinux) bootloaders share a name. Also, bootloader-configuration data is significant to bootloader installation, so it shouldn't just use the default values. Installation can rely on the provenance service instead, which should be present for the vast majority of systems. * gnu/bootloader.scm (%bootloaders): Delete variable. (lookup-bootloader-by-name, bootloader-modules): Delete procedures. * guix/scripts/system.scm (install-bootloader-from-os, install-bootloader-from-provenance): Add procedures. (reinstall-bootloader): Remove procedure. (switch-to-system-generation, process-command): Use install-bootloader-from-provenance. Change-Id: I5713a43ad4f9f32a129d980db06d70de16b03f27 --- gnu/bootloader.scm | 26 --------------- guix/scripts/system.scm | 73 ++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 71 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 865521e6e5..3ea50a4004 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -26,7 +26,6 @@ (define-module (gnu bootloader) #:use-module (gnu system file-systems) #:use-module (gnu system uuid) - #:use-module (guix discovery) #:use-module (guix gexp) #:use-module (guix profiles) #:use-module (guix records) @@ -79,8 +78,6 @@ (define-module (gnu bootloader) bootloader-configuration-device-tree-support? bootloader-configuration-extra-initrd - %bootloaders - lookup-bootloader-by-name efi-bootloader-chain)) @@ -287,29 +284,6 @@ (define (bootloader-configuration-targets config) ;;; Bootloaders. ;;; -(define (bootloader-modules) - "Return the list of bootloader modules." - (all-modules (map (lambda (entry) - `(,entry . "gnu/bootloader")) - %load-path) - #:warn warn-about-load-error)) - -(define %bootloaders - ;; The list of publically-known bootloaders. - (delay (fold-module-public-variables (lambda (obj result) - (if (bootloader? obj) - (cons obj result) - result)) - '() - (bootloader-modules)))) - -(define (lookup-bootloader-by-name name) - "Return the bootloader called NAME." - (or (find (lambda (bootloader) - (eq? name (bootloader-name bootloader))) - (force %bootloaders)) - (leave (G_ "~a: no such bootloader~%") name))) - (define (efi-bootloader-profile packages files hooks) "Creates a profile from the lists of PACKAGES and FILES from the store. This profile is meant to be used by the bootloader-installer. diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 881f2de104..6b6bb46975 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -11,6 +11,8 @@ ;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re> ;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2022 Tobias Geerinckx-Rice <me@tobias.gr> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -88,6 +90,7 @@ (define-module (guix scripts system) #:use-module (srfi srfi-37) #:use-module (ice-9 format) #:use-module (ice-9 match) + #:use-module (ice-9 receive) #:use-module (rnrs bytevectors) #:export (guix-system read-operating-system @@ -375,60 +378,39 @@ (define (switch-to-system-generation store spec) (activate (string-append generation "/activate"))) (if number (begin - (reinstall-bootloader store number) + (install-bootloader-from-provenance store number) (switch-to-generation* %system-profile number) (unless-file-not-found (primitive-load activate))) (leave (G_ "cannot switch to system generation '~a'~%") spec)))) -(define* (system-bootloader-name #:optional (system %system-profile)) - "Return the bootloader name stored in SYSTEM's \"parameters\" file." - (let ((params (unless-file-not-found - (read-boot-parameters-file system)))) - (boot-parameters-bootloader-name params))) - -(define (reinstall-bootloader store number) - "Re-install bootloader for existing system profile generation NUMBER. -STORE is an open connection to the store." - (let* ((generation (generation-file-name %system-profile number)) - ;; Detect the bootloader used in %system-profile. - (bootloader (lookup-bootloader-by-name (system-bootloader-name))) - - ;; Use the detected bootloader with default configuration. - ;; It will be enough to allow the system to boot. - (bootloader-config (bootloader-configuration - (bootloader bootloader))) - - ;; Make the specified system generation the default entry. - (chosen-alternative (generation->boot-alternative - %system-profile number)) - (params (boot-alternative-parameters chosen-alternative)) - (locale (boot-parameters-locale params)) - (store-crypto-devices (boot-parameters-store-crypto-devices params)) - (store-directory-prefix - (boot-parameters-store-directory-prefix params)) - (old-generations - (delv number (reverse (generation-numbers %system-profile)))) - (previous-boot-alternatives (profile->boot-alternatives - %system-profile old-generations)) - (entries (list (boot-parameters->menu-entry params))) - (old-entries (map boot-alternative->menu-entry - previous-boot-alternatives))) +(define (install-bootloader-from-os store number os) + "Re-install an old bootloader defined in <operating-system> record OS, +for system profile generation NUMBER, with store STORE." + (let* ((os (read-operating-system os)) + (bootloader-config (operating-system-bootloader os)) + (numbers (generation-numbers %system-profile)) + (numbers (delv number (reverse numbers))) + (old (profile->boot-alternatives %system-profile numbers)) + (bootcfg (operating-system-bootcfg os old))) (run-with-store store - (mlet* %store-monad - ((bootcfg (lower-object - ((bootloader-configuration-file-generator bootloader) - bootloader-config entries - #:locale locale - #:store-crypto-devices store-crypto-devices - #:store-directory-prefix store-directory-prefix - #:old-entries old-entries))) - (drvs -> (list bootcfg))) + (mlet* %store-monad ((bootcfg (lower-object bootcfg)) + (drvs -> (list bootcfg))) (mbegin %store-monad (built-derivations drvs) ;; Only install bootloader configuration file. (install-bootloader local-eval bootloader-config bootcfg #:run-installer? #f)))))) +(define (install-bootloader-from-provenance store number) + "Re-install an old bootloader using provenance data for system profile +generation NUMBER with store STORE." + (receive (_ os) + (system-provenance (generation-file-name %system-profile number)) + (if os + (install-bootloader-from-os store number os) + (leave (G_ "cannot rollback to generation '~a': no provenance~%") + number)))) + \f ;;; ;;; Graphs. @@ -1387,10 +1369,11 @@ (define (process-command command args opts) (let ((pattern (match args (() #f) ((pattern) pattern) - (x (leave (G_ "wrong number of arguments~%")))))) + (_ (leave (G_ "wrong number of arguments~%"))))) + (number (generation-number %system-profile))) (with-store* store (delete-matching-generations store %system-profile pattern) - (reinstall-bootloader store (generation-number %system-profile))))) + (install-bootloader-from-provenance store number)))) ((switch-generation) (let ((pattern (match args ((pattern) pattern) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 06/14] guix: utils: Add flatten and flat-map from haunt. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (3 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 05/14] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 07/14] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via ` (7 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice * guix/utils.scm (flatten, flat-map): Add procedures. Change-Id: I1d7d49fd02115e3de09ed69bcf5f55a10423162e --- guix/utils.scm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index f161cb4ef3..2740552a75 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -139,6 +139,9 @@ (define-module (guix utils) with-environment-variables arguments-from-environment-variable + flatten + flat-map + config-directory cache-directory @@ -1028,6 +1031,29 @@ (define (with-atomic-file-output file proc) (false-if-exception (delete-file template)) (close-port out))))) +;; TODO: bring over other utility procedures from (haunt utils). +(define* (flatten lst #:optional depth) + "Return a list that recursively concatenates the sub-lists of LST, +up to DEPTH levels deep. When DEPTH is #f, the entire tree is +flattened." + (if (and (number? depth) (zero? depth)) + lst + (fold-right (match-lambda* + (((sub-list ...) memo) + (append (flatten sub-list (and depth (1- depth))) + memo)) + ((elem memo) + (cons elem memo))) + '() + lst))) + +(define (flat-map proc . lsts) + "Apply PROC to each element of each list in LSTS and return a new +list in which nested lists are concatenated into the result. + +For example, the list (1 2 (3)) would be flattened to (1 2 3)." + (flatten (apply map proc lsts) 1)) + (define* (xdg-directory variable suffix #:key (ensure? #t)) "Return the name of the XDG directory that matches VARIABLE and SUFFIX, after making sure that it exists if ENSURE? is true. VARIABLE is an -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 07/14] guix: records: Add wrap-element procedure. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (4 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 06/14] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 08/14] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via ` (6 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Christopher Baines, Josselin Poiret, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice * guix/records.scm (wrap-element): Add procedure. Change-Id: If121c5d856e815776830282a0701a73e5ae2a7e7 --- guix/records.scm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/guix/records.scm b/guix/records.scm index c084441441..b521a59257 100644 --- a/guix/records.scm +++ b/guix/records.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012-2024 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2018 Mark H Weaver <mhw@netris.org> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -31,6 +32,8 @@ (define-module (guix records) alist->record object->fields recutils->alist + wrap-element + match-record match-record-lambda)) @@ -606,6 +609,10 @@ (define (recutils->alist port) (else (error "unmatched line" line)))))))) +(define (wrap-element x) + "Sanitize a record field value X to a list." + (if (list? x) x (list x))) + \f ;;; ;;; Pattern matching. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 08/14] gnu: bootloader: Add bootloader-target record and infastructure. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (5 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 07/14] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 09/14] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via ` (5 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Christopher Baines, Josselin Poiret, Lilah Tascheter, Ludovic Courtès, Mathieu Othacehe, Simon Tournier, Tobias Geerinckx-Rice From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (bootloader-target): New record. (&target-error): New condition. (pathcat, get-target-of-type, parent-of, unfold-pathcat, target-base?, type-major?, ensure, ensure-target-types, ensure-majors, gbegin): New procedures. (define-literal, with-targets, :path, :devpath, :device, :fs, :label, :uuid): New macros. * guix/ui.scm (call-with-error-handling)[target-error?]: Handle target-errors. Change-Id: I3f07c9096dd8b91c04449b6360b3b7d21640da14 --- gnu/bootloader.scm | 229 ++++++++++++++++++++++++++++++++++++++++++++- guix/ui.scm | 9 ++ 2 files changed, 233 insertions(+), 5 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 3ea50a4004..0c24996205 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -7,6 +7,7 @@ ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> ;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org> ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -24,19 +25,28 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu bootloader) + #:autoload (gnu build file-systems) + (read-partition-label read-partition-uuid + find-partition-by-label find-partition-by-uuid) #:use-module (gnu system file-systems) #:use-module (gnu system uuid) - #:use-module (guix gexp) - #:use-module (guix profiles) - #:use-module (guix records) + #:autoload (guix build syscalls) + (mounts mount-source mount-point mount-type) #:use-module (guix deprecation) - #:use-module ((guix ui) #:select (warn-about-load-error)) #:use-module (guix diagnostics) + #:use-module (guix gexp) #:use-module (guix i18n) + #:use-module (guix modules) + #:use-module (guix profiles) + #:use-module (guix records) + #:use-module (guix utils) + #:use-module (ice-9 match) + #:use-module (ice-9 receive) + #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) - #:use-module (ice-9 match) #:export (menu-entry menu-entry? menu-entry-label @@ -62,6 +72,25 @@ (define-module (gnu bootloader) bootloader-configuration-file bootloader-configuration-file-generator + bootloader-target + bootloader-target? + bootloader-target-type + bootloader-target-expected? + bootloader-target-path + bootloader-target-offset + bootloader-target-device + bootloader-target-file-system + bootloader-target-label + bootloader-target-uuid + + target-error? + target-error-type + target-error-targets + + gbegin + :path :devpath :device :fs :label :uuid + with-targets + bootloader-configuration bootloader-configuration? bootloader-configuration-bootloader @@ -232,6 +261,196 @@ (define-record-type* <bootloader> (configuration-file bootloader-configuration-file) (configuration-file-generator bootloader-configuration-file-generator)) +\f +;;; +;;; Bootloader target record. +;;; + +;; <bootloader-target> represents different kinds of targets in a +;; normalized form. + +(define-record-type* <bootloader-target> + bootloader-target make-bootloader-target bootloader-target? + (type bootloader-target-type) ; symbol + (expected? bootloader-target-expected? (default #f)) ; bool + + (path bootloader-target-path (default #f)) ; string|#f + (offset bootloader-target-offset (thunked) ; symbol|#f + (default (and (bootloader-target-path this-record) + (not (eq? (bootloader-target-type this-record) 'root)) + 'root))) + (device bootloader-target-device (default #f)) ; string|#f + (file-system bootloader-target-file-system (default #f)) ; string|#f + (label bootloader-target-label (default #f)) ; string|#f + (uuid bootloader-target-uuid (default #f))) ; uuid|#f + +(define-condition-type &target-error &error target-error? + (type target-error-type) + (targets target-error-targets)) + +(define (pathcat p1 p2) + (string-append (string-trim-right p1 #\/) "/" (string-trim p2 #\/))) + +(define* (get-target-of-type type targets #:optional require?) + "Finds a target in TARGETS of type TYPE, returns REQUIRE? if #false, +or provides an error otherwise." + (define (type? target) + (eq? type (bootloader-target-type target))) + (match (filter type? targets) + ((target _ ...) target) + (_ (and require? + (raise + (condition + (&message (message (G_ "required, but not provided"))) + (&target-error (type type) (targets targets)))))))) + +(define (parent-of target targets) + "Resolve the parent of TARGET in TARGETS, return #f if orphan." + (and=> (bootloader-target-offset target) + (cut get-target-of-type <> targets #t))) + +(define (unfold-pathcat target targets) + "Find the full VFS path of TARGET." + (let ((quit (lambda (t) (not (and=> t bootloader-target-path)))) + (parent-of (cut parent-of <> targets))) + (reduce pathcat #f + (unfold quit bootloader-target-path parent-of target)))) + +(define (target-base? t) + (or (not t) (match-record t <bootloader-target> + (expected? offset device label uuid) + (or device label uuid (not offset) expected?)))) + +(define (type-major? target) (memq target '(root esp disk))) + +(define (ensure types targets end) + (let* ((used-in (cute unfold end identity (cut parent-of <> targets) <>)) + (cons-in (lambda (t) (cons t (used-in t)))) + (ensure (map (cut get-target-of-type <> targets #t) types))) + (filter identity (apply append (map cons-in ensure))))) + +(define* (ensure-target-types types targets #:optional (base? #f)) + "Ensures all TYPES are provided in TARGETS. Returns #t iff every ensured +target and its requirements are fully provided. Errors out when a required TYPE +isn't provided. When BASE?, only ensure path requirements up to a device." + (not (any bootloader-target-expected? + (ensure types targets (if base? target-base? not))))) + +(define (ensure-majors types targets) + "Errors out when a required TYPE isn't provided, or when use of multiple major +targets is detected." + (let* ((all (map bootloader-target-type (ensure types targets target-base?))) + (majors (delete-duplicates (filter type-major? all) eq?))) + (if (< (length majors) 2) #t + (raise (condition (&message (message (G_ "multiple major targets used"))) + (&target-error (type majors) (targets targets))))))) + + + +(define (gbegin . gex) + "Sequence provided g-expressions." + (case (length gex) ((0) #f) ((1) (car gex)) (else #~(begin #$@gex)))) + +;; syntax matching on free literals breaks easily, so bind them +(define-syntax-rule (define-literal id) (define-syntax id (syntax-rules ()))) +(define-literal :path) +(define-literal :devpath) +(define-literal :device) +(define-literal :fs) +(define-literal :label) +(define-literal :uuid) + +(define-syntax with-targets + (cut syntax-case <> () + ((_ targets-expr block ...) + (let* ((genvars (compose generate-temporaries make-list)) + (targets (car (genvars 1)))) + (define (resolve in target base) + (with-syntax ((target target) (base base) (targets targets)) + (syntax-case in + (:path :devpath :device :fs :label :uuid) + ((name _) (not (identifier? #'name)) + #`(_ (syntax-error "binds must be to identifiers" #,in))) + ((name :device) #'(name (bootloader-target-device base))) + ((name :label) #'(name (bootloader-target-label base))) + ((name :uuid) #'(name (bootloader-target-uuid base))) + ((name :fs) #'(name (bootloader-target-file-system base))) + ((name :path) #'(name (unfold-pathcat target targets))) + ((name :devpath) + #'(name (if (target-base? target) + "/" + (pathcat "/" (bootloader-target-path target))))) + (_ #`(_ (syntax-error "invalid binding spec" #,in)))))) + + (define (binds spec) + (syntax-case spec (=>) + ((type => binds ...) + (with-syntax (((target base) (genvars 2)) (targets targets)) + (append + #`((get (lambda (t) (get-target-of-type t targets #t))) + (target (get type)) + (base (if (target-base? target) + target + (get (bootloader-target-offset target))))) + (map (cut resolve <> #'target #'base) #'(binds ...))))) + (_ #f))) + + (define blocks + (cut syntax-case <> () + ((spec ... expr) + (let* ((path? (cut syntax-case <> (:path) ((_ :path) #t) (_ #f))) + (qualified? (cut syntax-case <> (=>) + ((_ => spec ...) (any path? #'(spec ...))) + (_ #f))) + (specs #'(spec ...)) + (lets (apply append (filter-map binds specs))) + (type (cut syntax-case <> (=>) + ((t => _ ...) #'t) (t #'t)))) + (receive (full part) (partition qualified? specs) + #`(and (ensure-majors (list #,@(map type specs)) #,targets) + (ensure-target-types (list #,@(map type part)) + #,targets #t) + (ensure-target-types (list #,@(map type full)) + #,targets #f) + (let* #,lets expr))))) + (bad #'(syntax-error "malformed block" bad)))) + "Using the list TARGETS, evaluate and sequence each BLOCK to produce a +gexp. BLOCK is a set of SPECs followed by an EXPR (evaluating to a gexp). +Each SPEC denotes a type of target to guard EXPR on their existance and +full-qualification. This procedure is linear in regard to BLOCKs. + +SPEC may be of the following forms: +@itemize +@item 'TYPE Requires TYPE to be fully present or promised. Errors otherwise. +@item ('TYPE => (VAR COMPONENT) ...): As type, but also binds variables. TYPE's + COMPONENT is bound to the variable VAR as described below. +@end itemize + +Available COMPONENTs are: +@itemize +@item :path (fully-qualified) +@item :devpath (relative from device) +@item :device (auto-detected from uuid and label if not user-provided) +@item :fs +@item :label +@item :uuid +@end itemize + +Note that installers may be called multiple times with different targets being +fully-qualified. To ensure that targets aren't installed multiple times, make sure +that each BLOCK ensures at least one major target, either directly or indirectly. +Likewise, at most one major target should be ensured per BLOCK, under the same +conditions. Major targets originate from disk image handling, and are currently: +@itemize +@item disk +@item root +@item esp +@end itemize" + #`(let ((#,targets targets-expr)) + (apply gbegin (filter identity + (list #,@(map blocks #'(block ...)))))))) + (bad #'(syntax-error "must provide targets" bad)))) + \f ;;; ;;; Bootloader configuration record. diff --git a/guix/ui.scm b/guix/ui.scm index fe059ba089..663b814da6 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -19,6 +19,7 @@ ;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com> ;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info> ;;; Copyright © 2022 Liliana Marie Prikler <liliana.prikler@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -36,6 +37,8 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix ui) ;import in user interfaces only + #:use-module ((gnu bootloader) + #:select (target-error? target-error-type target-error-targets)) #:use-module (guix i18n) #:use-module (guix colors) #:use-module (guix diagnostics) @@ -862,6 +865,12 @@ (define (call-with-error-handling thunk) (invoke-error-stop-signal c) (cons (invoke-error-program c) (invoke-error-arguments c)))) + ((target-error? c) + (leave (G_ "bootloader-target '~a'~@[: ~a~] ~ + among the following targets:~%~{~y~}") + (target-error-type c) + (and (message-condition? c) (condition-message c)) + (target-error-targets c))) ((formatted-message? c) (apply report-error -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 09/14] gnu: bootloader: Add bootloader-configurations->gexp. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (6 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 08/14] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 10/14] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via ` (4 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (bootloader)[default-targets]: Add field. (target-overrides, normalize, bootloader-configuration->gexp, bootloader-configurations->gexp): New procedures. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 0c24996205..c77de6f55e 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -67,6 +67,7 @@ (define-module (gnu bootloader) bootloader? bootloader-name bootloader-package + bootloader-default-targets bootloader-installer bootloader-disk-image-installer bootloader-configuration-file @@ -107,6 +108,8 @@ (define-module (gnu bootloader) bootloader-configuration-device-tree-support? bootloader-configuration-extra-initrd + bootloader-configuration->gexp + bootloader-configurations->gexp efi-bootloader-chain)) @@ -255,6 +258,7 @@ (define-record-type* <bootloader> bootloader? (name bootloader-name) (package bootloader-package) + (default-targets bootloader-default-targets (default '())) (installer bootloader-installer) (disk-image-installer bootloader-disk-image-installer (default #f)) @@ -498,6 +502,110 @@ (define (bootloader-configuration-targets config) ;; hence the default value of '(#f) rather than '(). (list #f))) +\f +;;; +;;; Bootloader installation paths. +;;; + +(define (target-overrides . layers) + (let* ((types (flat-map (cute map bootloader-target-type <>) layers)) + ;; TODO: use loop instead of fold for early termination. + (pred (lambda (type layer found) + (or found (get-target-of-type type layer)))) + (find (lambda (type) (fold (cute pred type <> <>) #f layers)))) + (filter identity (map find (delete-duplicates types))))) + +(define (normalize targets) + "Augments TARGETS with filesystem information at runtime, allowing +users to specify a lot less information. Puts TARGETS into a normal +form, where each path is fully specified up to a device offset." + (define (mass m) + `((,(mount-source m) . ,m) + (,(mount-point m) . ,m))) + + (define (accessible=> d f) + (and d (access? d R_OK) (f d))) + + (define (fixuuid target) + (match-record target <bootloader-target> (uuid file-system) + (let ((type (cond ((not file-system) 'dce) + ((member file-system '("vfat" "fat32")) 'fat) + ((string=? file-system "ntfs") 'ntfs) + ((string=? file-system "iso9660") 'iso9660) + (else 'dce)))) + (bootloader-target (inherit target) + (uuid (cond ((uuid? uuid) uuid) + ((bytevector? uuid) (bytevector->uuid uuid type)) + ((string? uuid) (string->uuid uuid type)) + (else #f))))))) + + (define (arborify target targets) + (let* ((up (lambda (t) (and t (parent-of t targets)))) + (proto (unfold target-base? identity up (up target) list)) + (chain (reverse (cons target proto)))) + (bootloader-target + (inherit target) + (offset (and=> (car chain) bootloader-target-type)) + (path (reduce pathcat #f (map bootloader-target-path (cdr chain))))))) + + (let ((amounts (delay (apply append (map mass (mounts)))))) + (define (assoc-mnt f) + (lambda (v) (and=> (assoc-ref (force amounts) v) f))) + + (define (scrape target) + (match-record target <bootloader-target> + (expected? path offset device label uuid file-system) + (if expected? target + (bootloader-target + (inherit target) + (device (or device + (false-if-exception + (or (and=> uuid find-partition-by-uuid) + (and=> label find-partition-by-label))) + (and path ((assoc-mnt mount-source) + (unfold-pathcat target targets))))) + (label (or label (accessible=> device read-partition-label))) + (uuid (or uuid (accessible=> device read-partition-uuid))) + (file-system (or file-system (and=> device (assoc-mnt mount-type)))) + (offset (and path offset)) + (path (or path (and=> device (assoc-mnt mount-point)))))))) + + (let ((mid (map (compose fixuuid scrape) targets))) + (map (cut arborify <> mid) mid)))) + +(define* (bootloader-configuration->gexp bootloader-config args #:key + (root-offset "/") (overrides '())) + "Returns a gexp to install BOOTLOADER-CONFIG to its targets, passing ARGS +to each installer alongside the additional #:bootloader-config keyword +arguments. Target OVERRIDES are applied and all path targets have ROOT-OFFSET +applied. The following keyword arguments are expected in ARGS: +@enumerate +@item current-boot-alternative +@item old-boot-alternatives +@item locale (from bootmeta) +@item store-directory-prefix (from bootmeta) +@item store-crypto-devices (from bootmeta) +@end enumerate" + (let* ((bootloader (bootloader-configuration-bootloader bootloader-config)) + (installer (bootloader-installer bootloader)) + (auto-targets (list (bootloader-target + (type 'root) + (path root-offset) + (offset #f)))) + (targets (target-overrides + overrides + (bootloader-configuration-targets bootloader-config) + auto-targets + (bootloader-default-targets bootloader))) + (conf (bootloader-configuration + (inherit bootloader-config) + (targets (normalize targets))))) + (apply installer #:bootloader-config conf args))) + +(define (bootloader-configurations->gexp bootloader-configs . rest) + (apply gbegin (filter-map (cut apply bootloader-configuration->gexp <> rest) + bootloader-configs))) + \f ;;; ;;; Bootloaders. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 10/14] gnu: bootloader: Add device-subvol field to menu-entry record. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (7 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 09/14] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 11/14] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via ` (3 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (menu-entry-device-subvol): Add and export field. (normalize-file): Add procedure. (device->sexp): Match device-subvol and include in S-expression. (sexp->menu-entry): Try match device-subvol and include in menu-entry. * gnu/system/boot.scm (boot-parameters->menu-entry): Add device-subvol value to menu-entry. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/bootloader.scm | 51 ++++++++++++++++++++++++++++++++++----------- gnu/system/boot.scm | 1 + 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index c77de6f55e..f1352122a9 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -51,15 +51,17 @@ (define-module (gnu bootloader) menu-entry? menu-entry-label menu-entry-device + menu-entry-device-mount-point + menu-entry-device-subvol menu-entry-linux menu-entry-linux-arguments menu-entry-initrd - menu-entry-device-mount-point menu-entry-multiboot-kernel menu-entry-multiboot-arguments menu-entry-multiboot-modules menu-entry-chain-loader + normalize-file menu-entry->sexp sexp->menu-entry @@ -126,6 +128,8 @@ (define-record-type* <menu-entry> (default #f)) (device-mount-point menu-entry-device-mount-point (default #f)) + (device-subvol menu-entry-device-subvol + (default #f)) (linux menu-entry-linux (default #f)) (linux-arguments menu-entry-linux-arguments @@ -142,6 +146,18 @@ (define-record-type* <menu-entry> (chain-loader menu-entry-chain-loader (default #f))) ; string, path of efi file +(define (normalize-file entry file) + "Normalize a file FILE stored in a menu entry into one suitable for a +bootloader. Realizes device-mount-point and device-subvol." + (match-menu-entry entry (device-mount-point device-subvol) + ;; Avoid using cut procedure from SRFI-26 inside G-exp. + (let ((mount (and=> device-mount-point (cut string-trim <> #\/)))) + #~(let* ((file (string-trim #$file #\/)) + (file (if (and #$mount (string-prefix? #$mount file)) + (substring file (string-length #$mount)) + file))) + (string-append (or #$device-subvol "") "/" file))))) + (define (report-menu-entry-error menu-entry) (raise (condition @@ -169,7 +185,7 @@ (define (menu-entry->sexp entry) `(label ,(file-system-label->string label))) (_ device))) (match entry - (($ <menu-entry> label device mount-point + (($ <menu-entry> label device mount-point subvol (? identity linux) linux-arguments (? identity initrd) #f () () #f) `(menu-entry (version 0) @@ -178,8 +194,9 @@ (define (menu-entry->sexp entry) (device-mount-point ,mount-point) (linux ,linux) (linux-arguments ,linux-arguments) - (initrd ,initrd))) - (($ <menu-entry> label device mount-point #f () #f + (initrd ,initrd) + (device-subvol ,subvol))) + (($ <menu-entry> label device mount-point subvol #f () #f (? identity multiboot-kernel) multiboot-arguments multiboot-modules #f) `(menu-entry (version 0) @@ -188,19 +205,23 @@ (define (menu-entry->sexp entry) (device-mount-point ,mount-point) (multiboot-kernel ,multiboot-kernel) (multiboot-arguments ,multiboot-arguments) - (multiboot-modules ,multiboot-modules))) - (($ <menu-entry> label device mount-point #f () #f #f () () + (multiboot-modules ,multiboot-modules) + (device-subvol ,subvol))) + (($ <menu-entry> label device mount-point subvol #f () #f #f () () (? identity chain-loader)) `(menu-entry (version 0) (label ,label) (device ,(device->sexp device)) (device-mount-point ,mount-point) - (chain-loader ,chain-loader))) + (chain-loader ,chain-loader) + (device-subvol ,subvol))) (_ (report-menu-entry-error entry)))) (define (sexp->menu-entry sexp) "Turn SEXP, an sexp as returned by 'menu-entry->sexp', into a <menu-entry> record." + ;; XXX: The match ORs shadow subvol. + (define subvol #f) (define (sexp->device device-sexp) (match device-sexp (('uuid type uuid-string) @@ -213,35 +234,41 @@ (define (sexp->menu-entry sexp) ('label label) ('device device) ('device-mount-point mount-point) ('linux linux) ('linux-arguments linux-arguments) - ('initrd initrd) _ ...) + ('initrd initrd) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (linux linux) (linux-arguments linux-arguments) (initrd initrd))) (('menu-entry ('version 0) ('label label) ('device device) - ('device-mount-point mount-point) + ('device-mount-point mount-point) ('device-subvol subvol) ('multiboot-kernel multiboot-kernel) ('multiboot-arguments multiboot-arguments) - ('multiboot-modules multiboot-modules) _ ...) + ('multiboot-modules multiboot-modules) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (multiboot-kernel multiboot-kernel) (multiboot-arguments multiboot-arguments) (multiboot-modules multiboot-modules))) (('menu-entry ('version 0) ('label label) ('device device) - ('device-mount-point mount-point) - ('chain-loader chain-loader) _ ...) + ('device-mount-point mount-point) ('device-subvol subvol) + ('chain-loader chain-loader) + (or ('device-subvol subvol _ ...) (_ ...))) (menu-entry (label label) (device (sexp->device device)) (device-mount-point mount-point) + (device-subvol subvol) (chain-loader chain-loader))))) \f diff --git a/gnu/system/boot.scm b/gnu/system/boot.scm index 54e5673a54..98fcd2b3a0 100644 --- a/gnu/system/boot.scm +++ b/gnu/system/boot.scm @@ -328,6 +328,7 @@ (define (boot-parameters->menu-entry conf) (label (boot-parameters-label conf)) (device (boot-parameters-store-device conf)) (device-mount-point (boot-parameters-store-mount-point conf)) + (device-subvol (boot-parameters-store-directory-prefix conf)) (linux (and (not multiboot?) kernel)) (linux-arguments (if (not multiboot?) (boot-parameters-kernel-arguments conf) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 11/14] gnu: build: bootloader: Add efi-bootnums procedure. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (8 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 10/14] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 12/14] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via ` (2 subsequent siblings) 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> * gnu/build/bootloader.scm (atomic-copy, efi-bootnums): Add procedures. (in-temporary-directory): Add macro. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- gnu/build/bootloader.scm | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm index af6063a884..3934e03aee 100644 --- a/gnu/build/bootloader.scm +++ b/gnu/build/bootloader.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> ;;; Copyright © 2022 Timothy Sample <samplet@ngyro.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -20,13 +21,25 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu build bootloader) + #:autoload (guix build syscalls) (free-disk-space) #:use-module (guix build utils) #:use-module (guix utils) #:use-module (ice-9 binary-ports) + #:use-module (guix diagnostics) + #:use-module (guix i18n) #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (ice-9 popen) + #:use-module (ice-9 receive) + #:use-module (ice-9 regex) #:use-module (rnrs io ports) #:use-module (rnrs io simple) - #:export (write-file-on-device + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-35) + #:export (atomic-copy + in-temporary-directory + write-file-on-device install-efi-loader)) \f @@ -34,6 +47,21 @@ (define-module (gnu build bootloader) ;;; Writing utils. ;;; +(define (atomic-copy from to) + (let ((pivot (string-append to ".new"))) + (copy-file from pivot) + (rename-file pivot to))) + +(define-syntax-rule (in-temporary-directory blocks ...) + "Run BLOCKS while chdir'd into a temporary directory." + ;; Under POSIX.1-2008, mkdtemp must make the dir with 700 perms. + (let* ((tmp (or (getenv "TMPDIR") "/tmp")) + (dir (mkdtemp (string-append tmp "/guix-bootloader.XXXXXX"))) + (cwd (getcwd))) + (dynamic-wind (lambda () (chdir dir)) + (lambda () blocks ...) + (lambda () (chdir cwd) (delete-file-recursively dir))))) + (define (write-file-on-device file size device offset) "Write SIZE bytes from FILE to DEVICE starting at OFFSET." (call-with-input-file file @@ -56,6 +84,24 @@ (define (write-file-on-device file size device offset) ;;; EFI bootloader. ;;; +;; XXX: Parsing efibootmgr output may be kinda jank. A better way may exist. +(define (efi-bootnums efibootmgr) + "Returns '(path . bootnum) pairs for each EFI boot entry. bootnum is +a string, and path is backslash-deliminated and relative to the ESP." + (let* ((pipe (open-pipe* OPEN_READ efibootmgr)) + (text (get-string-all pipe)) + (status (status:exit-val (close-pipe pipe))) + (bootnum-pattern + "^Boot([0-9a-fA-F]+).*[^A-Za-z]File\\(([^)]+)\\)$")) + (unless (zero? status) + (raise-exception + (formatted-message (G_ "efibootmgr exited with error code ~a") status))) + (fold-matches (make-regexp bootnum-pattern regexp/newline) text '() + (lambda (match acc) + (let* ((path (match:substring match 2)) + (bootnum (match:substring match 1))) + (cons (cons path bootnum) acc)))))) + (define* (install-efi grub grub-config esp #:key targets) "Write a self-contained GRUB EFI loader to the mounted ESP using GRUB-CONFIG. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 12/14] gnu: bootloader: Install any bootloader to ESP. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (9 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 11/14] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 13/14] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 14/14] teams: Add bootloading team Herman Rimm via Guix-patches via 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202 Cc: Lilah Tascheter, Florian Pelz, Lilah Tascheter, Ludovic Courtès, Maxim Cournoyer From: Lilah Tascheter <lilah@lunabee.space> * gnu/bootloader.scm (efi-arch, install-efi): New procedures. (%efi-supported-systems, lazy-efibootmgr): New variables. (bootloader-configuration)[efi-removable?, 32bit?]: New fields. (match-bootloader-configuration, match-menu-entry): New macros. * gnu/build/bootloader.scm (install-efi-loader): Delete procedure. (install-efi): Rewrite to support installation of any efi bootloader. * gnu/build/image.scm (initialize-efi32-partition): Deprecate. (initialize-efi-partitition): Only create EFI directory. * gnu/image.scm (partition)[target]: New field in order to support dynamic provision of image partitions as bootloader targets. * gnu/system/image.scm (root-partition, esp-partition): Use target field. * gnu/system/image.scm (esp32-partition, efi32-disk-partition, efi32-raw-image-type): Deprecate. * doc/guix.texi (Creating System Images)[image Reference]<partition Reference>: Add target field. [Instantiate an Image]: Update examples and update formatting. <efi32-disk-image, efi32-raw-image-type>: Delete. <pinebook-pro-image-type, rock64-image-type>: Reword slightly. Change-Id: I3654d160f7306bb45a78b82ea6b249ff4281f739 --- doc/guix.texi | 34 ++++++------ gnu/bootloader.scm | 56 ++++++++++++++++++- gnu/build/bootloader.scm | 115 ++++++++++++++++++++------------------- gnu/build/image.scm | 23 ++------ gnu/image.scm | 4 ++ gnu/system/image.scm | 22 +++----- 6 files changed, 150 insertions(+), 104 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 38a4650977..2f6d72f793 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -130,6 +130,7 @@ Copyright @copyright{} 2024 Dariqq@* Copyright @copyright{} 2024 Denis 'GNUtoo' Carikli@* Copyright @copyright{} 2024 Fabio Natali@* +Copyright @copyright{} 2024 Lilah Tascheter@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -48163,6 +48164,12 @@ partition Reference this flag set, usually the root one. The @code{'esp} flag identifies a UEFI System Partition. +@item @code{target} (default: @var{#f}) +If provided, this partition provides itself as a bootloader target +(@pxref{Bootloader Configuration}). Most commonly, this is used to provide the +@code{'root} and @code{'esp} targets, with the root partition and EFI System +Partition, respectively, though this can provide any target necessary. + @item @code{initializer} (default: @code{#false}) The partition initializer procedure as a gexp. This procedure is called to populate a partition. If no initializer is passed, the @@ -48211,6 +48218,7 @@ Instantiate an Image (label "GNU-ESP") (file-system "vfat") (flags '(esp)) + (target 'esp) (initializer (gexp initialize-efi-partition))) (partition (size (* 50 MiB)) @@ -48227,15 +48235,17 @@ Instantiate an Image (label root-label) (file-system "ext4") (flags '(boot)) + (target 'root) (initializer (gexp initialize-root-partition)))))) @end lisp -Note that the first and third partitions use generic initializers -procedures, initialize-efi-partition and initialize-root-partition -respectively. The initialize-efi-partition installs a GRUB EFI loader -that is loading the GRUB bootloader located in the root partition. The -initialize-root-partition instantiates a complete system as defined by -the @code{%simple-os} operating-system. +Note that the first and third partitions use generic initializer +procedures, @code{initialize-efi-partition} and +@code{initialize-root-partition} respectively. +@code{initialize-efi-partition} simply creates the directory structure +for an EFI bootloader to install itself to. +@code{initialize-root-partition} instantiates a complete system as +defined by the @code{%simple-os} operating-system. You can now run: @@ -48292,10 +48302,6 @@ Instantiate an Image @code{i686} machines, supporting BIOS or UEFI booting. @end defvar -@defvar efi32-disk-image -Same as @code{efi-disk-image} but with a 32 bits EFI partition. -@end defvar - @defvar iso9660-image An ISO-9660 image composed of a single bootable partition. This image can also be used on most @code{x86_64} and @code{i686} machines. @@ -48386,10 +48392,6 @@ image-type Reference Build an image based on the @code{efi-disk-image} image. @end defvar -@defvar efi32-raw-image-type -Build an image based on the @code{efi32-disk-image} image. -@end defvar - @defvar qcow2-image-type Build an image based on the @code{mbr-disk-image} image but with the @code{compressed-qcow2} image format. @@ -48417,14 +48419,14 @@ image-type Reference @defvar pinebook-pro-image-type Build an image that is targeting the Pinebook Pro machine. The MBR image contains a single partition starting at a @code{9MiB} offset. The -@code{u-boot-pinebook-pro-rk3399-bootloader} bootloader will be +@code{u-boot-pinebook-pro-rk3399-bootloader} bootloader can be installed in this gap. @end defvar @defvar rock64-image-type Build an image that is targeting the Rock64 machine. The MBR image contains a single partition starting at a @code{16MiB} offset. The -@code{u-boot-rock64-rk3328-bootloader} bootloader will be installed in +@code{u-boot-rock64-rk3328-bootloader} bootloader can be installed in this gap. @end defvar diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index f1352122a9..6b08e61492 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -100,6 +100,8 @@ (define-module (gnu bootloader) bootloader-configuration-targets bootloader-configuration-menu-entries bootloader-configuration-default-entry + bootloader-configuration-efi-removable? + bootloader-configuration-32bit? bootloader-configuration-timeout bootloader-configuration-keyboard-layout bootloader-configuration-theme @@ -113,6 +115,9 @@ (define-module (gnu bootloader) bootloader-configuration->gexp bootloader-configurations->gexp + %efi-supported-systems + efi-arch + install-efi efi-bootloader-chain)) \f @@ -502,6 +507,10 @@ (define-record-type* <bootloader-configuration> (default '())) ;list of <menu-entry> (default-entry bootloader-configuration-default-entry (default 0)) ;integer + (efi-removable? bootloader-configuration-efi-removable? + (default #f)) ;bool + (32bit? bootloader-configuration-32bit? + (default #f)) ;bool (timeout bootloader-configuration-timeout (default 5)) ;seconds as integer (keyboard-layout bootloader-configuration-keyboard-layout @@ -635,9 +644,54 @@ (define (bootloader-configurations->gexp bootloader-configs . rest) \f ;;; -;;; Bootloaders. +;;; Bootloader installation to ESP. ;;; +;; systems currently supported by efi-arch. should be used for packages relying +;; on it. +(define %efi-supported-systems + '("i686-linux" "x86_64-linux" "armhf-linux" "aarch64-linux" "riscv64-linux")) + +(define* (efi-arch #:key (target (or (%current-target-system) (%current-system))) + (32? #f)) + "Returns the UEFI architecture name for the current target, in lowercase." + (cond ((target-x86-32? target) "ia32") + ((target-x86-64? target) (if 32? "ia32" "x64")) + ((target-arm32? target) "arm") + ((target-aarch64? target) (if 32? "arm" "aa64")) + ((target-riscv64? target) (if 32? "riscv32" "riscv64")) + (else (raise (formatted-message (G_ "no UEFI standard arch for ~a!") + target))))) + +(define (lazy-efibootmgr) + "Lazy-loaded efibootmgr package, in order to prevent circular refs." + (module-ref (resolve-interface '(gnu packages linux)) 'efibootmgr)) + +(define (install-efi bootloader-config plan) + "Returns a gexp installing PLAN to the ESP, as denoted by the 'vendir target. +PLAN is a gexp of a list of '(BUILDER DEST-BASENAME . LABEL) triples, that +should be in boot order. If the user selects a removable bootloader, only the +first entry in PLAN is used." + (match-record bootloader-config <bootloader-configuration> + (targets efi-removable? 32bit?) + (if efi-removable? + ;; Hard code the output location to a well-known path recognized by + ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour": + ;; http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf + (with-targets targets + (('esp => (path :path)) + #~(let ((boot #$(string-append path "/EFI/BOOT")) + (arch #$(string-upcase (efi-arch #:32? 32bit?))) + (builder (car (car #$plan)))) + (mkdir-p boot) + ;; Only realize the first planspec. + (builder (string-append boot "/BOOT" arch ".EFI"))))) + ;; Install normally if not configured as removable. + (with-targets targets + (('vendir => (vendir :path) (loader :devpath) (disk :device)) + #~(install-efi #+(file-append (lazy-efibootmgr) "/sbin/efibootmgr") + #$vendir #$loader #$disk #$plan)))))) + (define (efi-bootloader-profile packages files hooks) "Creates a profile from the lists of PACKAGES and FILES from the store. This profile is meant to be used by the bootloader-installer. diff --git a/gnu/build/bootloader.scm b/gnu/build/bootloader.scm index 3934e03aee..064466bd33 100644 --- a/gnu/build/bootloader.scm +++ b/gnu/build/bootloader.scm @@ -23,8 +23,6 @@ (define-module (gnu build bootloader) #:autoload (guix build syscalls) (free-disk-space) #:use-module (guix build utils) - #:use-module (guix utils) - #:use-module (ice-9 binary-ports) #:use-module (guix diagnostics) #:use-module (guix i18n) #:use-module (ice-9 format) @@ -40,7 +38,7 @@ (define-module (gnu build bootloader) #:export (atomic-copy in-temporary-directory write-file-on-device - install-efi-loader)) + install-efi)) \f ;;; @@ -102,57 +100,62 @@ (define (efi-bootnums efibootmgr) (bootnum (match:substring match 1))) (cons (cons path bootnum) acc)))))) -(define* (install-efi grub grub-config esp #:key targets) - "Write a self-contained GRUB EFI loader to the mounted ESP using -GRUB-CONFIG. - -If TARGETS is set, use its car as the GRUB image format and its cdr as -the output filename. Otherwise, use defaults for the host platform." - (let* ((system %host-type) - ;; Hard code the output location to a well-known path recognized by - ;; compliant firmware. See "3.5.1.1 Removable Media Boot Behaviour": - ;; http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf - (grub-mkstandalone (string-append grub "/bin/grub-mkstandalone")) - (efi-directory (string-append esp "/EFI/BOOT")) - ;; Map grub target names to boot file names. - (efi-targets (or targets - (cond ((string-prefix? "x86_64" system) - '("x86_64-efi" . "BOOTX64.EFI")) - ((string-prefix? "i686" system) - '("i386-efi" . "BOOTIA32.EFI")) - ((string-prefix? "armhf" system) - '("arm-efi" . "BOOTARM.EFI")) - ((string-prefix? "aarch64" system) - '("arm64-efi" . "BOOTAA64.EFI")))))) - ;; grub-mkstandalone requires a TMPDIR to prepare the firmware image. - (setenv "TMPDIR" esp) - - (mkdir-p efi-directory) - (invoke grub-mkstandalone "-O" (car efi-targets) - "-o" (string-append efi-directory "/" - (cdr efi-targets)) - ;; Graft the configuration file onto the image. - (string-append "boot/grub/grub.cfg=" grub-config)))) - -(define* (install-efi-loader grub-efi esp #:key targets) - "Install in ESP directory the given GRUB-EFI bootloader. Configure it to -load the Grub bootloader located in the 'Guix_image' root partition. - -If TARGETS is set, use its car as the GRUB image format and its cdr as -the output filename. Otherwise, use defaults for the host platform." - (let ((grub-config "grub.cfg")) - (call-with-output-file grub-config - (lambda (port) - ;; Create a tiny configuration file telling the embedded grub where to - ;; load the real thing. XXX This is quite fragile, and can prevent - ;; the image from booting when there's more than one volume with this - ;; label present. Reproducible almost-UUIDs could reduce the risk - ;; (not eliminate it). - (format port - "insmod part_msdos~@ - insmod part_gpt~@ - search --set=root --label Guix_image~@ - configfile /boot/grub/grub.cfg~%"))) - (install-efi grub-efi grub-config esp #:targets targets) - (delete-file grub-config))) +(define (install-efi efibootmgr vendir loader* disk plan) + "See also install-efi in (gnu bootloader)." + (let* ((loader (string-map (match-lambda (#\/ #\\) (x x)) loader*)) + (bootnums (filter (compose (cut string-prefix? loader <>) car) + (efi-bootnums efibootmgr))) + (plan-files (map cadr plan))) + (define (size file) (if (file-exists? file) (stat:size (stat file)) 0)) + (define (vendirof file) (string-append vendir "/" file)) + (define (loaderof file) (string-append loader "\\" file)) + (define (delete-boot num file) + (invoke efibootmgr "--quiet" "--bootnum" num "--delete-bootnum") + (when (file-exists? file) (delete-file file))) + (mkdir-p vendir) + ;; Delete old entries first, to clear up space. + (for-each (lambda (spec) ; '(path . bootnum) + (let* ((s (substring (car spec) (string-length loader))) + (file (substring s (if (string-prefix? "\\" s) 1 0)))) + (unless (member file plan-files) + (delete-boot (cdr spec) (vendirof file))))) + bootnums) + ;; New and updated entries. + (in-temporary-directory + (for-each + (lambda (spec) + (let* ((builder (car spec)) (name (cadr spec)) + (dest (vendirof name)) (loadest (loaderof name)) + (rest (reverse (cdr (member name plan-files))))) + ;; Build to a temporary file so we can check its size. + (builder name) + ;; Disk space is usually limited on ESPs. + ;; Try to clear space as we install new bootloaders. + (if (while (> (- (size name) (size dest)) (free-disk-space vendir)) + (let ((del (find (compose file-exists? vendirof) rest))) + (if del (delete-file (vendirof del)) (break #t)))) + (begin + (and=> (assoc-ref bootnums loadest) (cut delete-boot <> dest)) + (warning (G_ "ESP too small for bootloader ~a!~%") name)) + ;; The ESP is too small for atomic copy. + (begin + (copy-file name dest) + (unless (assoc loadest bootnums) + (invoke + efibootmgr "--quiet" "--create-only" "--label" + (cddr spec) "--disk" disk "--loader" loadest)))) + (delete-file name))) + plan)) + ;; Verify that at least the first entry was installed. + (unless (file-exists? (vendirof (cadr (car plan)))) + ;; Extremely fatal error so we use leave instead of raise. + (leave (G_ "not enough space in ESP to install bootloader! + SYSTEM WILL NOT BOOT UNLESS THIS IS FIXED!~%"))) + ;; Some UEFI systems will refuse to acknowledge the existence of boot + ;; entries unless they're in bootorder, so just shove everything in there. + (invoke + efibootmgr "--quiet" "--bootorder" + ;; Recall efi-bootnums to get a fresh list with new installs. + (let ((num (cute assoc-ref (efi-bootnums efibootmgr) <>))) ; cute is eager + (string-join (filter-map (compose num loaderof) plan-files) ","))))) diff --git a/gnu/build/image.scm b/gnu/build/image.scm index 6ca0a428e0..1b2d4da814 100644 --- a/gnu/build/image.scm +++ b/gnu/build/image.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2022 Pavel Shlyak <p.shlyak@pantherx.org> ;;; Copyright © 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -28,6 +29,7 @@ (define-module (gnu build image) #:use-module (guix build store-copy) #:use-module (guix build syscalls) #:use-module (guix build utils) + #:use-module (guix deprecation) #:use-module (guix store database) #:use-module (guix utils) #:use-module (gnu build bootloader) @@ -181,23 +183,10 @@ (define* (register-closure prefix closure #:prefix prefix #:registration-time %epoch))))) -(define* (initialize-efi-partition root - #:key - grub-efi - #:allow-other-keys) - "Install in ROOT directory, an EFI loader using GRUB-EFI." - (install-efi-loader grub-efi root)) - -(define* (initialize-efi32-partition root - #:key - grub-efi32 - #:allow-other-keys) - "Install in ROOT directory, an EFI 32bit loader using GRUB-EFI32." - (install-efi-loader grub-efi32 root - #:targets (cond ((target-x86?) - '("i386-efi" . "BOOTIA32.EFI")) - ((target-arm?) - '("arm-efi" . "BOOTARM.EFI"))))) +(define (initialize-efi-partition root . rest) + (mkdir-p (string-append root "/EFI"))) + +(define-deprecated/alias initialize-efi32-partition initialize-efi-partition) (define* (initialize-root-partition root #:key diff --git a/gnu/image.scm b/gnu/image.scm index 7fb06dec10..c6cc264147 100644 --- a/gnu/image.scm +++ b/gnu/image.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2020, 2022 Mathieu Othacehe <othacehe@gnu.org> ;;; Copyright © 2023 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -35,6 +36,7 @@ (define-module (gnu image) partition-label partition-uuid partition-flags + partition-target partition-initializer image @@ -131,6 +133,8 @@ (define-record-type* <partition> partition make-partition (flags partition-flags (default '()) ;list of symbols (sanitize validate-partition-flags)) + (target partition-target ; bootloader target type: symbol | #f + (default #f)) (initializer partition-initializer (default #false))) ;gexp | #false diff --git a/gnu/system/image.scm b/gnu/system/image.scm index b0c96c60f0..8ac91800ad 100644 --- a/gnu/system/image.scm +++ b/gnu/system/image.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2022 Alex Griffin <a@ajgrf.com> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2023 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> ;;; ;;; This file is part of GNU Guix. ;;; @@ -23,6 +24,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu system image) + #:use-module (guix deprecation) #:use-module (guix diagnostics) #:use-module (guix discovery) #:use-module (guix gexp) @@ -133,12 +135,10 @@ (define esp-partition ;; FAT-ness is based on file system size (16 in this case). (file-system "vfat") (flags '(esp)) - (initializer (gexp initialize-efi-partition)))) + (target 'esp) + (initializer #~initialize-efi-partition))) -(define esp32-partition - (partition - (inherit esp-partition) - (initializer (gexp initialize-efi32-partition)))) +(define-deprecated/alias esp32-partition esp-partition) (define root-partition (partition @@ -149,6 +149,7 @@ (define root-partition ;; with U-Boot. (file-system-options (list "-O" "^metadata_csum,^64bit")) (flags '(boot)) + (target 'root) (initializer (gexp initialize-root-partition)))) (define mbr-disk-image @@ -173,11 +174,7 @@ (define efi-disk-image (partition-table-type 'gpt) (partitions (list esp-partition root-partition)))) -(define efi32-disk-image - (image-without-os - (format 'disk-image) - (partition-table-type 'gpt) - (partitions (list esp32-partition root-partition)))) +(define-deprecated/alias efi32-disk-image efi-disk-image) (define iso9660-image (image-without-os @@ -238,10 +235,7 @@ (define efi-raw-image-type (name 'efi-raw) (constructor (cut image-with-os efi-disk-image <>)))) -(define efi32-raw-image-type - (image-type - (name 'efi32-raw) - (constructor (cut image-with-os efi32-disk-image <>)))) +(define-deprecated/alias efi32-raw-image-type efi-raw-image-type) (define qcow2-image-type (image-type -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 13/14] gnu: bootloader: Match records outside the module. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (10 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 12/14] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 14/14] teams: Add bootloading team Herman Rimm via Guix-patches via 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter * gnu/bootloader.scm (match-bootloader-configuration, match-menu-entry): Add macros. Change-Id: I42cb7541045314c37ffef98fe6efe7f46acd9d9b --- gnu/bootloader.scm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm index 6b08e61492..b1ed187aa2 100644 --- a/gnu/bootloader.scm +++ b/gnu/bootloader.scm @@ -8,6 +8,7 @@ ;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org> ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; Copyright © 2024 Lilah Tascheter <lilah@lunabee.space> +;;; Copyright © 2024 Herman Rimm <herman@rimm.ee> ;;; ;;; This file is part of GNU Guix. ;;; @@ -115,6 +116,9 @@ (define-module (gnu bootloader) bootloader-configuration->gexp bootloader-configurations->gexp + match-bootloader-configuration + match-menu-entry + %efi-supported-systems efi-arch install-efi @@ -642,6 +646,20 @@ (define (bootloader-configurations->gexp bootloader-configs . rest) (apply gbegin (filter-map (cut apply bootloader-configuration->gexp <> rest) bootloader-configs))) +;; In lieu of exporting bootloader-configuration and menu-entry RTDs. +(define-syntax match-bootloader-configuration + (syntax-rules () + "Bind each BOOTLOADER-CONFIGURATION field in FIELDS." + ((_ bootloader-configuration (fields ...) body ...) + (match-record bootloader-configuration <bootloader-configuration> + (fields ...) body ...)))) + +(define-syntax match-menu-entry + (syntax-rules () + "Bind each MENU-ENTRY field in FIELDS." + ((_ menu-entry (fields ...) body ...) + (match-record menu-entry <menu-entry> (fields ...) body ...)))) + \f ;;; ;;; Bootloader installation to ESP. -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH v3 14/14] teams: Add bootloading team. 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via ` (11 preceding siblings ...) 2024-09-26 10:09 ` [bug#73202] [PATCH v3 13/14] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via @ 2024-09-26 10:09 ` Herman Rimm via Guix-patches via 12 siblings, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-09-26 10:09 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter From: Lilah Tascheter <lilah@lunabee.space> Might as well, to help ease the transition. * etc/teams.scm (bootloaders): New team. (Lilah Tascheter): Create and add to above. Change-Id: I63620f4e3151bb8e3d0bdf619fc70501af6397a0 --- etc/teams.scm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/etc/teams.scm b/etc/teams.scm index 9239021b39..2150a7aad1 100755 --- a/etc/teams.scm +++ b/etc/teams.scm @@ -328,6 +328,12 @@ (define-team embedded #:scope (list "gnu/packages/bootloaders.scm" "gnu/packages/firmware.scm"))) +(define-team bootloaders + (team 'bootloaders + #:name "Bootloaders" + #:scope (list "gnu/bootloader.scm" + (make-regexp* "^gnu/bootloader/")))) + (define-team rust (team 'rust #:name "Rust" @@ -749,6 +755,10 @@ (define-member (person "André Batista" "nandre@riseup.net") mozilla) +(define-member (person "Lilah Tascheter" + "lilah@lunabee.space") + bootloaders) + \f (define (find-team name) (or (hash-ref %teams (string->symbol name)) -- 2.45.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-09-12 16:58 [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via ` (2 preceding siblings ...) 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via @ 2024-10-03 20:32 ` Herman Rimm via Guix-patches via 2024-10-04 5:07 ` Lilah Tascheter via Guix-patches 3 siblings, 1 reply; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-10-03 20:32 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter Hi Lilah, I wrote a series of annotated Guile code snippets, regarding an alternative implementation of bootloader-target, and example user configuration (with tftp/NFS). See below, and please let me know what you think. Cheers, Herman ;; In (gnu bootloader grub): (define (grub-efi-default-targets esp) (tree->target ; like arborify (bootloader-target (type 'esp) (path esp) (targets ; counterpart of offset (list (bootloader-target (type 'vendir) (path "EFI/Guix")) (bootloader-target (type 'install) (path "grub"))))))) ;; This is the same as (grub-efi-default-targets "boot"). It could be ;; exported standalone, instead of using bootloader default-targets. (define %grub-efi-default-targets '((esp . "/boot") (install . "/boot/EFI/Guix") (vendir . "/boot/grub"))) ;; A simple consequence of this change is that this: (with-targets %grub-efi-default-targets (('install => (path :path)) ...)) ;; becomes: (let ((install-path (assoc-ref %grub-efi-default-targets 'install))) ...) ;; But e.g. device is provided separately (or derived from path): (with-targets %grub-efi-default-targets (('esp => (device :device)) ...)) ;; becomes: (let* ((path (assoc-ref %grub-efi-default-targets 'esp)) ;; A single root-device is provided in addition to targets. (device (root-device->block-device root-device path))) ...) ;; This procedure is in (gnu bootloader). Something like: (define (root-device->block-device device path) (match device ((? block-device?) device) ; string with /dev/ prefix ((? uuid?) (find-partition-for-uuid device)) ((? string?) (find-partition-for-label device)) ;; This might be necessary, but should not be relied on. (_ (mount-source (find-mount path))))) ;; Example user configuration: (define %grub-efi-bootloader (bootloader-configuration (bootloader grub-efi-bootloader) ;; This is for bootloader configuration (not installation), e.g. ;; GRUB search or install-efi disk argument. (root-device "UUID, label, or block device.") ;; This is complementary to root-device. It will configure some ;; files to be fetched remotely instead of installed. (tftp "Varies for UEFI/GRUB/U-Boot."))) (operating-system (bootloader (list %grub-efi-bootloader)) ;; This is shared between bootloaders. Ideally, it does not affect ;; which files are installed or their contents, but only the location. (bootloader-targets (grub-efi-default-targets "boot"))) ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-03 20:32 ` [bug#73202] [PATCH] Preparation for bootloader rewrite Herman Rimm via Guix-patches via @ 2024-10-04 5:07 ` Lilah Tascheter via Guix-patches 2024-10-04 13:55 ` Herman Rimm via Guix-patches via 0 siblings, 1 reply; 41+ messages in thread From: Lilah Tascheter via Guix-patches @ 2024-10-04 5:07 UTC (permalink / raw) To: 73202; +Cc: Herman Rimm hey herman! > ;; In (gnu bootloader grub): > (define (grub-efi-default-targets esp) > (tree->target ; like arborify > (bootloader-target > (type 'esp) > (path esp) > (targets ; counterpart of offset > (list (bootloader-target > (type 'vendir) > (path "EFI/Guix")) > (bootloader-target > (type 'install) > (path "grub"))))))) how would this handle root offsets, eg by guix system init? is everything assumed to be offset from root? I'm also worried about indentation growing too quickly. otherwise, though, it's definately an improvement over offset! > ;; This is the same as (grub-efi-default-targets "boot"). It could > be > ;; exported standalone, instead of using bootloader default-targets. > (define %grub-efi-default-targets > '((esp . "/boot") > (install . "/boot/EFI/Guix") > (vendir . "/boot/grub"))) > > ;; A simple consequence of this change is that this: > (with-targets %grub-efi-default-targets > (('install => (path :path)) > ...)) > ;; becomes: > (let ((install-path (assoc-ref %grub-efi-default-targets 'install))) > ...) > > ;; But e.g. device is provided separately (or derived from path): > (with-targets %grub-efi-default-targets > (('esp => (device :device)) > ...)) > ;; becomes: > (let* ((path (assoc-ref %grub-efi-default-targets 'esp)) > ;; A single root-device is provided in addition to targets. > (device (root-device->block-device root-device path))) > ...) > > ;; This procedure is in (gnu bootloader). Something like: > (define (root-device->block-device device path) > (match device > ((? block-device?) device) ; string with /dev/ prefix > ((? uuid?) (find-partition-for-uuid device)) > ((? string?) (find-partition-for-label device)) > ;; This might be necessary, but should not be relied on. > (_ (mount-source (find-mount path))))) how are you replacing device-local paths? some bootloaders need that information to access files before fully loading. also, if the path, device, label, and uuid fields are combined, the guix system image won't be able to get all the info it needs to the bootloader installers. uuid or label needs to be there to identify the device on- boot, but also path, device, and devpath are required to actually install bootloader files. also, one reason with-targets exists is as a safeguard for future people writing bootloaders. guix system image tends to be overlooked, so it performs checks to make sure the bootloader targets requested are available during image generation. > ;; Example user configuration: > (define %grub-efi-bootloader > (bootloader-configuration > (bootloader grub-efi-bootloader) > ;; This is for bootloader configuration (not installation), e.g. > ;; GRUB search or install-efi disk argument. > (root-device "UUID, label, or block device.") > ;; This is complementary to root-device. It will configure some > ;; files to be fetched remotely instead of installed. > (tftp "Varies for UEFI/GRUB/U-Boot."))) > > (operating-system > (bootloader (list %grub-efi-bootloader)) > ;; This is shared between bootloaders. Ideally, it does not affect > ;; which files are installed or their contents, but only the > location. > (bootloader-targets (grub-efi-default-targets "boot"))) I do really like the conceptual separation between configuration and installation! though, users would now need to enter the root device details three times, potentially in inconsistant formats. - lilah ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-04 5:07 ` Lilah Tascheter via Guix-patches @ 2024-10-04 13:55 ` Herman Rimm via Guix-patches via 2024-10-07 16:59 ` Ryan via Guix-patches via 2024-10-08 18:05 ` Lilah Tascheter via Guix-patches 0 siblings, 2 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-10-04 13:55 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter Hello, On Fri, Oct 04, 2024 at 12:07:16AM -0500, Lilah Tascheter wrote: > > (define (grub-efi-default-targets esp) > how would this handle root offsets, eg by guix system init? is > everything assumed to be offset from root? For every (key . value) in targets, prefix value with root-offset. Or if the target tree is still available, extend it: (bootloader-target (type 'root) (path root-offset) (targets (list %target-tree))) It works under the assumption that bootloader-target paths will not be referenced in bootloader configuration files. When that does not hold, e.g. in the (make-)grub.cfg procedure, then I think either the target paths (or tree) need to be unprefixed (or unwrapped); or the root should be offset implicitly, i.e. doing the installation in a chroot. > I'm also worried about indentation growing too quickly. Do you have a use case in mind, with more than three levels of nesting? > otherwise, though, it's definately an improvement over offset! Thanks. Using the assumption that Guix only works with UNIX file systems and not DOS-derivatives or exotic data stores, it only allows constructing a tree and not a forest or (cyclic) graph, respectively. > how are you replacing device-local paths? some bootloaders need that > information to access files before fully loading. I guess when device-local paths are required, a targets tree should be provided and queried using the with-targets macro. They could also be cast from target paths, with a warning. > also, if the path, device, label, and uuid fields are combined, the > guix system image won't be able to get all the info it needs to the > bootloader installers. uuid or label needs to be there to identify the > device on-boot, So I have tried combining the path field into the device field, but I'm now in favor of using a target tree/paths field together with a combined block device, file system label, or UUID field. Here the assumption is that any of the aformentioned types can be derived from any other, e.g. with find-partition-by-uuid and read-partition-label. If a bootloader cannot use a provided type, or find other required types, it should throw an error. If you have a use case where both a block device and a (potentially unrelated) UUID are configured, please let me know. > but also path, device, and devpath are required to actually install > bootloader files. I think the device could be installation-agnostic and anything related to installation could be a different bootloader, or a field like tftp. > also, one reason with-targets exists is as a safeguard for future > people writing bootloaders. guix system image tends to be overlooked, > so it performs checks to make sure the bootloader targets requested > are available during image generation. What do you think about having required types per bootloader, and tests for trees generated from image partitions in (gnu tests image) instead? That reminds me: I would like to add a supported file systems field to the bootloader, so that if the file system found for root-device is not supported, it throws a little error. > > (operating-system > > (bootloader (list %grub-efi-bootloader)) > > ;; This is shared between bootloaders. Ideally, it does not affect > > ;; which files are installed or their contents, but only the > > location. > > (bootloader-targets (grub-efi-default-targets "boot"))) > I do really like the conceptual separation between configuration and > installation! though, users would now need to enter the root device > details three times, potentially in inconsistant formats. Thanks, I think the two examples below could work pretty well. Cheers, Herman (define %boot-fs (file-system (device (uuid "E6A5-FEBB" 'fat32)) (mount-point "/boot") ; Taken as ESP. ;; Cannot be used to configure e.g. GRUB netboot, but it would be ;; nice to assert (support? bootloader type) in fs->bootloader. (type "vfat"))) (operating-system (bootloader ;; Procedure defined in (gnu system file-systems). (file-system->grub-efi-bootloader %boot-fs)) ...) ;; bootloader->file-system would not work as well. An OS field (macro) ;; to define both simultaneously at a high level could be useful though. (operating-system (file-systems-with-bootloader ;; Irrelevant for file-systems. (bootloader grub-efi-bootloader) ;; Relevant as a file-system and bootloader installation. (boot-device "UUID, label, or block device.") (mount-point "/boot") (type "vfat") ;; Not relevant to bootloader. Default values given. (root-file-system (mounted-root-fs)) ; Error if not found. ;; Cons the generated boot FS and mounted root FS to this. (file-systems %base-file-systems)) ...) ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-04 13:55 ` Herman Rimm via Guix-patches via @ 2024-10-07 16:59 ` Ryan via Guix-patches via 2024-10-07 19:23 ` Herman Rimm via Guix-patches via 2024-10-08 14:37 ` Ryan via Guix-patches via 2024-10-08 18:05 ` Lilah Tascheter via Guix-patches 1 sibling, 2 replies; 41+ messages in thread From: Ryan via Guix-patches via @ 2024-10-07 16:59 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Herman Rimm Hi all, question about this entire patchset. I would like to do some testing and play around with this myself, but I cannot for the life of me figure out how it's supposed to be patched on top of the main tree, if someone could clarify. Right now, I have Guix master branch checked out @7e63a35f, and am under the assumption that the order of patching should be as follows: 69343->73202 ->72457. Is this correct? I can apply 69343 cleanly, however trying to apply the latest patchsets for 73202 or 72457 fail immediately, complaining that either I cannot build fake ancestors (attempting a 3-way merge) or that various files do not match the index. I'm assuming I am missing some more patchsets somewhere, but am unsure which are dependent on one another. Hoping for some clarification so I can get my local tree all patched and begin some testing (nothing too special, just want to set up UKIs on x86_64 but it could be some insight nonetheless!) Thanks! --- Best, Ryan S ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-07 16:59 ` Ryan via Guix-patches via @ 2024-10-07 19:23 ` Herman Rimm via Guix-patches via 2024-10-08 14:37 ` Ryan via Guix-patches via 1 sibling, 0 replies; 41+ messages in thread From: Herman Rimm via Guix-patches via @ 2024-10-07 19:23 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Ryan Hello Ryan, On Mon, Oct 07, 2024 at 12:59:16PM -0400, Ryan wrote: > Right now, I have Guix master branch checked out @7e63a35f, and am under the > assumption that the order of patching should be as follows: 69343->73202 > ->72457. Is this correct? Almost, v6 of 72457 additionally requires v2 of 70131. > I can apply 69343 cleanly, however trying to apply > the latest patchsets for 73202 or 72457 fail immediately, complaining that Yeah, applying 73202 after 69343 using 'mumi am' immediately returns: Applying: gnu: bootloader: Install any bootloader to ESP. error: patch failed: gnu/bootloader.scm:113 error: gnu/bootloader.scm: patch does not apply error: patch failed: gnu/build/bootloader.scm:23 error: gnu/build/bootloader.scm: patch does not apply Patch failed at 0001 gnu: bootloader: Install any bootloader to ESP. Very strange because this is not [PATCH v3 01/14], but [PATCH v3 12/14]. Manually downloading the patches from [1] and applying them seems to work, until again [PATCH v3 12/14]. Looking closer at the download of it (34), it seems to actually be [PATCH v3 14/14]... Besides that, your message here does not appear on [1], or [2] for October 07. Do you know why that is? But anyway, Lilah also had trouble applying v6 of 72457. v7 of 72457 will be independent of 70131, and hopefully possible to apply. For now, you can get patches similar to those in 70131, 69343, 73202, 72457, and 68524 (UKI bootloader) from my git repository, by running: git checkout 7e63a35f git remote add herman https://codeberg.org/herman_rimm/guix.git git fetch herman git cherry-pick herman/lint-order..herman/uki-efi-bootloader-stable Cheers, Herman [1]: https://issues.guix.gnu.org/73202 [2]: https://lists.gnu.org/archive/html/guix-patches/2024-10/index.html ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-07 16:59 ` Ryan via Guix-patches via 2024-10-07 19:23 ` Herman Rimm via Guix-patches via @ 2024-10-08 14:37 ` Ryan via Guix-patches via 2024-10-08 17:23 ` Lilah Tascheter via Guix-patches 1 sibling, 1 reply; 41+ messages in thread From: Ryan via Guix-patches via @ 2024-10-08 14:37 UTC (permalink / raw) To: 73202; +Cc: Lilah Tascheter, Herman Rimm, Ryan Hi Herman, > On Mon, Oct 07, 2024 at 09:23:14PM +0200, Herman wrote: > Very strange because this is not [PATCH v3 01/14], but [PATCH v3 12/14]. > Manually downloading the patches from [1] and applying them seems to > work, until again [PATCH v3 12/14]. Looking closer at the download of > it (34), it seems to actually be [PATCH v3 14/14]... Besides that, your > message here does not appear on [1], or [2] for October 07. Do you know > why that is? Very odd, do you think this is a bug in mumi of some kind? I'm new to email based git workflows, so I've been leaning a mumi for a lot of my setup. Didn't even think to look if it was trying to apply patches in the correct order, I just assumed it was and I was doing something wrong. To your second point, I have the same question. My current theory is that I am new enough to the mailing lists that I have to go through some sort of approval process before my emails appear in the actual list and subsequent mumi site, but I have no proof of this, other than my posts historically taking many hours to actually appear. Maybe I am doing something wrong? > But anyway, Lilah also had trouble applying v6 of 72457. v7 of 72457 > will be independent of 70131, and hopefully possible to apply. For now, > you can get patches similar to those in 70131, 69343, 73202, 72457, and > 68524 (UKI bootloader) from my git repository, by running: > > git checkout 7e63a35f > git remote add herman https://codeberg.org/herman_rimm/guix.git > git fetch herman > git cherry-pick herman/lint-order..herman/uki-efi-bootloader-stable Thanks for linking your tree (and adding the helpful instructions!) Glad to report I cherry-picked the commits without any issues. I'll continue working on my changes I am making to my system (that integrates these changes) and report on the proper issues if I run into anything! --- Best, Ryan S ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-08 14:37 ` Ryan via Guix-patches via @ 2024-10-08 17:23 ` Lilah Tascheter via Guix-patches 0 siblings, 0 replies; 41+ messages in thread From: Lilah Tascheter via Guix-patches @ 2024-10-08 17:23 UTC (permalink / raw) To: 73202; +Cc: Herman Rimm, Ryan ugh forgot to send this to the mailing list, so resending: > Very odd, do you think this is a bug in mumi of some kind? yep! I tried to message guix-devel about it but nobody responded. no clue where to report mumi bugs. a control message I sent caused mumi's message download links to be offset one back, resulting in a request to download any email (both in the cli and the web ui) to return the previous email in order. it sucks. ^ permalink raw reply [flat|nested] 41+ messages in thread
* [bug#73202] [PATCH] Preparation for bootloader rewrite. 2024-10-04 13:55 ` Herman Rimm via Guix-patches via 2024-10-07 16:59 ` Ryan via Guix-patches via @ 2024-10-08 18:05 ` Lilah Tascheter via Guix-patches 1 sibling, 0 replies; 41+ messages in thread From: Lilah Tascheter via Guix-patches @ 2024-10-08 18:05 UTC (permalink / raw) To: 73202; +Cc: Herman Rimm hi!! > > I'm also worried about indentation growing too quickly. > Do you have a use case in mind, with more than three levels of > nesting? yeah good point :p > > also, if the path, device, label, and uuid fields are combined, the > > guix system image won't be able to get all the info it needs to the > > bootloader installers. uuid or label needs to be there to identify > > the device on-boot, > So I have tried combining the path field into the device field, but > I'mnow in favor of using a target tree/paths field together with a > combined block device, file system label, or UUID field. Here the > assumption is that any of the aformentioned types can be derived from > any other, e.g. with find-partition-by-uuid and read-partition- > label. If a bootloader cannot use a provided type, or find other > required types, it should throw an error. If you have a use case > where both a block device and a (potentially unrelated) UUID are > configured, please let me know. alright, that sounds great! would work for image gen, and can't think of a reason why distinct uuids and devices would be supplied. > > > but also path, device, and devpath are required to actually install > > bootloader files. > I think the device could be installation-agnostic and anything > related > to installation could be a different bootloader, or a field like > tftp. > > also, one reason with-targets exists is as a safeguard for future > > people writing bootloaders. guix system image tends to be > > overlooked, > > so it performs checks to make sure the bootloader targets requested > > are available during image generation. > What do you think about having required types per bootloader, and > tests > for trees generated from image partitions in (gnu tests image) > instead? oh yeah that's a way better idea! offloads the test work from runtime to, well, testing. > That reminds me: I would like to add a supported file systems field > to the bootloader, so that if the file system found for root-device > is not supported, it throws a little error. sounds good, make sure the field supports specifying that all filesystems are supported though (mostly just because of bootloaders that install a kernel directly, like uki-efi). > (define %boot-fs > (file-system > (device (uuid "E6A5-FEBB" 'fat32)) > (mount-point "/boot") ; Taken as ESP. > ;; Cannot be used to configure e.g. GRUB netboot, but it would be > ;; nice to assert (support? bootloader type) in fs->bootloader. > (type "vfat"))) > (operating-system > (bootloader ;; Procedure defined in (gnu system file-systems). > (file-system->grub-efi-bootloader %boot-fs)) > ...) > > ;; bootloader->file-system would not work as well. An OS field > (macro) > ;; to define both simultaneously at a high level could be useful > though. > (operating-system > (file-systems-with-bootloader > ;; Irrelevant for file-systems. > (bootloader grub-efi-bootloader) > ;; Relevant as a file-system and bootloader installation. > (boot-device "UUID, label, or block device.") > (mount-point "/boot") > (type "vfat") > ;; Not relevant to bootloader. Default values given. > (root-file-system (mounted-root-fs)) ; Error if not found. > ;; Cons the generated boot FS and mounted root FS to this. > (file-systems %base-file-systems)) > ...) so, the benefit here is that bootloader builds would be deterministic from the bootloader-configuration, right? I feel like a new top-level macro, that requires specific fields for each possible device type is unwieldly. it's also potentially important to be able to install multiple distinct bootloaders with distinct configurations, for eg u-boot->uefi chainloading or raid arrays. how about something like the following: (operating-system (bootloader (list (grub-efi-bootloader ;; ... remove the bootloader-configuration record ;; entirely, and have each bootloader take their ;; own config. apart from targets and ;; menu-entries (which we can split off), there ;; aren't really any shared config opts anyway. ;; assoc-fs assocs a path with a file-system type ;; from the operating-system record (delay ;; or thunk the bootloader field so that images ;; can override file-systems?) (root (assoc-fs file-systems "/"))))) ;; have your original targets system in place (bootloader-targets ...) ;; non-grub replacement for menu-entries, potentially with a ;; %base-boot-options thing for the autogenerated ones per ;; guix system generation? (boot-options ...)) with a field sanitizer to make singular entries into lists, to simplify single-bootloader use. devpaths would then be able to be generated by the bootloader using the configuration target information. honestly, then maybe just specify a target field (taking a symbol) in the file-system record, and have assoc-fs take either a target symbol or mount path. have bootloader-targets be generated from the file- systems, with the bootloader-targets field just specifying non- filesystem block devices. I think parts of that may be similar to what you were originally intending? I'm sorry, if so. - lilah ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2024-10-08 18:06 UTC | newest] Thread overview: 41+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-09-12 16:58 [bug#73202] [PATCH] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 01/15] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 02/15] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 03/15] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 04/15] guix: scripts: Remove unused code Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 05/15] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 06/15] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 07/15] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 08/15] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 09/15] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 10/15] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 11/15] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 12/15] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 13/15] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via 2024-09-20 10:37 ` [bug#73202] [PATCH v2 14/15] gnu: system: boot: Add procedure Herman Rimm via Guix-patches via 2024-09-20 10:38 ` [bug#73202] [PATCH v2 15/15] teams: Add bootloading team Herman Rimm via Guix-patches via 2024-09-21 10:57 ` [bug#73202] [PATCH v2 00/15] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-09-25 20:58 ` Lilah Tascheter via Guix-patches 2024-09-26 10:08 ` [bug#73202] [PATCH v3 01/14] gnu: bootloader: Remove deprecated bootloader-configuration field Herman Rimm via Guix-patches via 2024-09-26 10:08 ` [bug#73202] [PATCH v3 02/14] gnu: system: Remove useless boot parameters Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 03/14] gnu: tests: reconfigure: Remove bootloader install test Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 04/14] guix: scripts: Remove unused code Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 05/14] guix: scripts: Rewrite reinstall-bootloader to use provenance data Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 06/14] guix: utils: Add flatten and flat-map from haunt Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 07/14] guix: records: Add wrap-element procedure Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 08/14] gnu: bootloader: Add bootloader-target record and infastructure Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 09/14] gnu: bootloader: Add bootloader-configurations->gexp Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 10/14] gnu: bootloader: Add device-subvol field to menu-entry record Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 11/14] gnu: build: bootloader: Add efi-bootnums procedure Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 12/14] gnu: bootloader: Install any bootloader to ESP Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 13/14] gnu: bootloader: Match records outside the module Herman Rimm via Guix-patches via 2024-09-26 10:09 ` [bug#73202] [PATCH v3 14/14] teams: Add bootloading team Herman Rimm via Guix-patches via 2024-10-03 20:32 ` [bug#73202] [PATCH] Preparation for bootloader rewrite Herman Rimm via Guix-patches via 2024-10-04 5:07 ` Lilah Tascheter via Guix-patches 2024-10-04 13:55 ` Herman Rimm via Guix-patches via 2024-10-07 16:59 ` Ryan via Guix-patches via 2024-10-07 19:23 ` Herman Rimm via Guix-patches via 2024-10-08 14:37 ` Ryan via Guix-patches via 2024-10-08 17:23 ` Lilah Tascheter via Guix-patches 2024-10-08 18:05 ` Lilah Tascheter via Guix-patches
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/guix.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.