at 23.11-beta 3.7 kB view raw
1# Tests building and running a GUID Partition Table (GPT) appliance image. 2# "Appliance" here means that the image does not contain the normal NixOS 3# infrastructure of a system profile and cannot be re-built via 4# `nixos-rebuild`. 5 6{ lib, ... }: 7 8let 9 rootPartitionLabel = "root"; 10 11 bootLoaderConfigPath = "/loader/entries/nixos.conf"; 12 kernelPath = "/EFI/nixos/kernel.efi"; 13 initrdPath = "/EFI/nixos/initrd.efi"; 14in 15{ 16 name = "appliance-gpt-image"; 17 18 meta.maintainers = with lib.maintainers; [ nikstur ]; 19 20 nodes.machine = { config, lib, pkgs, ... }: { 21 22 imports = [ ../modules/image/repart.nix ]; 23 24 virtualisation.directBoot.enable = false; 25 virtualisation.mountHostNixStore = false; 26 virtualisation.useEFIBoot = true; 27 28 # Disable boot loaders because we install one "manually". 29 # TODO(raitobezarius): revisit this when #244907 lands 30 boot.loader.grub.enable = false; 31 32 virtualisation.fileSystems = lib.mkForce { 33 "/" = { 34 device = "/dev/disk/by-partlabel/${rootPartitionLabel}"; 35 fsType = "ext4"; 36 }; 37 }; 38 39 image.repart = { 40 name = "appliance-gpt-image"; 41 partitions = { 42 "esp" = { 43 contents = 44 let 45 efiArch = config.nixpkgs.hostPlatform.efiArch; 46 in 47 { 48 "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = 49 "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi"; 50 51 # TODO: create an abstraction for Boot Loader Specification (BLS) entries. 52 "${bootLoaderConfigPath}".source = pkgs.writeText "nixos.conf" '' 53 title NixOS 54 linux ${kernelPath} 55 initrd ${initrdPath} 56 options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} 57 ''; 58 59 "${kernelPath}".source = 60 "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}"; 61 62 "${initrdPath}".source = 63 "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; 64 }; 65 repartConfig = { 66 Type = "esp"; 67 Format = "vfat"; 68 # Minimize = "guess" seems to not work very vell for vfat 69 # partitons. It's better to set a sensible default instead. The 70 # aarch64 kernel seems to generally be a little bigger than the 71 # x86_64 kernel. To stay on the safe side, leave some more slack 72 # for every platform other than x86_64. 73 SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M"; 74 }; 75 }; 76 "root" = { 77 storePaths = [ config.system.build.toplevel ]; 78 repartConfig = { 79 Type = "root"; 80 Format = config.fileSystems."/".fsType; 81 Label = rootPartitionLabel; 82 Minimize = "guess"; 83 }; 84 }; 85 }; 86 }; 87 }; 88 89 testScript = { nodes, ... }: '' 90 import os 91 import subprocess 92 import tempfile 93 94 tmp_disk_image = tempfile.NamedTemporaryFile() 95 96 subprocess.run([ 97 "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img", 98 "create", 99 "-f", 100 "qcow2", 101 "-b", 102 "${nodes.machine.system.build.image}/image.raw", 103 "-F", 104 "raw", 105 tmp_disk_image.name, 106 ]) 107 108 # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image. 109 os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name 110 111 bootctl_status = machine.succeed("bootctl status") 112 assert "${bootLoaderConfigPath}" in bootctl_status 113 assert "${kernelPath}" in bootctl_status 114 assert "${initrdPath}" in bootctl_status 115 ''; 116}