Merge pull request #7087 from ncfavier/referenceablePaths

Self-contained outputs
This commit is contained in:
Théophane Hufschmitt 2023-01-30 11:06:54 +01:00 committed by GitHub
commit de1b593233
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 7 deletions

View file

@ -212,7 +212,7 @@ Derivations can declare some infrequently used optional attributes.
If this **experimental** attribute is set to true, then the derivation If this **experimental** attribute is set to true, then the derivation
outputs will be stored in a content-addressed location rather than the outputs will be stored in a content-addressed location rather than the
traditional input-addressed one. 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). Setting this attribute also requires setting `outputHashMode` and `outputHashAlgo` like for *fixed-output derivations* (see above).

View file

@ -8,3 +8,15 @@
discovered by making multiple syscalls. This change makes these operations discovered by making multiple syscalls. This change makes these operations
lazy such that these lookups will only be performed if the attribute is used. lazy such that these lookups will only be performed if the attribute is used.
This optimization affects a minority of filesystems and operating systems. This optimization affects a minority of filesystems and operating systems.
* In derivations that use structured attributes, you can now use `unsafeDiscardReferences`
to disable scanning a given output for runtime dependencies:
```nix
__structuredAttrs = true;
unsafeDiscardReferences.out = 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.

View file

@ -2323,11 +2323,28 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt, buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt,
inodesSeen); inodesSeen);
bool discardReferences = false;
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
if (auto udr = get(*structuredAttrs, "unsafeDiscardReferences")) {
settings.requireExperimentalFeature(Xp::DiscardReferences);
if (auto output = get(*udr, outputName)) {
if (!output->is_boolean())
throw Error("attribute 'unsafeDiscardReferences.\"%s\"' of derivation '%s' must be a Boolean", outputName, drvPath.to_string());
discardReferences = output->get<bool>();
}
}
}
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); 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. */ /* Pass blank Sink as we are not ready to hash data at this stage. */
NullSink blank; NullSink blank;
auto references = scanForReferences(blank, actualPath, referenceablePaths); references = scanForReferences(blank, actualPath, referenceablePaths);
}
outputReferencesIfUnregistered.insert_or_assign( outputReferencesIfUnregistered.insert_or_assign(
outputName, outputName,

View file

@ -16,6 +16,7 @@ std::map<ExperimentalFeature, std::string> stringifiedXpFeatures = {
{ Xp::ReplFlake, "repl-flake" }, { Xp::ReplFlake, "repl-flake" },
{ Xp::AutoAllocateUids, "auto-allocate-uids" }, { Xp::AutoAllocateUids, "auto-allocate-uids" },
{ Xp::Cgroups, "cgroups" }, { Xp::Cgroups, "cgroups" },
{ Xp::DiscardReferences, "discard-references" },
}; };
const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name) const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name)

View file

@ -25,6 +25,7 @@ enum struct ExperimentalFeature
ReplFlake, ReplFlake,
AutoAllocateUids, AutoAllocateUids,
Cgroups, Cgroups,
DiscardReferences,
}; };
/** /**

View file

@ -67,4 +67,11 @@ rec {
disallowedReferences = [test5]; disallowedReferences = [test5];
}; };
test11 = makeTest 11 {
__structuredAttrs = true;
unsafeDiscardReferences.out = true;
outputChecks.out.allowedReferences = [];
buildCommand = ''echo ${dep} > "''${outputs[out]}"'';
};
} }

View file

@ -40,3 +40,12 @@ nix-build -o $RESULT check-refs.nix -A test7
# test10 should succeed (no disallowed references). # test10 should succeed (no disallowed references).
nix-build -o $RESULT check-refs.nix -A test10 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