Conversation
| struct MountedSourceAccessor : SourceAccessor | ||
| { | ||
| virtual void mount(CanonPath mountPoint, ref<SourceAccessor> accessor) = 0; | ||
|
|
||
| /** | ||
| * Return the accessor mounted on `mountPoint`, or `nullptr` if | ||
| * there is no such mount point. | ||
| */ | ||
| virtual std::shared_ptr<SourceAccessor> getMount(CanonPath mountPoint) = 0; |
There was a problem hiding this comment.
This is great. Like this exactly what's needed for in-memory dummy store.
There was a problem hiding this comment.
We'll need to use this with care. E.g. the path ${m}/foo != getMount m foo, so if both are observable in the language, that would be a problem. (And they are substantially different in terms of root and path components)
There was a problem hiding this comment.
This shouldn't be a problem here since we don't have lazy trees yet. I.e. identical inputs are deterministically mounted on the same store paths.
|
|
||
| if (originalInput.getNarHash() && narHash != *originalInput.getNarHash()) | ||
| throw Error( | ||
| (unsigned int) 102, |
There was a problem hiding this comment.
Isn't there an enum for this?
There was a problem hiding this comment.
Don't think so... There is Worker::failingExitStatus() which should probably be factored out.
There was a problem hiding this comment.
I was meaning to clean that up and unify with BuildResult statuses at some point, fwiw.
| { | ||
| auto storePath = fetchToStore(fetchSettings, *store, accessor, FetchMode::Copy, input.getName()); | ||
|
|
||
| allowPath(storePath); // FIXME: should just whitelist the entire virtual store |
There was a problem hiding this comment.
I would like this part done sooner rather than later
|
I took the "easy parts" of this and did some other cleanups and put in #14080. |
src/libexpr/eval.cc
Outdated
| auto realStoreDir = dirOf(store->toRealPath(StorePath::dummy)); | ||
| if (settings.pureEval || store->storeDir != realStoreDir) { | ||
| accessor = settings.pureEval ? storeFS : makeUnionSourceAccessor({accessor, storeFS}); | ||
| } | ||
| accessor = settings.pureEval ? storeFS.cast<SourceAccessor>() : makeUnionSourceAccessor({accessor, storeFS}); |
There was a problem hiding this comment.
I don't think this is quite right --- evidently we need better unit tests to catch this.
#14080 removes redundant branches while keeping the store->storeDir != realStoreDir fix.
There was a problem hiding this comment.
No, this change is necessary. Otherwise, if pureEval isn't enabled, rootFS ends up not containing storeFS, so the mounts on storeFS won't be visible in rootFS.
|
@Ericson2314 now this one needs a rebase? |
With FilteringSourceAccessor, lstat() needs to throw a different exception if the path is inaccessible than if it doesn't exist.
This returns the fingerprint for a specific subpath. This is intended for "composite" accessors like MountedSourceAccessor, where different subdirectories can have different fingerprints.
|
I'll rebase it |
fetchToStore() caching was broken because it uses the fingerprint of the accessor, but now that the accessor (typically storeFS) is a composite (like MountedSourceAccessor or AllowListSourceAccessor), there was no fingerprint anymore. So fetchToStore now uses the new getFingerprint() method to get the specific fingerprint for the subpath.
This is to test the non-functional property that most paths should be cacheable. We've had frequent cases where caching broken but we didn't notice.
7618094 to
4b9735b
Compare
|
|
||
| // Backward compatibility hack: throw an exception if access | ||
| // to this path is not allowed. | ||
| if (auto accessor = res.accessor.dynamic_pointer_cast<FilteringSourceAccessor>()) | ||
| accessor->checkAccess(res.path); |
There was a problem hiding this comment.
This stuff has been on lazy trees for a while I know, but I guess a this point I am skeptical it is still needed? Especially with #14081
There was a problem hiding this comment.
No, they're still needed.
|
So my current plan (as of yesterday) is that after @xokdvium fixes some bugs, I think #14081 will pass tests, and then I hope we can do that, and then I think we will be better prepared to review this. I want avoid a mixture of mounting and filtering in the pure eval case because I think that is hard to reason about. |
Let's please not block pretty important bug fixes on nice-to-have refactorings. Currently the |
|
This seems to have regressed: |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
|
This seems to cause $ nix edit nixpkgs#hello
error: cannot open '«github:NixOS/nixpkgs/af84f9d270d404c17699522fab95bbf928a2d92f»/pkgs/by-name/he/hello/package.nix' in an editor because it has no physical path
Additional information: I have a user registry pin (this is probably unrelated to the issue?) $ nix registry list | grep nixpkgs
user flake:nixpkgs github:NixOS/nixpkgs/af84f9d270d404c17699522fab95bbf928a2d92f
global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable |
Yeah that in the current form won't work well with anything "lazy tree" shaped. The file really doesn't have a location on disk and the file lives the git packfiles (although it is copied to the store still). I guess what we can do is when the file doesn't have a physical location we copy the contents into a temporary and open that. |
|
For some input schemes like |
|
Another regression from this: #14961 (though it was already broken with a relocated store when |
Motivation
fetchToStore()caching is broken because it uses the fingerprint of the accessor, but now that the accessor (typicallystoreFS) is a composite (likeMountedSourceAccessororAllowListSourceAccessor), there is no fingerprint anymore.So
fetchToStore()now uses the newgetFingerprint()method to get the specific fingerprint for the subpath. We now also mount inputs on top ofstoreFSto make their fingerprints visible tofetchToStore().To prevent future regressions like this, this PR also adds tests to make sure that most paths are cacheable.
Context
Mostly cherry-picked from DetSys Nix and #13225.
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.