Readit News logoReadit News
edolstra · 2 months ago
The deriver field in Nix has always been a misfeature. It was intended to provide traceability back to the Nix expression used to create the derivation, but it doesn't actually do that (since that wasn't really possible in the pre-flakes world, without hermetic evaluation). So instead it just causes a lot of confusion when the deriver recorded in the binary cache doesn't match the local evaluation result, due to fixed-output derivations changing.

In the future, Nix will hopefully gain proper provenance tracking that will tell you exactly where a store path came from: https://github.com/NixOS/nix/pull/11749

Ericson2314 · 2 months ago
The biggest problem of all is that derivers are not unique! A separate "build trace" map will solve this.
tomberek · 2 months ago
Presumably this would support a big improvement to both SBOM generation as well as various UX features and workflow improvements.
setheron · 2 months ago
is that the 'build-trace' feature I saw John write about ? (I want to explore that more)
Ericson2314 · 2 months ago
I think Eelco has in mind a separate thing that would still be a store object field. But IMO we should not do that since derives are unique, and we should instead use the "build trace" instead, which properly handles that.

As Martin Schwaighofer has discussed, it is fine and in fact good for build traces entries to have arbitrary meta data, so the "claims" being cryptographically signed are more precise. (This is good for auditing, and if something looks suspicious, having full accountability.)

So on that grounds, if eelco would like to include some "this came from this flake" information as informal metadata. (formally the key must still the resolved derivation.) That is fine with me.

---

As I linked in my other reply, see my fast-growing https://github.com/NixOS/nix/pull/14408 docs PR where I try to formally nail all this stuff down for the first time.

ronef · 2 months ago
+1 to Farid, great write-up! What you’re seeing is the long-standing “deriver” mismatch: fixed-output derivations can change their .drv without changing the output path. Eelco is calling it out as well in the comment below. I believe the idea behind the path forward is there but happy to hear more!

Also. Check out Farid's other posts.

amelius · 2 months ago
> The road to Nix enlightenment is no joke and full of dragons.

Nix was a great research project. Now is the time to rewrite it from the ground up.

Ericson2314 · 2 months ago
The core store layer is quite small, and I am trying to thoroughly document it, with all 3 of:

- a more "academic" spec of what it does

- nuts-and-bolts JSON schema for many data types

- JSON golden tests instead of C++ literals in the unit tests as often as possible.

I hope this will make additional store layer easy to churn out.

(The "hash derivation modulo" that is so fiddly described in this blog post can be dropped in a world where we no longer have input addressing, and just have content-addressing. Or, in a world where we have a new, simpler type of input-addressing instead.)

jbstack · 2 months ago
Well, there's Guix as an alternative if you want a similar concept but different implementation philosophy. For me the major disadvantage of Guix is lack of package availability compared to Nix.
n8henrie · a month ago
I really wish Guix worked on macOS. Nix-Darwin and home-manager have been game changers -- sharing much config and tooling between my Mac, arch, and nixos machines has been a blessing.
amelius · 2 months ago
Isn't there a way to transpile the scripts from Nix to Guix?
zamalek · 2 months ago
AFAIK Guix uses parts of Nix as a backend.
mystifyingpoi · 2 months ago
I feel the same about HCL in Terraform. The tool is perfect, the language is bollocks.
WillDaSilva · 2 months ago
Pulumi may be what you're looking for. Same concept as Terraform, and many of its provider libraries are just wrappers around Terraform provider libraries, but you can use a variety of common programming languages to declare your desired state, rather than HCL.
otabdeveloper4 · 2 months ago
It has been rewritten a few times already. The "fixed output hash" is a dirty optimisation hack borne out of real-world needs and not a research idea.
Valodim · 2 months ago
Eh. This can be applied to so many technologies that run the world..
beardsciences · 2 months ago
If I understand this correctly, upcoming Ca-derivations will fix this by making these situations expected, properly-handled cases rather than a weird bug? https://nixos.wiki/wiki/Ca-derivations
Ericson2314 · 2 months ago
Yes, a hope of mine is that we can stop using "hash derivation modulo" entirely.

I've recently started some fancy formal spec-level documentation here https://github.com/NixOS/nix/pull/14408 The "resolution" equivalence class is both simpler and better than the "hash derivation modulo ..." one.

(The fact that it is a mouthful to say what the derivations are modulo kinda gives the game away! I put "hash quotient derivation" in the docs to side-step the issue.)

edolstra · 2 months ago
To be clear, there is no bug here: derivers are simply not uniquely determined in the presence of fixed-output derivations, which is by design. That's even more true with CA derivations.

CA derivations also introduce the opposite situation, namely that the same derivation can produce different output paths for different users (if the build is not bitwise reproducible).

setheron · 2 months ago
pick your poison: 1:N or N:1 ;P
setheron · 2 months ago
ca-derivations from what i understand, fixed-output derivations but more general.

The point of the article to me (author) was that i found it odd that Nix replaces the derivations when calculating the output path but not the derivation path. (talking about "paths" in Nix is so hard!)

beardsciences · 2 months ago
That makes sense, thanks for clarifying. Great writeup.
huem0n · 2 months ago
As a mere mortal I find none of this surprising, mostly because I never understood any of it in the first place ... :)
eviks · 2 months ago
> nix/store/24v9wpp393ib1gllip7ic13aycbi704g-ruby-3.3.9.drv

A different type of madness, but are ugly names so common, why not start with ruby-3.3.9 so any list of files is semantically sorted/readable?

rkomorn · 2 months ago
The package name is "secondary" information in this context. The hash is the primary one because it's stable unless the input changes.

The semantic is "what did this configuration generate", not "what's this package's version".

eviks · 2 months ago
it's primary for every human involved, also, the way you check whether it's changed is by automatically comparing that full hash, not its starting symbols, so you don't care where in the full string it's positioned

> The semantic is "what did this configuration generate", not "what's this package's version".

Then why have the name/version at all like in those nameless cache dirs?

Kootle · 2 months ago
In nix packages (derivations) are so lightweight that your store has tens of thousands of them, many with the same name, or with no meaningful name at all. On the rare occasions that you need to look in the store for a package you’re much more likely to be looking for a particular hash than a particular name. That, and having the hash as a prefix looks nicer in tabular output.
Ericson2314 · 2 months ago
If I had my way

1. store paths would have no names at all

2. listing the contents of the store directory would not be allowed

3. store paths have more bits of information

Then store paths are halfway decent (but non-revocable) capabilities.

tkz1312 · 2 months ago
I grep through the store pretty regularly looking for names. The tone of the original comment is annoying but the suggestion is imo quite a good one.
otabdeveloper4 · 2 months ago
It's done that way on purpose. Precisely so you don't try to use the paths semantically. The names literally mean nothing in this context.
eviks · 2 months ago
That contradicts the simple fact that the name includes "ruby" and isn't just a hash
whacked_new · 2 months ago
I can't find the video of the talk where either Eelco Dolstra (nix) or Todd Gamblin (spack) talks about this, but IIRC it's a design decision; you generally don't go spelunking in the nix store, but if you do, and you ls /nix/store, you'll see a huge list of packages, and due to the hash being a constant length, you can visually separate the tails of the package names like

    0009flr197p89fz2vg032g556014z7v1-libass-0.17.3.drv
    000ghm78048kh2prsfzkf93xm3803m0r-default.md
    001f6fysrshkq7gaki4lv8qkl38vjr6a-python-runtime-deps-check-hook.sh.drv
    001gp43bjqzx60cg345n2slzg7131za8-nix-nss-open-files.patch
    001im7qm8achbyh0ywil6hif6rqf284z-bootstrap-stage0-binutils-wrapper-boot.drv
    001pc0cpvpqix4hy9z296qnp0yj00f4n-zbmath-review-template.r59693.tar.xz.drv
Spack, another deterministic builder / package manager, IIRC uses the reversed order so the hash is at the tail. Pros/cons under different search / inspection conditions.

eviks · 2 months ago
> Pros/cons under different search / inspection conditions.

But what's the pro? The tail alignment is worse than the head alignment since you read head to tail, not the other way aground

setheron · 2 months ago
I would be interested in that video.
XorNot · 2 months ago
The reason it's like this is because the only way to reliably grab it is to cut the string at the first hyphen - then the rest can be almost free text.

It you do it the other way it's harder. You can try this with nix commands /nix/store/<hash>-x is a valid way to refer to something in the store most of the time.

Kudos · 2 months ago
You could just use the last hyphen. It's not as simple since you need to scan the whole string, but it certainly doesn't seem like a challenge to me.
singron · 2 months ago
It really doesn't matter. As a normal user, you don't use `drv` files directly, and everything you configure yourself will use attribute paths in nixpkgs. E.g. `pkgs.ruby` or `pkgs.ruby_3_3`.

Dead Comment