nixos/etc-overlay: pad the mode when building the composefs dump

Fixes https://github.com/NixOS/nixpkgs/issues/462972
This commit is contained in:
r-vdp
2025-11-22 20:49:09 -03:00
parent 73a6106226
commit 01aacd04f8
3 changed files with 41 additions and 1 deletions
@@ -61,7 +61,15 @@ class ComposefsPath:
self.path = path
self.size = size
self.filetype = filetype
self.mode = mode
match len(mode):
case 3 | 4:
# We need to pad the mode, because we will later use the concatentation
# filetype|mode, which assumes that the mode has a length of 4.
self.mode = f"{mode:0>4}"
case _:
raise ValueError(f"mode should be 3 or 4 octal digits, got: {mode}")
self.uid = attrs["uid"]
self.gid = attrs["gid"]
self.payload = payload
@@ -11,6 +11,17 @@
system.etc.overlay.enable = true;
system.etc.overlay.mutable = false;
environment.etc = {
modetest = {
text = "foo";
mode = "300";
};
modetest2 = {
text = "foo";
mode = "0300";
};
};
# Prerequisites
systemd.sysusers.enable = true;
users.mutableUsers = false;
@@ -49,6 +60,10 @@
with subtest("/etc is mounted as an overlay"):
machine.succeed("findmnt --kernel --type overlay /etc")
with subtest("modes work correctly"):
machine.succeed("stat --format '%F' /etc/modetest | tee /dev/stderr | grep -q 'regular file'")
machine.succeed("stat --format '%F' /etc/modetest2 | tee /dev/stderr | grep -q 'regular file'")
with subtest("direct symlinks point to the target without indirection"):
assert machine.succeed("readlink -n /etc/localtime") == "/etc/zoneinfo/Utc"
@@ -11,6 +11,17 @@
system.etc.overlay.enable = true;
system.etc.overlay.mutable = true;
environment.etc = {
modetest = {
text = "foo";
mode = "300";
};
modetest2 = {
text = "foo";
mode = "0300";
};
};
# Prerequisites
boot.initrd.systemd.enable = true;
boot.kernelPackages = pkgs.linuxPackages_latest;
@@ -37,6 +48,12 @@
with subtest("/etc is mounted as an overlay"):
machine.succeed("findmnt --kernel --type overlay /etc")
with subtest("modes work correctly"):
machine.succeed("stat --format '%F' /etc/modetest | tee /dev/stderr | grep -Eq '^regular file$'")
machine.succeed("stat --format '%a' /etc/modetest | tee /dev/stderr | grep -Eq '^300$'")
machine.succeed("stat --format '%F' /etc/modetest2 | tee /dev/stderr | grep -Eq '^regular file$'")
machine.succeed("stat --format '%a' /etc/modetest2 | tee /dev/stderr | grep -Eq '^300$'")
with subtest("switching to the same generation"):
machine.succeed("/run/current-system/bin/switch-to-configuration test")