Adding a recovery boot entry while using systemd-boot

Hi there,

I’m trying to find a way to add another boot entry to my NixOS setup that boots something like the NixOS minimal installer which I can use if I borked my normal NixOS to recover, instead of having to flash a USB drive and boot from that. (Had a recent issue where full disk encryption broke in a way that prevented old rollbacks from working too.)

If I were using grub2, I could use something like boot.loader.grub.extraEntries to manually specify an entry for a partition that has it, but I had to switch away from grub to just using systemd-boot due to FDE LUKS issues.

Overall my question breaks down to:

  1. Is it possible to add additional boot entries while using systemd-boot?

  2. Is it possible to have NixOS automagically build an isolated boot target separate from the main NixOS install to populate the additional boot entry?

Haven’t been able to find examples of this elsewhere, but links to resources are appreciated!

Yes, drop files in /boot/loader/entries — NixOS should leave any extra files there alone. You can use netboot kernel and initramfs images as a recovery boot option. For example,

nix-build '<nixpkgs/nixos>'  -A config.system.build.kernel -A config.system.build.netbootRamdisk \
  --arg configuration '{
       imports = [ <nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix> ];
       networking.wireless.enable = true;
    }' 

to get store paths containing the kernel and initramfs for a system with wireless support. Note that this will be an installer image, i.e. one that allows logging in without a password! You may want to use netboot-base.nix instead and set users.users.root.hashedPassword so that you can only log in with a password, especially if this is a laptop.

Yes, but this may actually not be desirable! If it’s not decoupled from your main system config, any nixpkgs breakage which may break your normal boot could break your recovery boot.

4 Likes

That’s great, thank you!

Next step is figuring out what’s the best way to store this configuration so that the resulting store assets don’t get garbage collected. Guessing I’ll need to make a derivation to include in my config. Ah I can just cp them from the store into the EFI dir, got it.

Either way, this is a great starting point, thanks again!

Exactly — you’ll need them copied to a filesystem that your firmware can read (and firmwares that support anything other than FAT32 are few and far between AFAIK) anyway, so it makes a lot of sense to copy them over.

Oh, one more thing! You’ll need to get the right command line for this to boot. The easiest way is to build the iPXE script instead of the kernel directly, it contains the necessary paths:

$ nix-build '<nixpkgs/nixos>'  -A config.system.build.netbootIpxeScript -A config.system.build.netbootRamdisk \
  --arg configuration '{
       imports = [ <nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix> ];
       networking.wireless.enable = true;
    }'
<snip>
$ cat result
#!ipxe
kernel bzImage init=/nix/store/cz0l2d19gygk1skq4413azmz3vd8y9x4-nixos-system-nixos-20.09pre228204.467ce5a9f45/init initrd=initrd loglevel=4
initrd initrd
boot
3 Likes

This would make a handy blog post!

First I need to get around to resizing my EFI partition to fit a full image, then I’ll give it a whirl. :slight_smile:

2 Likes