1{ lib, ... }:
2
3let
4 rootFslabel = "external";
5 rootFsDevice = "/dev/disk/by-label/${rootFslabel}";
6
7 externalModule =
8 partitionTableType:
9 {
10 config,
11 lib,
12 pkgs,
13 ...
14 }:
15 {
16 virtualisation.directBoot.enable = false;
17 virtualisation.mountHostNixStore = false;
18 virtualisation.useEFIBoot = partitionTableType == "efi";
19
20 # This stops the qemu-vm module from overriding the fileSystems option
21 # with virtualisation.fileSystems.
22 virtualisation.fileSystems = lib.mkForce { };
23
24 boot.loader.grub.enable = true;
25 boot.loader.grub.efiSupport = partitionTableType == "efi";
26 boot.loader.grub.efiInstallAsRemovable = partitionTableType == "efi";
27 boot.loader.grub.device = if partitionTableType == "efi" then "nodev" else "/dev/vda";
28
29 boot.growPartition = true;
30
31 fileSystems = {
32 "/".device = rootFsDevice;
33 };
34
35 # Needed for installing bootloader
36 system.switch.enable = true;
37
38 system.build.diskImage = import ../lib/make-disk-image.nix {
39 inherit config lib pkgs;
40 label = rootFslabel;
41 inherit partitionTableType;
42 format = "raw";
43 bootSize = "128M";
44 additionalSpace = "0M";
45 copyChannel = false;
46 };
47 };
48in
49{
50 name = "grow-partition";
51
52 meta.maintainers = with lib.maintainers; [ arianvp ];
53
54 nodes = {
55 efi = externalModule "efi";
56 legacy = externalModule "legacy";
57 legacyGPT = externalModule "legacy+gpt";
58 hybrid = externalModule "hybrid";
59 };
60
61 testScript =
62 { nodes, ... }:
63 lib.concatLines (
64 lib.mapAttrsToList (name: node: ''
65 import os
66 import subprocess
67 import tempfile
68 import shutil
69
70 tmp_disk_image = tempfile.NamedTemporaryFile()
71
72 shutil.copyfile("${node.system.build.diskImage}/nixos.img", tmp_disk_image.name)
73
74 subprocess.run([
75 "${node.virtualisation.qemu.package}/bin/qemu-img",
76 "resize",
77 "-f",
78 "raw",
79 tmp_disk_image.name,
80 "+32M",
81 ])
82
83 # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image.
84 os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
85
86 ${name}.wait_for_unit("growpart.service")
87 systemd_growpart_logs = ${name}.succeed("journalctl --boot --unit growpart.service")
88 assert "CHANGED" in systemd_growpart_logs
89 ${name}.succeed("systemctl restart growpart.service")
90 systemd_growpart_logs = ${name}.succeed("journalctl --boot --unit growpart.service")
91 assert "NOCHANGE" in systemd_growpart_logs
92
93 '') nodes
94 );
95}