From 4f8c8580b45c0ce69bf22a0b2bc5743db50d9c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Mon, 6 May 2024 19:29:20 +0200 Subject: [PATCH] fix building images when non-binary reproducible builds are present closure-info has one flaw, it's possible that this file contains stale information when build are not reproducible and the local checksum doesn't match what the remote build created. The work-around here is that we disregard the hashes and re-compute with what nar's we actually have locally instead. --- lib/closure-info.nix | 45 +++++++++++++++++++++++++++++++++++++++++ lib/make-disk-image.nix | 4 +++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 lib/closure-info.nix diff --git a/lib/closure-info.nix b/lib/closure-info.nix new file mode 100644 index 0000000..e40fe18 --- /dev/null +++ b/lib/closure-info.nix @@ -0,0 +1,45 @@ +# This is a modified version of the closure-info derivation from nixpkgs. +# Unlike the original, it does not include hashes in the registration file, +# which might be incorrect if a build is not binary reproducible. + +# This derivation builds two files containing information about the +# closure of 'rootPaths': $out/store-paths contains the paths in the +# closure, and $out/registration contains a file suitable for use with +# "nix-store --register-validity". + +{ stdenv, coreutils, jq }: + +{ rootPaths }: + +assert builtins.langVersion >= 5; + +stdenv.mkDerivation { + name = "closure-info"; + + __structuredAttrs = true; + + exportReferencesGraph.closure = rootPaths; + + preferLocalBuild = true; + + nativeBuildInputs = [ coreutils jq ]; + + empty = rootPaths == []; + + buildCommand = + '' + out=''${outputs[out]} + + mkdir $out + + if [[ -n "$empty" ]]; then + echo 0 > $out/total-nar-size + touch $out/registration $out/store-paths + else + jq -r ".closure | map(.narSize) | add" < "$NIX_ATTRS_JSON_FILE" > $out/total-nar-size + jq -r '.closure | map([.path, "", (.references | length)] + .references) | add | map("\(.)\n") | add' < "$NIX_ATTRS_JSON_FILE" | head -n -1 > $out/registration + jq -r '.closure[].path' < "$NIX_ATTRS_JSON_FILE" > $out/store-paths + fi + + ''; +} diff --git a/lib/make-disk-image.nix b/lib/make-disk-image.nix index 7bbc021..69db53e 100644 --- a/lib/make-disk-image.nix +++ b/lib/make-disk-image.nix @@ -38,6 +38,8 @@ let ${lib.concatMapStringsSep "\n" (disk: "mv ${disk.name}.raw \"$out\"/${disk.name}.raw") (lib.attrValues nixosConfig.config.disko.devices.disk)} ${extraPostVM} ''; + + closureInfo = pkgs.callPackage ./closure-info.nix { }; partitioner = '' # running udev, stolen from stage-1.sh echo "running udev..." @@ -55,7 +57,7 @@ let # populate nix db, so nixos-install doesn't complain export NIX_STATE_DIR=$TMPDIR/state - nix-store --load-db < ${pkgs.closureInfo { + ${pkgs.fakeroot}/bin/fakeroot nix-store --register-validity --reregister < ${closureInfo { rootPaths = [ systemToInstall.config.system.build.toplevel ]; }}/registration