at master 3.3 kB view raw
1# similar to the appliance-repart-image test but with a dm-verity 2# protected nix store and tmpfs as rootfs 3{ lib, ... }: 4 5{ 6 name = "appliance-repart-image-verity-store"; 7 8 meta.maintainers = with lib.maintainers; [ 9 nikstur 10 willibutz 11 ]; 12 13 nodes.machine = 14 { 15 config, 16 lib, 17 pkgs, 18 ... 19 }: 20 let 21 inherit (config.image.repart.verityStore) partitionIds; 22 in 23 { 24 imports = [ ../modules/image/repart.nix ]; 25 26 virtualisation.fileSystems = lib.mkVMOverride { 27 "/" = { 28 fsType = "tmpfs"; 29 options = [ "mode=0755" ]; 30 }; 31 32 # bind-mount the store 33 "/nix/store" = { 34 device = "/usr/nix/store"; 35 options = [ "bind" ]; 36 }; 37 }; 38 39 image.repart = { 40 verityStore = { 41 enable = true; 42 # by default the module works with systemd-boot, for simplicity this test directly boots the UKI 43 ukiPath = "/EFI/BOOT/BOOT${lib.toUpper config.nixpkgs.hostPlatform.efiArch}.EFI"; 44 }; 45 46 name = "appliance-verity-store-image"; 47 48 partitions = { 49 ${partitionIds.esp} = { 50 # the UKI is injected into this partition by the verityStore module 51 repartConfig = { 52 Type = "esp"; 53 Format = "vfat"; 54 SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M"; 55 }; 56 }; 57 ${partitionIds.store-verity}.repartConfig = { 58 Minimize = "best"; 59 }; 60 ${partitionIds.store}.repartConfig = { 61 Minimize = "best"; 62 }; 63 }; 64 }; 65 66 virtualisation = { 67 directBoot.enable = false; 68 mountHostNixStore = false; 69 useEFIBoot = true; 70 }; 71 72 boot = { 73 loader.grub.enable = false; 74 initrd.systemd.enable = true; 75 }; 76 77 system.image = { 78 id = "nixos-appliance"; 79 version = "1"; 80 }; 81 82 # don't create /usr/bin/env 83 # this would require some extra work on read-only /usr 84 # and it is not a strict necessity 85 system.activationScripts.usrbinenv = lib.mkForce ""; 86 }; 87 88 testScript = 89 { nodes, ... }: # python 90 '' 91 import os 92 import subprocess 93 import tempfile 94 95 tmp_disk_image = tempfile.NamedTemporaryFile() 96 97 subprocess.run([ 98 "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img", 99 "create", 100 "-f", 101 "qcow2", 102 "-b", 103 "${nodes.machine.system.build.finalImage}/${nodes.machine.image.repart.imageFile}", 104 "-F", 105 "raw", 106 tmp_disk_image.name, 107 ]) 108 109 os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name 110 111 machine.wait_for_unit("default.target") 112 113 with subtest("Running with volatile root"): 114 machine.succeed("findmnt --kernel --type tmpfs /") 115 116 with subtest("/nix/store is backed by dm-verity protected fs"): 117 verity_info = machine.succeed("dmsetup info --target verity usr") 118 assert "ACTIVE" in verity_info,f"unexpected verity info: {verity_info}" 119 120 backing_device = machine.succeed("df --output=source /nix/store | tail -n1").strip() 121 assert "/dev/mapper/usr" == backing_device,"unexpected backing device: {backing_device}" 122 ''; 123}