summary refs log tree commit diff
path: root/gnu/bootloader.scm
diff options
context:
space:
mode:
authorStefan <stefan-guix@vodafonemail.de>2022-11-30 19:59:09 -0500
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>2022-12-01 14:31:28 -0500
commita9acbf919a7668e26863d2d26d48c5fd41b57fcd (patch)
treee29c25d793f35b03a711ed865d20eecb55033034 /gnu/bootloader.scm
parent1a63aea94340f6a24ac09e1c348401e9dfd05395 (diff)
downloadguix-a9acbf919a7668e26863d2d26d48c5fd41b57fcd.tar.gz
gnu: bootloader: Rework chaining, add grub-efi-netboot-removable-bootloader.
This rework allows to use an (efi-bootloader-chain) like this, which is able
to boot over network or local storage, depending on whether the bootloader
target has support for symbolic links:

   (operating-system
    (bootloader
      (bootloader-configuration
        (bootloader
          (efi-bootloader-chain
            grub-efi-netboot-removable-bootloader
            #:packages (list my-firmware-package
                             my-u-boot-package)
            #:files (list (plain-file "config.txt"
                                      "kernel=u-boot.bin"))
            #:hooks my-special-bootloader-profile-manipulator))
        (targets '("/booti/efi"))
        …))
    …)

* doc/guix.texi (Bootloader Configuration): Describe the new
‘grub-efi-netboot-removable-bootloader’.  Mention the file names used and that
the UEFI Boot Manager is not modified.  Advise to disable write-access over
TFTP.
* gnu/bootloader.scm (efi-bootloader-profile): Allow a list of packages and
collect everything directly in the profile, avoiding a separate collection
directory.  Renamed the profile from "bootloader-profile" to
"efi-bootloader-profile".
[bootloader-collection]: Rename to...
[efi-bootloader-profile-hook]: ... this and remove unused modules.  Do not
create the now extraneous collection directory.
(efi-bootloader-chain): Add PACKAGES and DISK-IMAGE-INSTALLER arguments.
Remove handling of the collection directory, now only calling the given
installer procedure.
* gnu/bootloader/grub.scm (make-grub-efi-netboot-installer): New helper.
(make-grub-configuration): New helper based on (grub-configuration-file).  Add
a GRUB argument, fix indentation, remove previous code retrieving GRUB from
CONFIG.
(grub-configuration-file): Make use of make-grub-configuration.
(grub-efi-configuration-file): New procedure.
(grub-cfg): New variable to replace "/boot/grub/grub.cfg".
(install-grub-efi-netboot): Remove, splitting logic to...
(make-grub-efi-netboot-installer): ... this new helper procedure, as well as
to make-grub-efi-netboot, added below.
(grub-bootloader): Adjust to use the GRUB-CFG.
(grub-efi-bootloader): Likewise.  Removed inheritance and declare all fields
explicitly.
(make-grub-efi-netboot-bootloader): New procedure.
(grub-efi-netboot-bootloader): Use it.
(grub-efi-netboot-removable-bootloader): New variable.
* gnu/packages/bootloaders.scm (make-grub-efi-netboot): New procedure.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Modified-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Diffstat (limited to 'gnu/bootloader.scm')
-rw-r--r--gnu/bootloader.scm105
1 files changed, 53 insertions, 52 deletions
diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm
index da65b9d5d5..2c36d8c6cf 100644
--- a/gnu/bootloader.scm
+++ b/gnu/bootloader.scm
@@ -322,26 +322,22 @@ instead~%")))
             (force %bootloaders))
       (leave (G_ "~a: no such bootloader~%") name)))
 
-(define (efi-bootloader-profile files bootloader-package hooks)
-  "Creates a profile with BOOTLOADER-PACKAGE and a directory collection/ with
-links to additional FILES from the store.  This collection is meant to be used
-by the bootloader installer.
+(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.
 
 FILES is a list of file or directory names from the store, which will be
-symlinked into the collection/ directory.  If a directory name ends with '/',
-then the directory content instead of the directory itself will be symlinked
-into the collection/ directory.
+symlinked into the profile.  If a directory name ends with '/', then the
+directory content instead of the directory itself will be symlinked into the
+profile.
 
-FILES may contain file like objects produced by functions like plain-file,
+FILES may contain file like objects produced by procedures like plain-file,
 local-file, etc., or package contents produced with file-append.
 
 HOOKS lists additional hook functions to modify the profile."
-  (define (bootloader-collection manifest)
+  (define (efi-bootloader-profile-hook manifest)
     (define build
-        (with-imported-modules '((guix build utils)
-                                 (ice-9 ftw)
-                                 (srfi srfi-1)
-                                 (srfi srfi-26))
+        (with-imported-modules '((guix build utils))
           #~(begin
             (use-modules ((guix build utils)
                           #:select (mkdir-p strip-store-file-name))
@@ -365,8 +361,7 @@ HOOKS lists additional hook functions to modify the profile."
             (define (name-is-store-entry? name)
               "Return #t if NAME is a direct store entry and nothing inside."
               (not (string-index (strip-store-file-name name) #\/)))
-            (let* ((collection (string-append #$output "/collection"))
-                   (files '#$files)
+            (let* ((files '#$files)
                    (directories (filter name-ends-with-/? files))
                    (names-from-directories
                     (append-map (lambda (directory)
@@ -374,11 +369,11 @@ HOOKS lists additional hook functions to modify the profile."
                                 directories))
                    (names (append names-from-directories
                                   (remove name-ends-with-/? files))))
-              (mkdir-p collection)
+              (mkdir-p #$output)
               (if (every file-exists? names)
                   (begin
                     (for-each (lambda (name)
-                               (symlink-to name collection
+                               (symlink-to name #$output
                                             (if (name-is-store-entry? name)
                                                 strip-store-file-name
                                                 basename)))
@@ -386,57 +381,63 @@ HOOKS lists additional hook functions to modify the profile."
                     #t)
                   #f)))))
 
-    (gexp->derivation "bootloader-collection"
+    (gexp->derivation "efi-bootloader-profile"
                       build
                       #:local-build? #t
                       #:substitutable? #f
                       #:properties
                       `((type . profile-hook)
-                        (hook . bootloader-collection))))
+                        (hook . efi-bootloader-profile-hook))))
 
-  (profile (content (packages->manifest (list bootloader-package)))
-           (name "bootloader-profile")
-           (hooks (append (list bootloader-collection) hooks))
+  (profile (content (packages->manifest packages))
+           (name "efi-bootloader-profile")
+           (hooks (cons efi-bootloader-profile-hook hooks))
            (locales? #f)
            (allow-collisions? #f)
            (relative-symlinks? #f)))
 
-(define* (efi-bootloader-chain files
-                               final-bootloader
+(define* (efi-bootloader-chain final-bootloader
                                #:key
+                               (packages '())
+                               (files '())
                                (hooks '())
-                               installer)
-  "Define a bootloader chain with FINAL-BOOTLOADER as the final bootloader and
-certain directories and files from the store given in the list of FILES.
+                               installer
+                               disk-image-installer)
+  "Define a chain of bootloaders with the FINAL-BOOTLOADER, optional PACKAGES,
+and optional directories and files from the store given in the list of FILES.
 
-FILES may contain file like objects produced by functions like plain-file,
-local-file, etc., or package contents produced with file-append.  They will be
-collected inside a directory collection/ inside a generated bootloader profile,
-which will be passed to the INSTALLER.
+The package of the FINAL-BOOTLOADER and all PACKAGES and FILES will be placed
+in an efi-bootloader-profile, which will be passed to the INSTALLER.
+
+FILES may contain file-like objects produced by procedures like plain-file,
+local-file, etc., or package contents produced with file-append.
 
 If a directory name in FILES ends with '/', then the directory content instead
-of the directory itself will be symlinked into the collection/ directory.
+of the directory itself will be symlinked into the efi-bootloader-profile.
 
 The procedures in the HOOKS list can be used to further modify the bootloader
 profile.  It is possible to pass a single function instead of a list.
 
-If the INSTALLER argument is used, then this function will be called to install
-the bootloader.  Otherwise the installer of the FINAL-BOOTLOADER will be called."
-  (let* ((final-installer (or installer
-                              (bootloader-installer final-bootloader)))
-         (profile (efi-bootloader-profile files
-                                          (bootloader-package final-bootloader)
-                                          (if (list? hooks)
-                                              hooks
-                                              (list hooks)))))
-    (bootloader
-     (inherit final-bootloader)
-     (package profile)
-     (installer
-      #~(lambda (bootloader target mount-point)
-          (#$final-installer bootloader target mount-point)
-          (copy-recursively
-           (string-append bootloader "/collection")
-           (string-append mount-point target)
-           #:follow-symlinks? #t
-           #:log (%make-void-port "w")))))))
+If the INSTALLER argument is used, then this gexp procedure will be called to
+install the efi-bootloader-profile.  Otherwise the installer of the
+FINAL-BOOTLOADER will be called.
+
+If the DISK-IMAGE-INSTALLER is used, then this gexp procedure will be called
+to install the efi-bootloader-profile into a disk image.  Otherwise the
+disk-image-installer of the FINAL-BOOTLOADER will be called."
+  (bootloader
+    (inherit final-bootloader)
+    (name "efi-bootloader-chain")
+    (package
+     (efi-bootloader-profile (cons (bootloader-package final-bootloader)
+                                   packages)
+                             files
+                             (if (list? hooks)
+                                 hooks
+                                 (list hooks))))
+    (installer
+     (or installer
+         (bootloader-installer final-bootloader)))
+    (disk-image-installer
+     (or disk-image-installer
+         (bootloader-disk-image-installer final-bootloader)))))