1
0
mirror of https://git.savannah.gnu.org/git/guix.git synced 2026-04-06 21:20:33 +02:00

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>
This commit is contained in:
Stefan
2022-11-30 19:59:09 -05:00
committed by Maxim Cournoyer
parent 1a63aea943
commit a9acbf919a
4 changed files with 323 additions and 151 deletions

View File

@@ -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)))))