Reproducibility checking with new CLI and fixed output derivations

Checking whether a particular derivation is reproducible is helpful because we can head off problems with builds working on one machine but not another.

On https://r13y.com/ there is a procedure for verifying the reproducibility of a derivation:

$ nix-build . -A hello
$ nix-build . -A hello --check --keep-failed
[...snip...]
error: derivation '/nix/store/...hello.drv' may not be deterministic:
output '/nix/store/...-hello' differs from '/nix/store/...hello.check'
$ diffoscope /nix/store/...hello /nix/store/...hello.check

This works.

New CLI

We can also update this for the new cli:

$ nix build --file default.nix
$ nix build --file default.nix --rebuild --keep-failed
note: keeping build directory '/tmp/nix-build-repro.drv-2'
error: derivation '/nix/store/xh668ji9s80hym2jvw0p8q1iq969n82k-repro.drv' may not be deterministic: output '/nix/store/8r3yardsjsdrjhl84j5k8a78955ad59i-repro' differs from '/nix/store/8r3yardsjsdrjhl84j5k8a78955ad59i-repro.check'
$ diffoscope /nix/store/...repro /nix/store/...repro.check

Fixed Output Derivations

Now say we have a fixed output derivation and we want to assess the reproducibility of it. For example:

{pkgs ? import <nixpkgs> {} }:
derivation {
  name = "repro";
  system = "x86_64-linux";
  builder = "${pkgs.bash}/bin/bash"; args = [ ./build.sh ];
  outputHashMode = "recursive";
  outputHashAlgo = "sha256";
  outputHash = "";
}

and build.sh:

declare -xp
echo $RANDOM > $out

What series of actions should you take so that you can diffoscope two outputs of the fixed output derivation?

$ nix build --file default.nix
warning: found empty hash, assuming 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
error: hash mismatch in fixed-output derivation '/nix/store/p54hsja603qsywsvbv3xf9jhpn0dg0ar-repro.drv':
         specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
            got:    sha256-ioysUt3TKJzSBp143eRBzSwTp7dwi+FdQRDTyjEaOrk=

$ # Copy got: hash into derivation

$ nix build --file default.nix && readlink result

$ # Save result path for future diffoscope command 
$ # Change outputHash back to and empty string

$ nix build --file default.nix
warning: found empty hash, assuming 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
error: hash mismatch in fixed-output derivation '/nix/store/p54hsja603qsywsvbv3xf9jhpn0dg0ar-repro.drv':
         specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
            got:    sha256-lWb1HhrSY8cAnPsRIgm1N52mvfF9vGWPNa0kTLc47CA=

$ # Copy got: hash into derivation

$ nix build --file default.nix && readlink result

$ # Save result path for future diffoscope command

$ diffoscope path1 path2
6 Likes

That’s a great explanation, thanks!

I added some of this information to our newly-created Reproducible Builds site at https://reproducible.nixos.org/

1 Like