unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [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
  0 siblings, 1 reply; 17+ 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] 17+ 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)
  0 siblings, 15 replies; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ messages in thread

end of thread, other threads:[~2024-09-20 10:58 UTC | newest]

Thread overview: 17+ 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

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).