Skip to content

Get rid of deep realisations entirely#15289

Merged
Ericson2314 merged 2 commits intoNixOS:masterfrom
obsidiansystems:fix-11896
Mar 23, 2026
Merged

Get rid of deep realisations entirely#15289
Ericson2314 merged 2 commits intoNixOS:masterfrom
obsidiansystems:fix-11896

Conversation

@Ericson2314
Copy link
Copy Markdown
Member

Motivation

Fix #11896

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions bot added documentation new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority store Issues and pull requests concerning the Nix store repl The Read Eval Print Loop, "nix repl" command and debugger labels Feb 18, 2026
@Ericson2314 Ericson2314 force-pushed the fix-11896 branch 5 times, most recently from 9c3eabb to b7a9a14 Compare February 19, 2026 15:56
@Ericson2314 Ericson2314 force-pushed the fix-11896 branch 3 times, most recently from 719c8e9 to 99353ea Compare March 3, 2026 07:38
@amaanq amaanq force-pushed the fix-11896 branch 8 times, most recently from e69a5a0 to 134f1b4 Compare March 4, 2026 05:32
* Callback type for querying realisations. The callback should return
* the realisation for the given DrvOutput, or nullptr if not found.
*/
using QueryRealisationFun = std::function<std::shared_ptr<const UnkeyedRealisation>(const DrvOutput &)>;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be fun<> now?
Makes your reference to nullptr trivially unambiguous :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes this is something to improve post the recent rebase :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean std::optional<fun<....>>?

Comment on lines +16 to +18
/**
* For internal use only.
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're teasing me!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* For internal use only.
*/
/**
* For internal use only. Just here to be shared in the implementation of `Store::queryPartialDerivationOutputMap` and `deepQueryPartialDerivationOutputMap`.
*/


static bool tryResolveInput(
Store & store,
const StoreDirConfig & store,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a storedir, nice.

Copy link
Copy Markdown
Member

@roberth roberth Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love to see progress on CA. Would be great to add a release note!

@github-actions github-actions bot added the c api Nix as a C library with a stable interface label Mar 11, 2026
@Ericson2314 Ericson2314 force-pushed the fix-11896 branch 2 times, most recently from 9971ea9 to 30a9106 Compare March 16, 2026 16:45
Comment on lines 1572 to 1575
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing this? What if one enables and then disables CA drvs?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check was moved to Store::queryRealisation, so it affects all implementations / no implementation can forget to check.

Copy link
Copy Markdown
Member Author

@Ericson2314 Ericson2314 Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was done in its own commit btw, it might be easier to read that way.

Copy link
Copy Markdown
Member

@lovesegfault lovesegfault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one thing not in the diff — nix-build.cc:593 still uses store->queryPartialDerivationOutputMap(inputDrv). line 537 got migrated to deepQuery* but this one didn't. if inputDrv is a CA drv that needs resolution, i think *o at 596 could throw now that deep realisations are gone? pretty niche (nix-shell + __structuredAttrs + CA input) so maybe fine to punt.

not blocking — overall this looks good, happy to see deep realisations go

src/nix/copy.cc Outdated
}

copyPaths(*srcStore, *dstStore, stuffToCopy, NoRepair, checkSigs, substitute);
copyClosure(*srcStore, *dstStore, stuffToCopy, NoRepair, checkSigs, substitute);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, maybe I did this because I needed to compute the shallow realisation build closure to send it over.

If so, that should be factored out. And longer term, we should stop implicitly copying realisations anyways.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the --no-recursive option ignored.

Comment on lines +39 to +41
# copyClosure copies unsigned input-addressed closure deps into the
# binary cache, so mark the substituter as trusted to skip the
# signature check in substitution-goal.cc.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually want this?

We don't want to only have build traces for objects we have in the
store, anymore.
@amaanq amaanq force-pushed the fix-11896 branch 4 times, most recently from ece4def to 8ab8977 Compare March 19, 2026 22:37
@domenkozar
Copy link
Copy Markdown
Member

pretty niche (nix-shell + __structuredAttrs + CA input) so maybe fine to punt.

not that niche in my experience

Comment on lines -212 to -223
if (!drv->type().isImpure()) {
Realisation newRealisation{
realisation,
{
.drvPath = drvPath,
.outputName = wantedOutput,
}};
newRealisation.signatures.clear();
worker.store.signRealisation(newRealisation);
worker.store.registerDrvOutput(newRealisation);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this removed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this is the spot where it created deep realizations before.

clearStore
# Check nothing gets built.
buildAttr "$derivationPath" 1 --option substituters "file://$cacheDir" --no-require-sigs |& grepQuietInverse " will be built:"
buildAttr "$derivationPath" 1 --option substituters "file://$cacheDir?trusted=1" --no-require-sigs -j0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed. Some weird existing problem that made ?trusted=1 needed, but it is just helping along with the existing --no-require-sigs flag. Not adding fundamentally new untrustedness.

Comment on lines +980 to +989
std::visit(
overloaded{
[&](const Realisation & realisation) {
experimentalFeatureSettings.require(Xp::CaDerivations);
realisations.push_back(&realisation);
storePaths.insert(realisation.outPath);
},
[&](const OpaquePath & op) { storePaths.insert(op.path); },
},
path.raw);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the effect of this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer copy over out paths implicitly. If the thing wants to copy a realisation, we just copy that.

This morally goes with removing the foreign keys in the previous commit. It is necessary for copying a (shallow) realisation closure without also making it necessary to keep the build closure around.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually I think we will get rid of RealisedPath::Set because it is just better to manage the build trace explicitly and separately.

@Ericson2314 Ericson2314 added this pull request to the merge queue Mar 23, 2026
Merged via the queue into NixOS:master with commit e6ac69f Mar 23, 2026
16 checks passed
@Ericson2314 Ericson2314 deleted the fix-11896 branch March 23, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c api Nix as a C library with a stable interface documentation new-cli Relating to the "nix" command repl The Read Eval Print Loop, "nix repl" command and debugger store Issues and pull requests concerning the Nix store with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deep realisations should not be shared between stores

5 participants