From d8112ea386634c353b2d5e6ad48b1930b59a43c0 Mon Sep 17 00:00:00 2001 From: Joshua Date: Thu, 15 Oct 2026 11:30:18 +0300 Subject: [PATCH] fix(nix): build the same image on every machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same commit measured to two PCR0s: 458969f7 from CI, 7bdd3f85 from a workstation. Taking both images apart, the kernel, the command line, the boot ramdisk and every file of the rootfs but two were identical. The two were the ZFS modules, spl.ko and zfs.ko: ZFS's assertions carry __FILE__, so the modules recorded where they were compiled, /build/source in a sandboxed Nix and /tmp/nix-build-zfs-kernel-…/source in one without a sandbox. The module build now maps its build directory to /build, the sandbox's own path. A sandboxed build is unchanged by it, and a workstation's now measures to CI's PCR0: 458969f7 from both. PCR0 for every image already built in a sandbox stays what it was. eif_build's clock is also frozen rather than started at the epoch: with the @ faketime let it run, and BuildTime's nanoseconds differed between builds. That is metadata, which no PCR covers, but it kept the files from being identical; `nix build .#eif-qemu --rebuild` now passes. Co-Authored-By: Claude Opus 5.5 --- nix/eif.nix | 4 +++- nix/kernel-zfs.nix | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/nix/eif.nix b/nix/eif.nix index b1c1e64..55c84cf 100644 --- a/nix/eif.nix +++ b/nix/eif.nix @@ -150,7 +150,9 @@ stdenvNoCC.mkDerivation { # people compare artifacts by hashing them, and because it lets # `nix build --rebuild` be a check that passes rather than a known # exception. - faketime -f '@1970-01-01 00:00:01' \ + # No `@`: with one, faketime starts the clock there and lets it run, and the nanoseconds it + # had run for by the time eif_build read it still differed between builds. + faketime -f '1970-01-01 00:00:01' \ eif_build \ --kernel ${kernel}/bzImage \ --kernel_config ${kernel}/bzImage.config \ diff --git a/nix/kernel-zfs.nix b/nix/kernel-zfs.nix index b49f909..2845a8e 100644 --- a/nix/kernel-zfs.nix +++ b/nix/kernel-zfs.nix @@ -78,7 +78,15 @@ let extraMakeFlags = [ "KBUILD_BUILD_USER=nixbuild" "KBUILD_BUILD_HOST=nixbuilder" ]; }; - zfsKmod = (linuxPackagesFor kernel).${zfs.kernelModuleAttribute}; + # ZFS's assertions carry __FILE__, so its modules record where they were compiled: /build/source + # in a sandboxed Nix, a temporary directory in one without a sandbox. The image held them, and + # the same commit measured to two PCR0s. Mapped to the sandbox's path, every builder produces + # the modules a sandboxed one always did. + zfsKmod = ((linuxPackagesFor kernel).${zfs.kernelModuleAttribute}).overrideAttrs (old: { + preBuild = (old.preBuild or "") + '' + export KCFLAGS="''${KCFLAGS:-} -ffile-prefix-map=$NIX_BUILD_TOP=/build" + ''; + }); in assert zfsKmod.version == zfs.version; {