aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-09-23 23:30:29 +0200
committerNaïm Favier <n@monade.li>2023-01-03 17:19:16 +0100
commit15f7fa59bec1dbb4fa94bc1c2f9018b1f14f0d65 (patch)
tree16772ce4d4c9a8c9f0f4c0d55c39ce4f75065e47
parent15341334b50b2b432830a8e78abc331d0a47de13 (diff)
`unsafeDiscardReferences`
Adds a new boolean structured attribute `outputChecks.<output>.unsafeDiscardReferences` which disables scanning an output for runtime references. __structuredAttrs = true; outputChecks.out.unsafeDiscardReferences = true; This is useful when creating filesystem images containing their own embedded Nix store: they are self-contained blobs of data with no runtime dependencies. Setting this attribute requires the experimental feature `discard-references` to be enabled.
-rw-r--r--doc/manual/src/language/advanced-attributes.md6
-rw-r--r--doc/manual/src/release-notes/rl-next.md12
-rw-r--r--src/libstore/build/local-derivation-goal.cc27
-rw-r--r--src/libutil/experimental-features.cc1
-rw-r--r--src/libutil/experimental-features.hh1
-rw-r--r--tests/check-refs.nix9
-rw-r--r--tests/check-refs.sh9
7 files changed, 58 insertions, 7 deletions
diff --git a/doc/manual/src/language/advanced-attributes.md b/doc/manual/src/language/advanced-attributes.md
index 2e7e80ed0..f02425b13 100644
--- a/doc/manual/src/language/advanced-attributes.md
+++ b/doc/manual/src/language/advanced-attributes.md
@@ -207,13 +207,13 @@ Derivations can declare some infrequently used optional attributes.
the hash in either hexadecimal or base-32 notation. (See the
[`nix-hash` command](../command-ref/nix-hash.md) for information
about converting to and from base-32 notation.)
-
+
- [`__contentAddressed`]{#adv-attr-__contentAddressed}
If this **experimental** attribute is set to true, then the derivation
outputs will be stored in a content-addressed location rather than the
traditional input-addressed one.
- This only has an effect if the `ca-derivation` experimental feature is enabled.
-
+ This only has an effect if the `ca-derivations` experimental feature is enabled.
+
Setting this attribute also requires setting `outputHashMode` and `outputHashAlgo` like for *fixed-output derivations* (see above).
- [`passAsFile`]{#adv-attr-passAsFile}\
diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md
index 9f491efc8..51320d50a 100644
--- a/doc/manual/src/release-notes/rl-next.md
+++ b/doc/manual/src/release-notes/rl-next.md
@@ -21,3 +21,15 @@
* Error traces have been reworked to provide detailed explanations and more
accurate error locations. A short excerpt of the trace is now shown by
default when an error occurs.
+
+* In derivations that use structured attributes, you can now use `unsafeDiscardReferences`
+ to disable scanning a given output for runtime dependencies:
+ ```nix
+ __structuredAttrs = true;
+ outputChecks.out.unsafeDiscardReferences = true;
+ ```
+ This is useful e.g. when generating self-contained filesystem images with
+ their own embedded Nix store: hashes found inside such an image refer
+ to the embedded store and not to the host's Nix store.
+
+ This requires the `discard-references` experimental feature.
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 9d869d513..65340d6ce 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -2319,11 +2319,30 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt,
inodesSeen);
- debug("scanning for references for output '%s' in temp location '%s'", outputName, actualPath);
+ bool discardReferences = false;
+ if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
+ if (auto outputChecks = get(*structuredAttrs, "outputChecks")) {
+ if (auto output = get(*outputChecks, outputName)) {
+ if (auto unsafeDiscardReferences = get(*output, "unsafeDiscardReferences")) {
+ settings.requireExperimentalFeature(Xp::DiscardReferences);
+ if (!unsafeDiscardReferences->is_boolean())
+ throw Error("attribute 'outputChecks.\"%s\".unsafeDiscardReferences' of derivation '%s' must be a Boolean", outputName, drvPath.to_string());
+ discardReferences = unsafeDiscardReferences->get<bool>();
+ }
+ }
+ }
+ }
- /* Pass blank Sink as we are not ready to hash data at this stage. */
- NullSink blank;
- auto references = scanForReferences(blank, actualPath, referenceablePaths);
+ StorePathSet references;
+ if (discardReferences)
+ debug("discarding references of output '%s'", outputName);
+ else {
+ debug("scanning for references for output '%s' in temp location '%s'", outputName, actualPath);
+
+ /* Pass blank Sink as we are not ready to hash data at this stage. */
+ NullSink blank;
+ references = scanForReferences(blank, actualPath, referenceablePaths);
+ }
outputReferencesIfUnregistered.insert_or_assign(
outputName,
diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc
index e0902971e..58d762ebb 100644
--- a/src/libutil/experimental-features.cc
+++ b/src/libutil/experimental-features.cc
@@ -16,6 +16,7 @@ std::map<ExperimentalFeature, std::string> stringifiedXpFeatures = {
{ Xp::ReplFlake, "repl-flake" },
{ Xp::AutoAllocateUids, "auto-allocate-uids" },
{ Xp::Cgroups, "cgroups" },
+ { Xp::DiscardReferences, "discard-references" },
};
const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name)
diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh
index af775feb0..ac372e03e 100644
--- a/src/libutil/experimental-features.hh
+++ b/src/libutil/experimental-features.hh
@@ -25,6 +25,7 @@ enum struct ExperimentalFeature
ReplFlake,
AutoAllocateUids,
Cgroups,
+ DiscardReferences,
};
/**
diff --git a/tests/check-refs.nix b/tests/check-refs.nix
index 9d90b0920..a5e40c9e5 100644
--- a/tests/check-refs.nix
+++ b/tests/check-refs.nix
@@ -67,4 +67,13 @@ rec {
disallowedReferences = [test5];
};
+ test11 = makeTest 11 {
+ __structuredAttrs = true;
+ outputChecks.out = {
+ unsafeDiscardReferences = true;
+ allowedReferences = [];
+ };
+ buildCommand = ''echo ${dep} > "''${outputs[out]}"'';
+ };
+
}
diff --git a/tests/check-refs.sh b/tests/check-refs.sh
index 16bbabc40..65a72552a 100644
--- a/tests/check-refs.sh
+++ b/tests/check-refs.sh
@@ -40,3 +40,12 @@ nix-build -o $RESULT check-refs.nix -A test7
# test10 should succeed (no disallowed references).
nix-build -o $RESULT check-refs.nix -A test10
+
+if isDaemonNewer 2.12pre20230103; then
+ enableFeatures discard-references
+ restartDaemon
+
+ # test11 should succeed.
+ test11=$(nix-build -o $RESULT check-refs.nix -A test11)
+ [[ -z $(nix-store -q --references "$test11") ]]
+fi