Example:
test.nix:
let
inherit (import <nixpkgs> {}) runCommand;
drv = runCommand "test" {} ''
echo "{}" > $out
'';
in import "${drv}"
Now, turn off network and run:
$ nix-instantiate -v test.nix
[…]
evaluating file '/nix/store/dyilzxs9z1kbrbmwjkl9869s440sq81v-nixos-18.03/nixos/pkgs/stdenv/common-path.nix'
querying info about '/nix/store/bzq000c18inh7bsnzmwrv8pzvfa11j4f-offline-ifd-test' on 'https://cache.nixos.org'...
downloading 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo'...
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
warning: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve hosts
error: unable to download 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo': Couldn't resolve host n)
Re-run with network connectivity:
$ nix-instantiate -v test.nix
[…]
evaluating file '/nix/store/dyilzxs9z1kbrbmwjkl9869s440sq81v-nixos-18.03/nixos/pkgs/stdenv/common-path.nix'
querying info about '/nix/store/bzq000c18inh7bsnzmwrv8pzvfa11j4f-offline-ifd-test' on 'https://cache.nixos.org'...
downloading 'https://cache.nixos.org/bzq000c18inh7bsnzmwrv8pzvfa11j4f.narinfo'...
building '/nix/store/8a5gmhd3pjyg5k5fwc4mwvj70a9z1aar-offline-ifd-test.drv'...
linking '/nix/store/bzq000c18inh7bsnzmwrv8pzvfa11j4f-offline-ifd-test' to '/nix/store/.links/1xyw8jzhbh0aiivnm376ld01'
evaluating file '/nix/store/bzq000c18inh7bsnzmwrv8pzvfa11j4f-offline-ifd-test'
/cc @vcunat @shlevy @domenkozar
This also breaks offline nixpkgs.dhallToNix, even if nixpkgs.dhall-nix is in local store, and it’s how I encountered this. /cc @Gabriel439
So even if the derivation can be built locally, and I’m somewhere wild without range, I’m doomed. Seems… wrong.
Have you tried to pass the option
--option 'binary-caches' ''
?
Should work with it without network access.
@michalrus: Perhaps this would work:
runCommand "test" { preferLocalBuild = true; } ...
What I believe is happening here is that in the absence of preferLocalBuild = true Nix has an obligation to check all available substituters (i.e. caches that you have registered such as cache.nixos.org) to see if this derivation may have already been built before. Adding preferLocalBuild = true tells Nix to not bother to check caches. In fact, if you browse the trivial builders here:
https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/trivial-builders.nix
... you will find many builders derived from runCommand that set preferLocalBuild, too, typically for derivations where it is cheaper to rebuild it locally than to fetch it from a cache.
@Gabriel439 very close. You actually need to set allowSubstitutes = false; while preferLocalBuild will substitute if one exists, but prevent distributed builds to happen. See https://github.com/NixOS/nix/commit/1109193ea3a25208d438c65b2d79e207ae1af039
Using trivial derivations you need to set both to true.
Ohhhhhhhhh. Very cool! Thank you, both! :sparkles:
@Gabriel439 so perhaps this dhallToNix expression should use allowSubstitutes = false;?
Glad that resolves your question :)
@michalrus: Yeah, dhallToNix should probably set both preferLocalBuild = true; and allowSubstitutes = false;
E.g. like
{
dhallToNix = code:
let
drv = runCommand "dhall-compiled.nix" {
inherit code;
passAsFile = [ "code" ];
preferLocalBuild = true;
allowSubstitutes = false;
buildInputs = [ dhall-nix ];
} ''
dhall-to-nix <<< $codePath > $out
'';
in
import drv.outPath;
}
A derivation can be marked as trivial and unnecessary to substitute by adding allowSubstitutes = false; to the attributes. That will disable substitutes for that specific derivation without having to disable it on the cli.
EDIT: looks like I had an old tab open 😄
@michalrus: Yeah, that looks correct to me
If these options were designed anew, I'd suggest that preferLocalBuild = true by default implies allowSubstitutes = false (possibly naming these differently). If a build feels simple enough not to delegate to another machine, it's _probably_ not worth substituting either.
EDIT: let me provide an example where it _is_ worth it: when a "build" is trivial to compute from inputs, but build-time closure is significantly larger than run-time closure. There the substitution may help noticeably, depending on current nix store contents.
Now it would be an incompatible change at nix level, so it's probably not worth it. Introducing a new name implying both also doesn't seem worth it at this point.
Most helpful comment
@Gabriel439 very close. You actually need to set
allowSubstitutes = false;whilepreferLocalBuildwill substitute if one exists, but prevent distributed builds to happen. See https://github.com/NixOS/nix/commit/1109193ea3a25208d438c65b2d79e207ae1af039Using trivial derivations you need to set both to true.