diff options
| author | Arian van Putten <arian@mercury.com> | 2023-06-01 12:36:31 +0200 |
|---|---|---|
| committer | Arian van Putten <arian@mercury.com> | 2023-06-02 18:38:48 +0200 |
| commit | abd2ddbb012a9fa1619770cb8c19a3f2346bb153 (patch) | |
| tree | 70d03bc74a682b2d024399dcab70fb7a014d8789 | |
| parent | nixos/systemd-boot: remove graceful option (diff) | |
| download | nixpkgs-origin/fix-systemd-boot.tar.gz | |
nixos/systemd-boot: remove brittle version detection logicorigin/fix-systemd-boot
We were relying on the output of `status` which is not very stable.
Instead we rely on systemd to do the version detection logic.
Systemd will not update if version_available <= version_installed
we add --graceful to make sure systemd returns EXIT_SUCCESS in this
scenario.
Unfortunately --graceful also makes it return EXIT_SUCCESS if:
- ESP is not mounted
- Can not edit EFI variables
We alliviate this by introducing a `bootctl is-installed` check.
If that returns true we know the ESP is mounted and that `update`
will not modify any EFI variables.
| -rwxr-xr-x | nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index a152040e5890..6d4129724e7e 100755 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -254,34 +254,28 @@ def main() -> None: subprocess.check_call(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@"] + bootctl_flags + ["install"]) else: + is_installed = subprocess.check_output(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@", "is-installed"]) + + if is_installed != "yes": + raise Exception("boot loader is not installed so can not update. Try setting NIXOS_INSTALL_BOOTLOADER=1") + # Update bootloader to latest if needed available_out = subprocess.check_output(["@systemd@/bin/bootctl", "--version"], universal_newlines=True).split()[2] - installed_out = subprocess.check_output(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@", "status"], universal_newlines=True) - - # See status_binaries() in systemd bootctl.c for code which generates this - installed_match = re.search(r"^\W+File:.*/EFI/(?:BOOT|systemd)/.*\.efi \(systemd-boot ([\d.]+[^)]*)\)$", - installed_out, re.IGNORECASE | re.MULTILINE) available_match = re.search(r"^\((.*)\)$", available_out) - if installed_match is None: - raise Exception("could not find any previously installed systemd-boot") - if available_match is None: raise Exception("could not determine systemd-boot version") - installed_version = version.parse(installed_match.group(1)) available_version = version.parse(available_match.group(1)) # systemd 252 has a regression that leaves some machines unbootable, so we skip that update. # The fix is in 252.2 # See https://github.com/systemd/systemd/issues/25363 and https://github.com/NixOS/nixpkgs/pull/201558#issuecomment-1348603263 - if installed_version < available_version: - if version.parse('252') <= available_version < version.parse('252.2'): - print("skipping systemd-boot update to %s because of known regression" % available_version) - else: - print("updating systemd-boot from %s to %s" % (installed_version, available_version)) - subprocess.check_call(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@"] + bootctl_flags + ["update"]) + if version.parse('252') <= available_version < version.parse('252.2'): + print("skipping systemd-boot update to %s because of known regression" % available_version) + else: + subprocess.check_call(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@", "--graceful"] + bootctl_flags + ["update"]) mkdir_p("@efiSysMountPoint@/efi/nixos") mkdir_p("@efiSysMountPoint@/loader/entries") |
