-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Path coercion in Flakes causes files to be added to the store twice #9428
Comments
I suspect that it would be solved by #6530 when/if it lands (though that doesn't prevent it from being a bug). A possible workaround is to use |
had some random ideas... this happens often and is a common confusion due to the simple syntax and non-intuitive outcome. Note: most of these will change evaluation values for historical expressions, not backwards compatible.
Context that others may be interested in:
|
While undesirable, this is not a bug, not something we can fix in a backward compatible way, and not flake-specific. |
Importing a local directory (that's not already in the store) twice when using And the point of merging features as experimental is that it allows experimentation without having to worry about backwards compatibility. Sure there's a lot of people using this now, but we can still deprecate current experimental features within years rather than never. In particular, pure evaluation could be implemented in a way that doesn't need to import everything into the store first, which would fix this. |
So I guess it's not exclusively flake-specific, but flakes does cause this to trigger when you wouldn't expect it. But yes, this can also be fixed without involving flakes, fair enough. |
I am working on hacks to work around this in nixpkgs, since it is required for NixOS/nixpkgs#254405 Related to the hacks I am doing, as a fallback: #5868 |
…xt for self This is an extremely subtle feature which is necessary to be able to incur dependencies on this nixpkgs's source code without copying it twice (NixOS/nix#9428, NixOS/nix#5868). pkgs.path is not sufficient, because actually using it incurs a copy, which winds up looking like /nix/store/HASH-HASH-source in flakes. Similarly, `toString pkgs.path` is not sufficient because that does not have any string context, so it will not incur a dependency if it's used. It's exceptionally subtle. There are four cases: - non flakes, pure mode: can't do anything about this, we must copy to the store. - non flakes, not already in the store: can't do anything about this, we are copying to the store. - non flakes, already in the store: storePath gives us a string with context for free. - flakes: overlay makes it a stringification of self.outPath. In all cases, this is a string with appropriate context to transfer this nixpkgs to another system.
Edit: This isn't right! Please disregard this message, I'll investigate more.. Found it, very cursed, but unrelated to this issue: NixOS/nix.dev#830 (comment) I just discovered that this is the reason derivations differ between native Flake and flake-compat builds before Nix 2.16, and the reason they don't differ afterwards Observe:
This isn't a problem with 2.16 because of #8096, which started using And because This is why in NixOS/nix.dev#830 (comment) we discovered that 2.13 doesn't get substituted, when 2.18 and 2.19 do. Of course, not doing the double store import on the Flakes side will again cause the Flake builds to not line up with the flake-compat builds, unless flake-compat is adjusted as well, e.g. by using |
Copying to the store when interpolating a path value is normal. What's not required is copying sources to the store before evaluating. This was done as an implementation detail of flakes to enable caching, but it is too crude a solution. Lazy trees (#6530) solves the problem a the cost of correctness (specifically determinism, certainly in its current form). An alternate solution is lazy paths (#10252), which is a partial implementation of lazy trees; the part that does not compromise correctness. It only extends path values to include virtual trees (just like lazy trees does), without implementing the virtual path strings that are causing the problems in lazy-trees. This isn't completely airtight, although that's ok because users can opt out by choosing to copy to the store. Note that we can bring the same functionality to non-flakes users in the form of a |
fyi the filterSource API is very very bad. for example, it can't see targets of symlinks, among other things. See https://wiki.lix.systems/link/13, under "fix fs builtins". I don't think we should actually introduce anything new that looks like filterSource, because filterSource is bad. |
Another issue with
The latter two are not strictly necessary because of |
We could force the formals of the lambda to accept new fields by having ellipsis. wiggles did this to the repl overlays feature in lix to force not painting ourselves into a corner by accepting user code that can't take us extending the interface. I'm still not fully convinced by the idea of returning just a boolean either. We may want the ability to actually transform directory trees slightly in such a builtin, e.g. rewriting targets or perhaps injecting a little text file (but not dumping the whole everything in general). This is somewhat bike shedding but I do want to be careful about introducing new builtins that don't contain api design flaws that paint us into any existing corner we know about, especially if they need to get into multiple implementations to be actually used. |
Yes, exploring the design space is important to me too, and I think it's unfortunate whenever that's perceived as bikeshedding.
That's a great suggestion, if perhaps a bit humble; we could have some sort of Maybe we do want to have a specialized filtering function as a builtin nonetheless, but probably the best way to find out what its interface should be is to first build it on top of
Silvan did the same for |
Yeah, @lf- please check out the |
* nix: drop flake-utils * nix: drop rust-overlay * nix: don't re-instantiate nixpkgs Previously, applying the overlay to our instance of nixpkgs added about ~100mb of memory to each evaluation, along with a few extra seconds to evaluate (https://zimbatm.com/notes/1000-instances-of-nixpkgs) * nix: use nix-filter to filter source Avoids NixOS/nix#9428 (path coercion like `"${./.}"` causes files to be added to the store twice)
I mean flakes are still not stabilized no? So it def something that can be done considering their no stabilization guarantees. |
Describe the bug
When coercing paths to strings (which adds said paths into the Nix store) in Flakes, all files are added to the store twice, leading to doubled space usage.
I understand the underlying mechanism and why this happens, but this sounds like a bug to me.
Steps To Reproduce
Create this
flake.nix
:Then run:
Notice how the
flake.nix
file was copied to two store paths.Expected behavior
Only a single store path is used.
nix-env --version
outputnix-env (Nix) 2.18.1
Additional context
This issue is sponsored by Antithesis ✨
Priorities
Add 👍 to issues you find important.
The text was updated successfully, but these errors were encountered: