nixos/tests/appliance-repart-image-verity-store: init
This test should illustrate how to build a verity-protected NixOS image with systemd-repart, using the opinionated image.repart.verityStore module.
This commit is contained in:
parent
942588c686
commit
56d038e17d
@ -128,6 +128,7 @@ in {
|
|||||||
apcupsd = handleTest ./apcupsd.nix {};
|
apcupsd = handleTest ./apcupsd.nix {};
|
||||||
apfs = runTest ./apfs.nix;
|
apfs = runTest ./apfs.nix;
|
||||||
appliance-repart-image = runTest ./appliance-repart-image.nix;
|
appliance-repart-image = runTest ./appliance-repart-image.nix;
|
||||||
|
appliance-repart-image-verity-store = runTest ./appliance-repart-image-verity-store.nix;
|
||||||
apparmor = handleTest ./apparmor.nix {};
|
apparmor = handleTest ./apparmor.nix {};
|
||||||
archi = handleTest ./archi.nix {};
|
archi = handleTest ./archi.nix {};
|
||||||
aria2 = handleTest ./aria2.nix {};
|
aria2 = handleTest ./aria2.nix {};
|
||||||
|
130
nixos/tests/appliance-repart-image-verity-store.nix
Normal file
130
nixos/tests/appliance-repart-image-verity-store.nix
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
# similar to the appliance-repart-image test but with a dm-verity
|
||||||
|
# protected nix store and tmpfs as rootfs
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "appliance-repart-image-verity-store";
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [
|
||||||
|
nikstur
|
||||||
|
willibutz
|
||||||
|
];
|
||||||
|
|
||||||
|
nodes.machine =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (config.image.repart.verityStore) partitionIds;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../modules/image/repart.nix ];
|
||||||
|
|
||||||
|
virtualisation.fileSystems = lib.mkVMOverride {
|
||||||
|
"/" = {
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [ "mode=0755" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
"/usr" = {
|
||||||
|
device = "/dev/mapper/usr";
|
||||||
|
# explicitly mount it read-only otherwise systemd-remount-fs will fail
|
||||||
|
options = [ "ro" ];
|
||||||
|
fsType = config.image.repart.partitions.${partitionIds.store}.repartConfig.Format;
|
||||||
|
};
|
||||||
|
|
||||||
|
# bind-mount the store
|
||||||
|
"/nix/store" = {
|
||||||
|
device = "/usr/nix/store";
|
||||||
|
options = [ "bind" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
image.repart = {
|
||||||
|
verityStore = {
|
||||||
|
enable = true;
|
||||||
|
# by default the module works with systemd-boot, for simplicity this test directly boots the UKI
|
||||||
|
ukiPath = "/EFI/BOOT/BOOT${lib.toUpper config.nixpkgs.hostPlatform.efiArch}.EFI";
|
||||||
|
};
|
||||||
|
|
||||||
|
name = "appliance-verity-store-image";
|
||||||
|
|
||||||
|
partitions = {
|
||||||
|
${partitionIds.esp} = {
|
||||||
|
# the UKI is injected into this partition by the verityStore module
|
||||||
|
repartConfig = {
|
||||||
|
Type = "esp";
|
||||||
|
Format = "vfat";
|
||||||
|
SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
${partitionIds.store-verity}.repartConfig = {
|
||||||
|
Minimize = "best";
|
||||||
|
};
|
||||||
|
${partitionIds.store}.repartConfig = {
|
||||||
|
Minimize = "best";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation = {
|
||||||
|
directBoot.enable = false;
|
||||||
|
mountHostNixStore = false;
|
||||||
|
useEFIBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
loader.grub.enable = false;
|
||||||
|
initrd.systemd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
system.image = {
|
||||||
|
id = "nixos-appliance";
|
||||||
|
version = "1";
|
||||||
|
};
|
||||||
|
|
||||||
|
# don't create /usr/bin/env
|
||||||
|
# this would require some extra work on read-only /usr
|
||||||
|
# and it is not a strict necessity
|
||||||
|
system.activationScripts.usrbinenv = lib.mkForce "";
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
{ nodes, ... }: # python
|
||||||
|
''
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
tmp_disk_image = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
|
subprocess.run([
|
||||||
|
"${nodes.machine.virtualisation.qemu.package}/bin/qemu-img",
|
||||||
|
"create",
|
||||||
|
"-f",
|
||||||
|
"qcow2",
|
||||||
|
"-b",
|
||||||
|
"${nodes.machine.system.build.finalImage}/${nodes.machine.image.repart.imageFile}",
|
||||||
|
"-F",
|
||||||
|
"raw",
|
||||||
|
tmp_disk_image.name,
|
||||||
|
])
|
||||||
|
|
||||||
|
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
|
||||||
|
|
||||||
|
machine.wait_for_unit("default.target")
|
||||||
|
|
||||||
|
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}"
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user