-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Describe the bug
The built-in functions builtins.path or builtins.filterSource both accept a root path and a filter function. The filter function is then called with subpaths of the root path as argument. Under certain circumstances, those subpaths are in fact not subpaths of the root path. As far as I could investigate, this happens if
- the
--storeargument is used to point to another store that is not the "canonical" store ("canonical" usually is/nix/store), - the nix file that is evaluate and that contains the call to a built-in function is itself positioned in the "canonical" nix store,
- the root directory points to
./., and - the derivation that contains the nix file is also present in the other nix store.
Note that these circumstances are usually given when you install NixOS from a live iso with nixos-install: Most nix files involved are contained in the nixos channel, which is somewhere in /nix/store. This channel is copied to /mnt/nix/store by nixos-install before anything else is done.
Steps To Reproduce
Put these two files in the same directory, then execute test.sh (this expects Nix to be installed and accessible, but no root privileges):
test.nix
let
root = ./.;
filter = path: type:
let
rootStr = builtins.toString ./.;
in
if builtins.substring 0 (builtins.stringLength rootStr) (builtins.toString path) == rootStr then true
else builtins.throw "root path\n${rootStr}\nnot prefix of path\n${builtins.toString path}";
in
# each one will demonstrate the problem!:
#builtins.path { name="name"; path=root; inherit filter; }
builtins.filterSource filter roottest.sh
#! /usr/bin/env bash
tmpdir=$(mktemp -d)
mkdir $tmpdir/directory
cp test.nix $tmpdir/directory/default.nix
result=$(nix-store --add-fixed --recursive sha256 $tmpdir/directory)
nix-instantiate --eval $result
nix-instantiate --eval $result --store $tmpdir/2nd-store
nix-store --add-fixed --recursive sha256 $tmpdir/directory --store $tmpdir/2nd-store
echo this will fail...
nix-instantiate --eval $result --store $tmpdir/2nd-storeThe final nix-instantiate will trigger the throw from text.nix -- apparently filterSource confuses the store paths:
error: root path
/nix/store/dv15ix385vx19wxac0v5h5n7x8i5iwgp-directory
not prefix of path
/tmp/tmp.f3xsGxSb42/2nd-store/nix/store/dv15ix385vx19wxac0v5h5n7x8i5iwgp-directory/default.nix
Expected behavior
The final nix-instantiate invocation should succeed.
nix-env --version output
nix-env (Nix) 2.18.5
Additional context
Nixpkgs contains many instances of src = lib.fileset.toSouce { root = ./.; fileset = ..something..; } which are liable to trigger this bug if evaluated from within nixos-install; in that case src ends up as empty directory because the filter function from the fileset library constantly returns false. One such instance is documented (with steps to reproduce with nixos-install) in NixOS/nixpkgs#334098 .
Priorities
Add 👍 to issues you find important.