diff options
Diffstat (limited to 'nixpkgs/nixos/tests/systemd-repart.nix')
-rw-r--r-- | nixpkgs/nixos/tests/systemd-repart.nix | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/nixpkgs/nixos/tests/systemd-repart.nix b/nixpkgs/nixos/tests/systemd-repart.nix new file mode 100644 index 000000000000..3914d5b32397 --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-repart.nix @@ -0,0 +1,182 @@ +{ system ? builtins.currentSystem +, config ? { } +, pkgs ? import ../.. { inherit system config; } +}: + +with import ../lib/testing-python.nix { inherit system pkgs; }; +with pkgs.lib; + +let + # A testScript fragment that prepares a disk with some empty, unpartitioned + # space. and uses it to boot the test with. Takes a single argument `machine` + # from which the diskImage is extracted. + useDiskImage = machine: '' + import os + import shutil + import subprocess + import tempfile + + tmp_disk_image = tempfile.NamedTemporaryFile() + + shutil.copyfile("${machine.system.build.diskImage}/nixos.img", tmp_disk_image.name) + + subprocess.run([ + "${machine.config.virtualisation.qemu.package}/bin/qemu-img", + "resize", + "-f", + "raw", + tmp_disk_image.name, + "+32M", + ]) + + # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image. + os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name + ''; + + common = { config, pkgs, lib, ... }: { + virtualisation.useDefaultFilesystems = false; + virtualisation.fileSystems = { + "/" = { + device = "/dev/vda2"; + fsType = "ext4"; + }; + }; + + # systemd-repart operates on disks with a partition table. The qemu module, + # however, creates separate filesystem images without a partition table, so + # we have to create a disk image manually. + # + # This creates two partitions, an ESP available as /dev/vda1 and the root + # partition available as /dev/vda2. + system.build.diskImage = import ../lib/make-disk-image.nix { + inherit config pkgs lib; + # Use a raw format disk so that it can be resized before starting the + # test VM. + format = "raw"; + # Keep the image as small as possible but leave some room for changes. + bootSize = "32M"; + additionalSpace = "0M"; + # GPT with an EFI System Partition is the typical use case for + # systemd-repart because it does not support MBR. + partitionTableType = "efi"; + # We do not actually care much about the content of the partitions, so we + # do not need a bootloader installed. + installBootLoader = false; + # Improve determinism by not copying a channel. + copyChannel = false; + }; + }; +in +{ + basic = makeTest { + name = "systemd-repart"; + meta.maintainers = with maintainers; [ nikstur ]; + + nodes.machine = { config, pkgs, ... }: { + imports = [ common ]; + + boot.initrd.systemd.enable = true; + + boot.initrd.systemd.repart.enable = true; + systemd.repart.partitions = { + "10-root" = { + Type = "linux-generic"; + }; + }; + }; + + testScript = { nodes, ... }: '' + ${useDiskImage nodes.machine} + + machine.start() + machine.wait_for_unit("multi-user.target") + + systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") + assert "Growing existing partition 1." in systemd_repart_logs + ''; + }; + + after-initrd = makeTest { + name = "systemd-repart-after-initrd"; + meta.maintainers = with maintainers; [ nikstur ]; + + nodes.machine = { config, pkgs, ... }: { + imports = [ common ]; + + systemd.repart.enable = true; + systemd.repart.partitions = { + "10-root" = { + Type = "linux-generic"; + }; + }; + }; + + testScript = { nodes, ... }: '' + ${useDiskImage nodes.machine} + + machine.start() + machine.wait_for_unit("multi-user.target") + + systemd_repart_logs = machine.succeed("journalctl --unit systemd-repart.service") + assert "Growing existing partition 1." in systemd_repart_logs + ''; + }; + + create-root = makeTest { + name = "systemd-repart-create-root"; + meta.maintainers = with maintainers; [ nikstur ]; + + nodes.machine = { config, lib, pkgs, ... }: { + virtualisation.useDefaultFilesystems = false; + virtualisation.fileSystems = { + "/" = { + device = "/dev/disk/by-partlabel/created-root"; + fsType = "ext4"; + }; + "/nix/store" = { + device = "/dev/vda2"; + fsType = "ext4"; + }; + }; + + # Create an image containing only the Nix store. This enables creating + # the root partition with systemd-repart and then successfully booting + # into a working system. + # + # This creates two partitions, an ESP available as /dev/vda1 and the Nix + # store available as /dev/vda2. + system.build.diskImage = import ../lib/make-disk-image.nix { + inherit config pkgs lib; + onlyNixStore = true; + format = "raw"; + bootSize = "32M"; + additionalSpace = "0M"; + partitionTableType = "efi"; + installBootLoader = false; + copyChannel = false; + }; + + boot.initrd.systemd.enable = true; + + boot.initrd.systemd.repart.enable = true; + boot.initrd.systemd.repart.device = "/dev/vda"; + systemd.repart.partitions = { + "10-root" = { + Type = "root"; + Label = "created-root"; + Format = "ext4"; + }; + }; + }; + + testScript = { nodes, ... }: '' + ${useDiskImage nodes.machine} + + machine.start() + machine.wait_for_unit("multi-user.target") + + systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") + assert "Adding new partition 2 to partition table." in systemd_repart_logs + ''; + }; +} |