From ed3edf2de5510a9fd864f0c640d6055b2adfe5da Mon Sep 17 00:00:00 2001 From: Robert Hensing <robert@roberthensing.nl> Date: Thu, 24 Oct 2024 13:18:06 +0200 Subject: [PATCH] Add option disallow-copy-paths --- src/libexpr/eval-settings.hh | 9 +++++++++ src/libexpr/eval.cc | 3 +++ tests/functional/disallow-copy-paths.sh | 16 ++++++++++++++++ tests/functional/local.mk | 1 + tests/functional/meson.build | 1 + 5 files changed, 30 insertions(+) create mode 100755 tests/functional/disallow-copy-paths.sh diff --git a/src/libexpr/eval-settings.hh b/src/libexpr/eval-settings.hh index 115e3ee501b..ec6b609f422 100644 --- a/src/libexpr/eval-settings.hh +++ b/src/libexpr/eval-settings.hh @@ -247,6 +247,15 @@ struct EvalSettings : Config This option can be enabled by setting `NIX_ABORT_ON_WARN=1` in the environment. )"}; + + Setting<std::set<std::string>> disallowCopyPaths{this, {}, "disallow-copy-paths", + R"( + A list of paths that are not allowed to be copied. + + This is useful for finding expressions which copy sources, which can slow down evaluation. + You may find copied sources by running `nix` commands with increased verbosity, such as `nix build -vvvv 2>&1 | grep /nix/store`. + After identifying one more more paths, run `nix build --option disallow-copy-paths /nix/store/... --show-trace` to find the expression that copies the path, or add `--debugger`. + )"}; }; /** diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 25354fb1f92..640ca777e04 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2384,6 +2384,9 @@ StorePath EvalState::fetchToStore( PathFilter * filter, RepairFlag repair) { + if (path.accessor == rootFS && settings.disallowCopyPaths.get().contains(path.path.abs())) { + error<EvalError>("not allowed to copy '%1%' due to option '%2%'", path.path.abs(), settings.disallowCopyPaths.name).debugThrow(); + } return ::nix::fetchToStore(*store, path, mode, name, method, filter, repair); } diff --git a/tests/functional/disallow-copy-paths.sh b/tests/functional/disallow-copy-paths.sh new file mode 100755 index 00000000000..4cd1ff827f1 --- /dev/null +++ b/tests/functional/disallow-copy-paths.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +source common.sh + +clearStoreIfPossible + +# shellcheck disable=SC2016 +path="$(nix eval --raw --impure --expr '"${./disallow-copy-paths.sh}"')" + +# shellcheck disable=SC2016 +expectStderr 1 nix-instantiate \ + --disallow-copy-paths "$path" \ + --expr --strict \ + --argstr path "$path" \ + '{ path }: "${/. + path}" + "bla bla"' \ + | grepQuiet "error.*not allowed to copy.*$path.* due to option.*disallow-copy-paths" diff --git a/tests/functional/local.mk b/tests/functional/local.mk index e50b5eaf1df..26c6a5644bf 100644 --- a/tests/functional/local.mk +++ b/tests/functional/local.mk @@ -1,5 +1,6 @@ nix_tests = \ test-infra.sh \ + disallow-copy-paths.sh \ gc.sh \ nix-collect-garbage-d.sh \ remote-store.sh \ diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 54f3e7a0158..8f3a2cae90c 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -69,6 +69,7 @@ suites = [ 'deps': [], 'tests': [ 'test-infra.sh', + 'disallow-copy-paths.sh', 'gc.sh', 'nix-collect-garbage-d.sh', 'remote-store.sh',