at 25.11-pre 5.8 kB view raw
1{ 2 system ? builtins.currentSystem, 3 config ? { }, 4 pkgs ? import ../.. { inherit system config; }, 5}: 6 7with import ../lib/testing-python.nix { inherit system pkgs; }; 8with pkgs.lib; 9 10let 11 # A testScript fragment that prepares a disk with some empty, unpartitioned 12 # space. and uses it to boot the test with. Takes a single argument `machine` 13 # from which the diskImage is extracted. 14 useDiskImage = machine: '' 15 import os 16 import shutil 17 import subprocess 18 import tempfile 19 20 tmp_disk_image = tempfile.NamedTemporaryFile() 21 22 shutil.copyfile("${machine.system.build.diskImage}/nixos.img", tmp_disk_image.name) 23 24 subprocess.run([ 25 "${machine.virtualisation.qemu.package}/bin/qemu-img", 26 "resize", 27 "-f", 28 "raw", 29 tmp_disk_image.name, 30 "+32M", 31 ]) 32 33 # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image. 34 os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name 35 ''; 36 37 common = 38 { 39 config, 40 pkgs, 41 lib, 42 ... 43 }: 44 { 45 virtualisation.useDefaultFilesystems = false; 46 virtualisation.fileSystems = { 47 "/" = { 48 device = "/dev/vda2"; 49 fsType = "ext4"; 50 }; 51 }; 52 53 # systemd-repart operates on disks with a partition table. The qemu module, 54 # however, creates separate filesystem images without a partition table, so 55 # we have to create a disk image manually. 56 # 57 # This creates two partitions, an ESP available as /dev/vda1 and the root 58 # partition available as /dev/vda2. 59 system.build.diskImage = import ../lib/make-disk-image.nix { 60 inherit config pkgs lib; 61 # Use a raw format disk so that it can be resized before starting the 62 # test VM. 63 format = "raw"; 64 # Keep the image as small as possible but leave some room for changes. 65 bootSize = "32M"; 66 additionalSpace = "0M"; 67 # GPT with an EFI System Partition is the typical use case for 68 # systemd-repart because it does not support MBR. 69 partitionTableType = "efi"; 70 # We do not actually care much about the content of the partitions, so we 71 # do not need a bootloader installed. 72 installBootLoader = false; 73 # Improve determinism by not copying a channel. 74 copyChannel = false; 75 }; 76 }; 77in 78{ 79 basic = makeTest { 80 name = "systemd-repart"; 81 meta.maintainers = with maintainers; [ nikstur ]; 82 83 nodes.machine = 84 { config, pkgs, ... }: 85 { 86 imports = [ common ]; 87 88 boot.initrd.systemd.enable = true; 89 90 boot.initrd.systemd.repart.enable = true; 91 systemd.repart.partitions = { 92 "10-root" = { 93 Type = "linux-generic"; 94 }; 95 }; 96 }; 97 98 testScript = 99 { nodes, ... }: 100 '' 101 ${useDiskImage nodes.machine} 102 103 machine.start() 104 machine.wait_for_unit("multi-user.target") 105 106 systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") 107 assert "Growing existing partition 1." in systemd_repart_logs 108 ''; 109 }; 110 111 after-initrd = makeTest { 112 name = "systemd-repart-after-initrd"; 113 meta.maintainers = with maintainers; [ nikstur ]; 114 115 nodes.machine = 116 { config, pkgs, ... }: 117 { 118 imports = [ common ]; 119 120 systemd.repart.enable = true; 121 systemd.repart.partitions = { 122 "10-root" = { 123 Type = "linux-generic"; 124 }; 125 }; 126 }; 127 128 testScript = 129 { nodes, ... }: 130 '' 131 ${useDiskImage nodes.machine} 132 133 machine.start() 134 machine.wait_for_unit("multi-user.target") 135 136 systemd_repart_logs = machine.succeed("journalctl --unit systemd-repart.service") 137 assert "Growing existing partition 1." in systemd_repart_logs 138 ''; 139 }; 140 141 create-root = makeTest { 142 name = "systemd-repart-create-root"; 143 meta.maintainers = with maintainers; [ nikstur ]; 144 145 nodes.machine = 146 { 147 config, 148 lib, 149 pkgs, 150 ... 151 }: 152 { 153 virtualisation.useDefaultFilesystems = false; 154 virtualisation.mountHostNixStore = false; 155 virtualisation.fileSystems = { 156 "/" = { 157 device = "/dev/disk/by-partlabel/created-root"; 158 fsType = "ext4"; 159 }; 160 "/nix/store" = { 161 device = "/dev/vda2"; 162 fsType = "ext4"; 163 }; 164 }; 165 166 # Create an image containing only the Nix store. This enables creating 167 # the root partition with systemd-repart and then successfully booting 168 # into a working system. 169 # 170 # This creates two partitions, an ESP available as /dev/vda1 and the Nix 171 # store available as /dev/vda2. 172 system.build.diskImage = import ../lib/make-disk-image.nix { 173 inherit config pkgs lib; 174 onlyNixStore = true; 175 format = "raw"; 176 bootSize = "32M"; 177 additionalSpace = "0M"; 178 partitionTableType = "efi"; 179 installBootLoader = false; 180 copyChannel = false; 181 }; 182 183 boot.initrd.systemd.enable = true; 184 185 boot.initrd.systemd.repart.enable = true; 186 boot.initrd.systemd.repart.device = "/dev/vda"; 187 systemd.repart.partitions = { 188 "10-root" = { 189 Type = "root"; 190 Label = "created-root"; 191 Format = "ext4"; 192 }; 193 }; 194 }; 195 196 testScript = 197 { nodes, ... }: 198 '' 199 ${useDiskImage nodes.machine} 200 201 machine.start() 202 machine.wait_for_unit("multi-user.target") 203 204 systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") 205 assert "Adding new partition 2 to partition table." in systemd_repart_logs 206 ''; 207 }; 208}