This is pretty bananas... performing nix-shell on a derivation is causing its outpaths to be opened for writing, even though they were already built. The result of this is that the output paths can become corrupted by nix-shell operations, especially accidental ones. All you have to do is forget to change $out
to a new value before starting to call the stdenv build phases.
This is on NixOS with nix.readOnlyStore
set to true
.
Example:
[~]$ nix-build -E 'with import <nixpkgs> {}; runCommand "test" {} "mkdir $out"'
these derivations will be built:
/nix/store/q7wf6j0rczhsf0grcjag1zakji6nzavj-test.drv
building '/nix/store/q7wf6j0rczhsf0grcjag1zakji6nzavj-test.drv'...
/nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test
[~]$ touch /nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test/hello
touch: cannot touch '/nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test/hello': Read-only file system
[~]$ nix-shell /nix/store/q7wf6j0rczhsf0grcjag1zakji6nzavj-test.drv --run "touch \$out/hi"
[~]$ ls /nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test
hi
[~]$ nix-store --verify-path /nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test
path '/nix/store/yjxdn3nrwrrdgfczm8yhdhy2k7ggljwm-test' was modified! expected hash 'sha256:0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5', got 'sha256:0vg8b2f69719gy31y4xzc96n19fd7zrhqszfgiys3khiwvd9zjpn'
Hm, I guess nix-shell
should save the mount namespace of the parent and re-enter it before executing the shell.
Reverted in 01d07b1e92c298f729a73705907b2987da9a4d0c, maybe open it again
I'm getting corrupted store pretty regularly because of this issue. This happens in particular when running Python applications inside nix-shell. I guess that during import of Python packages they get recompiled automatically and stored back into repository, corrupting it in the process.
Most helpful comment
Reverted in 01d07b1e92c298f729a73705907b2987da9a4d0c, maybe open it again