The documentation describes this as a set of files copied to /boot, with
the attribute name denoting the destination file name in /boot.
This uses essentially the same description as refind, systemd-boot and
grub. However limine put it into limine_install_dir (/boot/limine by
default) by accident, which broke downstream users.
For example, nixos-apple-silicon uses boot.loader.limine.additionalFiles
(and similar directives for other bootloaders) to update its m1n1
bootloader (which chainloads into u-boot, which chainloads into the
bootloader selected in NixOS), and due to this bug, put new versions of
it in the wrong location, effectively never updating m1n1.
Fix this, by updating the location. The next commit adds a regression VM
test for it.
systemd v261 lists the new systemd-boot-fallback binary in `bootctl
status`, so our regex picked up the older fallback version and ran
`bootctl update` on an already current ESP, which then exits non-zero.
Switch from parsing the `bootctl --status` output to having bootctl
compare versions itself by calling io.systemd.BootControl.Install over
Varlink. bootctl is spawned as a stdio Varlink server so that we always
use the bootctl from the target closure. An already current binary comes
back as an io.systemd.System error carrying ESTALE, which we treat as
success.
This is for instance useful on Asahi where an additional initrd archive
containing firmware blobs and per-device calibration files is placed
on the ESP and updated by the Asahi Linux Installer.
These need to be loaded alongside the NixOS initrd.
Implemented for systemd-boot and Limine. Grub is left out since its
install script does not use bootspec yet.
Co-authored-by: Florian Klink <flokli@flokli.de>
Allows running additional shell commands after the limine install script
generates menu entries, mirroring the systemd-boot option of the same
name.
Co-authored-by: Florian Klink <flokli@flokli.de>
Currently, you need to override `stdenv.hostPlatform` to request a
compressed kernel on AArch64, and the kernel configuration is split
between the central structured configuration and string snippets in
platform definitions. This has consequently made the latter bitrot
terribly. Since the platform‐specific logic is now very limited after
cleaning up the detritus, we can move it into the kernel derivation
and expose the relevant configuration there for anyone who wants to
customize it further or needs to read it out.
Co-authored-by: zowoq <59103226+zowoq@users.noreply.github.com>
The CalledProcessError can only come from the append-initrd-secrets
script, so catching it in the generic write loop and then asserting
on the writer type to reach back into its `source` is the wrong
layer. Move the catch, the pristine-initrd fallback and the warning
into InitrdWithSecretsWriter itself, and pass `critical` through the
writer protocol so it can decide between aborting and falling back.
The writer carries the generation number so the warning can still
name the affected generation. write_boot_files no longer knows
anything about secrets and the isinstance assertion is gone.
Suggested-by: Will Fancher <elvishjerricco@gmail.com>
Whether a write failure must be fatal is a property of the destination
path (is it needed by the configuration we are switching to?), not of
the particular BootFile instance that happened to survive
deduplication. Compute the set of critical paths up front and look it
up in write_boot_files, so the dedup loop no longer needs to pick the
"right" instance and becomes a plain order-preserving seen-set walk.
This leaves BootFile.current unused.
Suggested-by: Will Fancher <elvishjerricco@gmail.com>
This guarantees the descriptor is closed even when copyfileobj raises,
matching the other writer implementations. The append-initrd-secrets
script reopens the file by path, so flush() is enough before invoking
it and the explicit close() is no longer needed.
Tell the user what actually happens (the old secrets stay in place) and
how to get rid of the warning, instead of just saying it is "normal".
Suggested-by: Will Fancher <elvishjerricco@gmail.com>
Shared kernels and initrds appear once per generation in boot_files, so
InitrdWithSecretsWriter rebuilt the same file repeatedly. Prefer the
current configuration's entry so its failures stay fatal.
has_gc_root() iterated the entire BootFileList for every file on the
ESP, giving O(files * roots) comparisons. Build the set of kept paths
once and use O(1) membership tests instead.
After removing or renaming a file in boot.initrd.secrets, older
generations' append scripts start failing. Aborting on that blocks
deploying the new configuration, so only treat a failure as fatal when
it belongs to the configuration being switched to.
Appending to the existing file made it grow on every rebuild and a
failed script could leave it half-written. Always rebuild from the
pristine initrd into a temp file and rename into place.
The signing service builds `fwupd_efi` as a bash array but referenced
it as a scalar, tripping SC2128 (array expanded without index) and
SC2046 (unquoted command substitution). With enableStrictShellChecks
these are promoted to errors, breaking the unit-script build when
secureBoot, fwupd and strict shell checks are all enabled.
Loop over the array and sign every matched fwupd EFI binary, quoting
the basename and the -o argument. Indexing a single element would
silently skip any additional files the glob matches.
Assisted-by: claude-code with claude-opus-4-8[1m]-high
Trigger re-installation of grub files when the store path of the grub
package changes.
This is consistent with how side-effects are executed in other parts of
NixOS, e.g. systemd service management, and ensures that the actually
running grub stays in sync with the grub package in the Nix store that
is part of the system closure.
In particular, this causes security patches or dependency changes to be
taken into effect without the need to bump the package version.
Impact:
This change causes a re-installation of grub for all systems,
due to the lack of a persisted grub store path in existing state files.
Background:
So far we only re-installed grub outside of the store when its its
version, the package name, or some flags changed.
This leads to the various security patches only fixing new installations
of grub and not existing ones. This has been like this for over a decade,
but it remains unclear why the implementation decision had been to
be overly cautious with modifying boot loader side effects.
Fixes#486315
PL-135147