diff --git a/nixos/modules/system/etc/build-composefs-dump.py b/nixos/modules/system/etc/build-composefs-dump.py index fe739a621ec4..d8ede9aebf83 100644 --- a/nixos/modules/system/etc/build-composefs-dump.py +++ b/nixos/modules/system/etc/build-composefs-dump.py @@ -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 diff --git a/nixos/tests/activation/etc-overlay-immutable.nix b/nixos/tests/activation/etc-overlay-immutable.nix index 2adb91114014..539010c4ad66 100644 --- a/nixos/tests/activation/etc-overlay-immutable.nix +++ b/nixos/tests/activation/etc-overlay-immutable.nix @@ -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" diff --git a/nixos/tests/activation/etc-overlay-mutable.nix b/nixos/tests/activation/etc-overlay-mutable.nix index 5dc27dedb30b..be0c80da861a 100644 --- a/nixos/tests/activation/etc-overlay-mutable.nix +++ b/nixos/tests/activation/etc-overlay-mutable.nix @@ -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")