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