Various repart image simplifications (#485954)
This commit is contained in:
@@ -96,6 +96,7 @@ in
|
||||
Verity = "hash";
|
||||
VerityMatchKey = lib.mkDefault verityMatchKey;
|
||||
Label = lib.mkDefault "store-verity";
|
||||
Minimize = lib.mkDefault "best";
|
||||
};
|
||||
# dm-verity data partition that contains the nix store
|
||||
${cfg.partitionIds.store} = {
|
||||
@@ -106,23 +107,29 @@ in
|
||||
Format = lib.mkDefault "erofs";
|
||||
VerityMatchKey = lib.mkDefault verityMatchKey;
|
||||
Label = lib.mkDefault "store";
|
||||
Minimize = lib.mkDefault "best";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
system.build = {
|
||||
finalImage = lib.warn "system.build.finalImage has been renamed to system.build.image" config.system.build.image;
|
||||
|
||||
# intermediate system image without ESP
|
||||
intermediateImage =
|
||||
(config.system.build.image.override {
|
||||
(config.image.repart.image.override {
|
||||
# always disable compression for the intermediate image
|
||||
compression.enable = false;
|
||||
}).overrideAttrs
|
||||
(
|
||||
_: 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" ];
|
||||
@@ -162,8 +169,8 @@ in
|
||||
);
|
||||
|
||||
# final system image that is created from the intermediate image by injecting the UKI from above
|
||||
finalImage =
|
||||
(config.system.build.image.override {
|
||||
image = lib.mkOverride 99 (
|
||||
(config.image.repart.image.override {
|
||||
# continue building with existing intermediate image
|
||||
createEmpty = false;
|
||||
}).overrideAttrs
|
||||
@@ -216,7 +223,8 @@ in
|
||||
rm -v repart-output_orig.json
|
||||
'';
|
||||
}
|
||||
);
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -282,6 +282,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
image = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
The image built by this module. Used as the default for `system.build.image`.
|
||||
'';
|
||||
};
|
||||
|
||||
assertions = lib.mkOption {
|
||||
type = options.assertions.type;
|
||||
default = [ ];
|
||||
@@ -356,6 +365,37 @@ in
|
||||
|
||||
finalPartitions = lib.mapAttrs addClosure cfg.partitions;
|
||||
|
||||
image =
|
||||
let
|
||||
fileSystems = lib.filter (f: f != null) (
|
||||
lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions
|
||||
);
|
||||
|
||||
format = pkgs.formats.ini { listsAsDuplicateKeys = true; };
|
||||
|
||||
definitionsDirectory = utils.systemdUtils.lib.definitions "repart.d" format (
|
||||
lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) cfg.finalPartitions
|
||||
);
|
||||
|
||||
mkfsEnv = mkfsOptionsToEnv cfg.mkfsOptions;
|
||||
val = pkgs.callPackage ./repart-image.nix {
|
||||
systemd = cfg.package;
|
||||
inherit (config.image) baseName;
|
||||
inherit (cfg)
|
||||
name
|
||||
version
|
||||
compression
|
||||
split
|
||||
seed
|
||||
imageSize
|
||||
sectorSize
|
||||
finalPartitions
|
||||
;
|
||||
inherit fileSystems definitionsDirectory mkfsEnv;
|
||||
};
|
||||
in
|
||||
lib.asserts.checkAssertWarn cfg.assertions cfg.warnings val;
|
||||
|
||||
assertions = lib.mapAttrsToList (
|
||||
fileName: partitionConfig:
|
||||
let
|
||||
@@ -401,36 +441,7 @@ in
|
||||
);
|
||||
};
|
||||
|
||||
system.build.image =
|
||||
let
|
||||
fileSystems = lib.filter (f: f != null) (
|
||||
lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions
|
||||
);
|
||||
|
||||
format = pkgs.formats.ini { listsAsDuplicateKeys = true; };
|
||||
|
||||
definitionsDirectory = utils.systemdUtils.lib.definitions "repart.d" format (
|
||||
lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) cfg.finalPartitions
|
||||
);
|
||||
|
||||
mkfsEnv = mkfsOptionsToEnv cfg.mkfsOptions;
|
||||
val = pkgs.callPackage ./repart-image.nix {
|
||||
systemd = cfg.package;
|
||||
inherit (config.image) baseName;
|
||||
inherit (cfg)
|
||||
name
|
||||
version
|
||||
compression
|
||||
split
|
||||
seed
|
||||
imageSize
|
||||
sectorSize
|
||||
finalPartitions
|
||||
;
|
||||
inherit fileSystems definitionsDirectory mkfsEnv;
|
||||
};
|
||||
in
|
||||
lib.asserts.checkAssertWarn cfg.assertions cfg.warnings val;
|
||||
system.build.image = cfg.image;
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
|
||||
@@ -10,13 +10,8 @@
|
||||
willibutz
|
||||
];
|
||||
|
||||
nodes.machine =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
defaults =
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (config.image.repart.verityStore) partitionIds;
|
||||
in
|
||||
@@ -55,12 +50,6 @@
|
||||
SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M";
|
||||
};
|
||||
};
|
||||
${partitionIds.store-verity}.repartConfig = {
|
||||
Minimize = "best";
|
||||
};
|
||||
${partitionIds.store}.repartConfig = {
|
||||
Minimize = "best";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -75,10 +64,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 +72,12 @@
|
||||
system.activationScripts.usrbinenv = lib.mkForce "";
|
||||
};
|
||||
|
||||
nodes.machine = {
|
||||
system.image.version = "1";
|
||||
};
|
||||
|
||||
nodes.without-version = { };
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }: # python
|
||||
''
|
||||
@@ -93,32 +85,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.finalImage}/${nodes.machine.image.repart.imageFile}",
|
||||
"-F",
|
||||
"raw",
|
||||
tmp_disk_image.name,
|
||||
])
|
||||
|
||||
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
|
||||
|
||||
"${nodes.machine.system.build.image}/${nodes.machine.image.filePath}",
|
||||
)
|
||||
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')
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ in
|
||||
"-f",
|
||||
"qcow2",
|
||||
"-b",
|
||||
"${nodes.machine.system.build.image}/${nodes.machine.image.repart.imageFile}",
|
||||
"${nodes.machine.system.build.image}/${nodes.machine.image.filePath}",
|
||||
"-F",
|
||||
"raw",
|
||||
tmp_disk_image.name,
|
||||
|
||||
Reference in New Issue
Block a user