diff --git a/nixos/modules/installer/netboot/netboot.nix b/nixos/modules/installer/netboot/netboot.nix index a50f22cbe471d..f19d3c8a4c549 100644 --- a/nixos/modules/installer/netboot/netboot.nix +++ b/nixos/modules/installer/netboot/netboot.nix @@ -1,7 +1,7 @@ # This module creates netboot media containing the given NixOS # configuration. -{ config, lib, pkgs, ... }: +{ options, config, lib, pkgs, ... }: with lib; @@ -41,6 +41,34 @@ with lib; environment.systemPackages = [ pkgs.grub2_efi ] ++ (lib.optionals (pkgs.stdenv.hostPlatform.system != "aarch64-linux") [pkgs.grub2 pkgs.syslinux]); + # We only want to set those options in the context of + # the QEMU infrastructure. + virtualisation = lib.optionalAttrs (options ? virtualisation.directBoot) { + # By default, using netboot images in virtualized contexts + # should not create any disk image ideally, except if + # asked explicitly. + diskImage = mkDefault null; + # We do not want to mount the host Nix store in those situations. + mountHostNixStore = mkDefault false; + # We do not need the nix store image because: + # - either we boot through network and we have the squashfs image + # - either we direct boot, we have the squashfs image + useNixStoreImage = mkDefault false; + # Though, we still want a writable store through .rw-store + writableStore = mkDefault true; + # Ideally, we might not want to test the network / firmware. + directBoot = { + enable = mkDefault true; + # We need to use our netboot initrd which contains a copy of the Nix store. + initrd = "${config.system.build.netbootRamdisk}/${config.system.boot.loader.initrdFile}"; + }; + # We do not want to use the default filesystems. + useDefaultFilesystems = mkDefault false; + # Bump the default memory size as we are loading the whole initrd in RAM. + memorySize = mkDefault 1536; + }; + + fileSystems."/" = mkImageMediaOverride { fsType = "tmpfs"; options = [ "mode=0755" ]; @@ -95,8 +123,7 @@ with lib; # Create the initrd system.build.netbootRamdisk = pkgs.makeInitrdNG { - inherit (config.boot.initrd) compressor; - prepend = [ "${config.system.build.initialRamdisk}/initrd" ]; + prepend = [ "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ]; contents = [ { object = config.system.build.squashfsStore; @@ -109,8 +136,8 @@ with lib; #!ipxe # Use the cmdline variable to allow the user to specify custom kernel params # when chainloading this script from other iPXE scripts like netboot.xyz - kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline} - initrd initrd + kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=${config.system.boot.loader.initrdFile} ${toString config.boot.kernelParams} ''${cmdline} + initrd ${config.system.boot.loader.initrdFile} boot ''; @@ -124,7 +151,7 @@ with lib; fi SCRIPT_DIR=$( cd -- "$( dirname -- "''${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) kexec --load ''${SCRIPT_DIR}/bzImage \ - --initrd=''${SCRIPT_DIR}/initrd.gz \ + --initrd=''${SCRIPT_DIR}/${config.system.boot.loader.initrdFile} \ --command-line "init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" kexec -e ''; @@ -132,8 +159,8 @@ with lib; # A tree containing initrd.gz, bzImage and a kexec-boot script. system.build.kexecTree = pkgs.linkFarm "kexec-tree" [ { - name = "initrd.gz"; - path = "${config.system.build.netbootRamdisk}/initrd"; + name = "${config.system.boot.loader.initrdFile}"; + path = "${config.system.build.netbootRamdisk}/${config.system.boot.loader.initrdFile}"; } { name = "bzImage"; diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 3d7f3ccb62f84..d28e958def5ba 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -1192,7 +1192,7 @@ in # value for the `fileSystems' attribute should be disregarded (since those # filesystems don't necessarily exist in the VM). You can disable this # override by setting `virtualisation.fileSystems = lib.mkForce { };`. - fileSystems = lib.mkIf (cfg.fileSystems != { }) (mkVMOverride cfg.fileSystems); + fileSystems = lib.mkIf (cfg.fileSystems != { }) (lib.mapAttrs (n: v: mkVMOverride v) cfg.fileSystems); virtualisation.fileSystems = let mkSharedDir = tag: share: diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix index ec2a9f6527c93..11fb817c77a7e 100644 --- a/nixos/tests/boot.nix +++ b/nixos/tests/boot.nix @@ -104,6 +104,15 @@ in { bios = uefiBinary; }; + directNetboot = makeTest { + name = "directboot-netboot"; + nodes.machine = { + imports = [ ../modules/installer/netboot/netboot-minimal.nix ]; + virtualisation.memorySize = 4096; + }; + testScript = "machine.fail('stat /dev/vda')"; + }; + uefiNetboot = makeNetbootTest "uefi" { bios = uefiBinary; # Custom ROM is needed for EFI PXE boot. I failed to understand exactly why, because QEMU should still use iPXE for EFI.