nixos/image/repart-verity-store: also support building images that do not have system.image.version set

The current limitation seems artificial and gives a very confusing error
message
This commit is contained in:
Arian van Putten
2026-01-07 11:29:28 +01:00
parent dff30f9b79
commit a5c1fff249
2 changed files with 54 additions and 34 deletions
+5 -1
View File
@@ -123,7 +123,11 @@ in
(
_: previousAttrs: {
# make it easier to identify the intermediate image in build logs
pname = "${previousAttrs.pname}-intermediate";
name =
if previousAttrs ? pname then
"${previousAttrs.pname}-${previousAttrs.version}-intermediate"
else
"${previousAttrs.name}-intermediate";
# do not prepare the ESP, this is done in the final image
systemdRepartFlags = previousAttrs.systemdRepartFlags ++ [ "--defer-partitions=esp" ];
@@ -10,13 +10,8 @@
willibutz
];
nodes.machine =
{
config,
lib,
pkgs,
...
}:
defaults =
{ config, lib, ... }:
let
inherit (config.image.repart.verityStore) partitionIds;
in
@@ -75,10 +70,7 @@
initrd.systemd.enable = true;
};
system.image = {
id = "nixos-appliance";
version = "1";
};
system.image.id = "nixos-appliance";
# don't create /usr/bin/env
# this would require some extra work on read-only /usr
@@ -86,6 +78,12 @@
system.activationScripts.usrbinenv = lib.mkForce "";
};
nodes.machine = {
system.image.version = "1";
};
nodes.without-version = { };
testScript =
{ nodes, ... }: # python
''
@@ -93,32 +91,50 @@
import subprocess
import tempfile
tmp_disk_image = tempfile.NamedTemporaryFile()
def create_disk_image(qemu_img, backing_file):
tmp = tempfile.NamedTemporaryFile()
subprocess.run([
qemu_img,
"create",
"-f",
"qcow2",
"-b",
backing_file,
"-F",
"raw",
tmp.name,
], check=True)
return tmp
subprocess.run([
def run_verity_tests(machine):
with subtest("Running with volatile root"):
machine.succeed("findmnt --kernel --type tmpfs /")
with subtest("/nix/store is backed by dm-verity protected fs"):
verity_info = machine.succeed("dmsetup info --target verity usr")
assert "ACTIVE" in verity_info, f"unexpected verity info: {verity_info}"
backing_device = machine.succeed("df --output=source /nix/store | tail -n1").strip()
assert "/dev/mapper/usr" == backing_device, f"unexpected backing device: {backing_device}"
tmp_disk_machine = create_disk_image(
"${nodes.machine.virtualisation.qemu.package}/bin/qemu-img",
"create",
"-f",
"qcow2",
"-b",
"${nodes.machine.system.build.image}/${nodes.machine.image.filePath}",
"-F",
"raw",
tmp_disk_image.name,
])
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
)
os.environ['NIX_DISK_IMAGE'] = tmp_disk_machine.name
machine.wait_for_unit("default.target")
run_verity_tests(machine)
with subtest("Image version is set"):
machine.succeed("grep IMAGE_VERSION=1 /etc/os-release")
with subtest("Running with volatile root"):
machine.succeed("findmnt --kernel --type tmpfs /")
with subtest("/nix/store is backed by dm-verity protected fs"):
verity_info = machine.succeed("dmsetup info --target verity usr")
assert "ACTIVE" in verity_info,f"unexpected verity info: {verity_info}"
backing_device = machine.succeed("df --output=source /nix/store | tail -n1").strip()
assert "/dev/mapper/usr" == backing_device,"unexpected backing device: {backing_device}"
tmp_disk_without_version = create_disk_image(
"${nodes."without-version".virtualisation.qemu.package}/bin/qemu-img",
"${nodes."without-version".system.build.image}/${nodes."without-version".image.filePath}",
)
os.environ['NIX_DISK_IMAGE'] = tmp_disk_without_version.name
without_version.wait_for_unit("default.target")
run_verity_tests(without_version)
with subtest("Image version is not set"):
without_version.succeed('grep IMAGE_VERSION="" /etc/os-release')
'';
}