Subject: [bug#73202] [PATCH] Preparation for bootloader rewrite.

From: Lilah Tascheter <[email-masked]>
Date: Tue, 08 Oct 2024 13:05:36 -0500

hi!!

> > I'm also worried about indentation growing too quickly.
> Do you have a use case in mind, with more than three levels of
> nesting?
yeah good point :p

> > also, if the path, device, label, and uuid fields are combined, the
> > guix system image won't be able to get all the info it needs to the
> > bootloader installers. uuid or label needs to be there to identify
> > the device on-boot,
> So I have tried combining the path field into the device field, but
> I'mnow in favor of using a target tree/paths field together with a
> combined block device, file system label, or UUID field.  Here the
> assumption is that any of the aformentioned types can be derived from
> any other, e.g. with find-partition-by-uuid and read-partition-
> label.  If a bootloader cannot use a provided type, or find other
> required types, it should throw an error.  If you have a use case
> where both a block device and a (potentially unrelated) UUID are
> configured, please let me know.
alright, that sounds great! would work for image gen, and can't think
of a reason why distinct uuids and devices would be supplied.

> 
> > but also path, device, and devpath are required to actually install
> > bootloader files.
> I think the device could be installation-agnostic and anything
> related
> to installation could be a different bootloader, or a field like
> tftp.

> > also, one reason with-targets exists is as a safeguard for future
> > people writing bootloaders. guix system image tends to be
> > overlooked,
> > so it performs checks to make sure the bootloader targets requested
> > are available during image generation.
> What do you think about having required types per bootloader, and
> tests
> for trees generated from image partitions in (gnu tests image)
> instead?
oh yeah that's a way better idea! offloads the test work from runtime
to, well, testing.

> That reminds me: I would like to add a supported file systems field
> to the bootloader, so that if the file system found for root-device
> is not supported, it throws a little error.
sounds good, make sure the field supports specifying that all
filesystems are supported though (mostly just because of bootloaders
that install a kernel directly, like uki-efi).

> (define %boot-fs
>   (file-system
>     (device (uuid "E6A5-FEBB" 'fat32))
>     (mount-point "/boot") ; Taken as ESP.
>     ;; Cannot be used to configure e.g. GRUB netboot, but it would be
>     ;; nice to assert (support? bootloader type) in fs->bootloader.
>     (type "vfat")))
> (operating-system 
>   (bootloader ;; Procedure defined in (gnu system file-systems).
>               (file-system->grub-efi-bootloader %boot-fs))
>   ...)
> 
> ;; bootloader->file-system would not work as well.  An OS field
> (macro)
> ;; to define both simultaneously at a high level could be useful
> though.
> (operating-system
>   (file-systems-with-bootloader
>     ;; Irrelevant for file-systems.
>     (bootloader grub-efi-bootloader)
>     ;; Relevant as a file-system and bootloader installation.
>     (boot-device "UUID, label, or block device.")
>     (mount-point "/boot")
>     (type "vfat")
>     ;; Not relevant to bootloader.  Default values given.
>     (root-file-system (mounted-root-fs)) ; Error if not found.
>     ;; Cons the generated boot FS and mounted root FS to this.
>     (file-systems %base-file-systems))
>   ...)
so, the benefit here is that bootloader builds would be deterministic
from the bootloader-configuration, right?  I feel like a new top-level
macro, that requires specific fields for each possible device type is
unwieldly.  it's also potentially important to be able to install
multiple distinct bootloaders with distinct configurations, for eg
u-boot->uefi chainloading or raid arrays. how about something like the
following:

(operating-system
  (bootloader (list (grub-efi-bootloader
                      ;; ... remove the bootloader-configuration record
                      ;; entirely, and have each bootloader take their
                      ;; own config.  apart from targets and
                      ;; menu-entries (which we can split off), there
                      ;; aren't really any shared config opts anyway.
                      ;; assoc-fs assocs a path with a file-system type
                      ;; from the operating-system record (delay
                      ;; or thunk the bootloader field so that images
                      ;; can override file-systems?)
                      (root (assoc-fs file-systems "/")))))
  ;; have your original targets system in place
  (bootloader-targets ...)
  ;; non-grub replacement for menu-entries, potentially with a 
  ;; %base-boot-options thing for the autogenerated ones per
  ;; guix system generation?
  (boot-options ...))

with a field sanitizer to make singular entries into lists, to simplify
single-bootloader use.  devpaths would then be able to be generated by
the bootloader using the configuration target information.

honestly, then maybe just specify a target field (taking a symbol) in
the file-system record, and have assoc-fs take either a target symbol
or mount path. have bootloader-targets be generated from the file-
systems, with the bootloader-targets field just specifying non-
filesystem block devices.

I think parts of that may be similar to what you were originally
intending? I'm sorry, if so.

- lilah