nix_2_3: drop and raise minver to 2.18#428076
Conversation
There was a problem hiding this comment.
Yes, this is a bit odd, but:
- I can't set
minverto "2.24.0", because lix will then fail to evaluate Nixpkgs. - I can't set
minverto "2.18.3" without changes here, because thenix_2_18attribute doesn't exist.
Maybe the proper solution is to track Nix and Lix minvers separately?
(also this part doesn't work, yet, it fails another part of CI)
There was a problem hiding this comment.
Lix is never going to change builtins.nixVersion so "good luck. it should be observably identical at least until we have builtins.features"! We saw it as a compat hazard in the very early days and hard-coded it permanently and we don't intend to violate that contract of "you can't detect it? you can't add it".
You might realize a pattern of us being a stick in the mud about a strong compat policy, which is directly descending from Lix being influenced by the former nixpkgs nix package maintainers to be what they wished was the package in pkgs.nix if they could get away with doing that politically (e.g. see biases on this issue that result from composition of the SC).
There was a problem hiding this comment.
Lix is never going to change builtins.nixVersion so "good luck. it should be observably identical at least until we have builtins.features"!
Ok, so we don't actually need a minimum version for Lix (at least not one based on builtins.nixVersion), but rather a "check if this is either suffixed with -lix or matches minver.nix". Does that make sense at this stage?
There was a problem hiding this comment.
The thing I expect it to be doing is:
- checking it's at least 2.18
- checking required features are present e.g. builtins or members of builtins.features once builtins.features exists
I would not expect any other checks. If you can't detect it, you can't use it, and I think y'all can hold CppNix to the same standard since if they violate that rule with a new feature, nixpkgs uses it and nixpkgs breaks, it implies they have broken nix language compatibility with Lix.
There was a problem hiding this comment.
OK, so what you're saying essentially means that we should get rid of the concept of nixVersions.minimum entirely. We should hand-select the versions we'd like to test instead.
That's because if we do the "does your nix support all features that we need?" approach to checking on the entrypoint, then we can't flip this concept around. We can't magically build a nix version "with the minimal feature set" by disabling all other features and test with that in CI.
There was a problem hiding this comment.
I think that since the Nix team’s policy is to only support the latest version and the default version(s?) in Nixpkgs, minimum doesn’t make much sense at this point. But I do think putting 2.18 in lib/minver.nix makes sense as a “language, cache, etc. baseline” in lieu of a better versioning scheme for those. Maybe having a specific package alias for the baseline doesn’t make sense, though, if it’ll only be consumed by CI that can manually select what to use. That means minver.nix could drift from reality, but in the absence of actual Nix 2.18 it’s already a little fuzzy.
There was a problem hiding this comment.
I'd say we don't really need lib/minver.nix in this case, because we don't expect it to change anymore in the future. It could be hardcoded, similar to builtins ? nixVersion, which is already a simple feature check. But I'll refrain from making this change in this PR.
|
2.18 as a baseline was what was previously discussed (with you and @Ma27, I believe?). It seems reasonable to me. I don’t know if we want to set a particular point version or not; I believe we’re on 2.3.bignumber because a bunch of things got backported specifically so they could be used in Nixpkgs. It’s unfortunate that 2.18 is no longer in Nixpkgs so we can’t use it directly for eval checks, but since we check parsing against Lix already it seems sensible to me to use it for baseline eval checks too, and in any case having a CI baseline that gets security patches seems like a good idea. Maybe we can move I know @flokli said he still considers 2.3 evaluation compatibility important the last time we talked about it on Matrix. That was before the vulnerabilities, though. If Tvix/Snix match 2.3, I suppose we could add those to CI? But IIRC they can’t evaluate all of Nixpkgs properly yet, so we might not want to make it load‐bearing. I could be wrong though. The PR title is inaccurate. |
pkgs/top-level/python-aliases.nix
Outdated
There was a problem hiding this comment.
What if it was all just a dream?
To be clear: We only do eval with Nix 2.29 right now. We do parse checks with Nix 2.3, 2.29 and Lix. Do I understand correctly, that you're suggesting to just remove Nix 2.3 from that, and only do parse checks with 2.29 and Lix? Aka: Do we consider Lix to still reflect "2.18", even if it advances?
This was written while I still assumed Lix to be something like 2.91.x, in which case it would have been accurate. I'm still not sure how to deal with the above. |
Right. I thought we might do some other checks against the minimal version too. I think it would be good to have more thorough checks of eval against what we claim as our baseline – especially, checks that no derivation/output hashes change! – but I assume it would probably have to wait for merge queues.
My understanding is that Lix do not intend to introduce any new language‐accessible functionality without explicit feature gating or versioning – at least out of “obviously unstable” edge cases? – but I can’t speak with confidence there; maybe that only applies to syntax rather than built‐ins? Hopefully someone from the Lix team can comment more authoritatively. But there are definitely things in newer versions of Nix that Lix does not implement and I think does not intend to, so I think it’s sensible as a “keep us honest” choice for 2.18 compatibility. Note that 24.05 shipped with Nix 2.18 as the default. So I think we do actually care about compatibility with Nix 2.18, and 2.24 would be too much; yeah, 24.05 is long EOL, but I don’t feel good about the idea that we could break even evaluating a new version to upgrade after you take a machine that hasn’t been touched in under a year out of storage. Unfortunately we have no way to validate that directly in CI. |
I wonder whether we should do all our Eval with the version that is closest to the minimum, aka 2.3 now or 2.18 after this PR. And then only do the additional parse checks with latest versions. In theory, we could also run one version on push events (the target branch) and one version on pull requests. Then, if we get "fake rebuilds", aka some where we didn't actually change the code, but still got different hashes, we'd know something is up. In practice, this should only happen when introducing a new Nix/Lix version, which would only happen when updating the pinned nixpkgs for CI. (theoretically, it could happen when somebody introduces code to trigger an edge-case, that we didn't hit before... but that's unlikely, I think - also these would appear as rebuilds in every PR, so should be quite visible if suddenly a comment-only-change causes rebuilds) |
Lix cares about being hash equivalent to Nix 2.18 (i.e. drvs equivalence, outpath equivalence, etc.) & cares about language stability including with respect to laziness behaviors. All experimental features are out of scope, obviously. Anything else is a bug. |
|
Lix probably cannot be relied upon long term to never ever invent new language features that are on by default, but in general our position is "we're not doing that until there's a versioning mechanism and if CppNix forces our hand by not having a stability policy and adding features that are relied upon then we will take it case by case". Currently one known feature Lix doesn't have is builtins.warn (but we will add it, and adding builtins is.. mostly considered acceptable assuming they have a fully defined contract). In general the attitude is "you don't add something that cannot be detected at runtime. if you don't like that then build a feature detection mechanism". See the Lix builtins.features issue on said feature detection mechanism. The other thing that Lix does is ban bad features that are sufficiently unused (thanks @piegamesde for pushing on this evolution!). The most notable ones so far are:
Those bans aren't a problem for nixpkgs because it just forces nixpkgs to stay honest with actually never adding them back. |
I think it’s good to ensure all of (minimum versions, default versions, latest versions) work. That would be too much, though, so we have to pick and choose. I don’t have a strong opinion on what we should pick if we can only have one except that it seems best to be conservative about unnecessary changes in this PR since it’s already likely to be a matter of some controversy. My hope is that merge queues would allow us to cover at least both the minimum version and the default or latest, by punting all but one eval into the queue job; we could then also ensure hash stability between versions, which is important for Nixpkgs integrity and also I believe something that has regressed in the past (due to implementation bugs rather than Nixpkgs ones). (Modulo available CI resources, checking eval against Lix seems like a sensible idea in general given a lot of contributors and deployments use it, even aside from how we encode the minimum version stuff.) |
|
By the way you could probably write such an evaluation test that's slow as a nightly CI job and it wouldn't lose very much aside from not being able to kick out the bad code from the merge train, even without a merge queue. |
If we just compare minimum vs latest, then:
I'd say the chance for breakage is smaller in the second case, although #428076 (comment) explicitly mentions removal of "integer overflow". So we'd need to make sure to at least test with a version that throw for this as well.
Absolutely, I don't intend to make any changes that way in this PR. But it's important to understand which direction to take wrt to My current gut feel is going towards: We should define both a minimum Nix and a minimum Lix version and test against both of these. But only these, not stable or latest - that would use too many resources. Also, since Lix is removing support for a few things, I would run Lix in PRs, to catch somebody using the removed features early. Then run Nix on pushes and then compare the results. This should give us really good coverage already. Since new versions are only introduced when updating the pinned nixpkgs, we could also add a matrix of eval jobs only when |
|
I guess the thing is, Lix is the one that can be relied upon for having the strictest semantics, but there's been historically many bugs found in CppNix immediately after a version becomes nixpkgs default, so it winds up being somewhat part of their QA which is a reason it probably needs to be tested also (I used to be involved in pkgs.nix upgrades for about two to three years). The integer overflow example is actually a happy accident caused by Lix running hardening flags in prod, not noticing we removed integer overflow, not learning we crashed on it for months, then being like "damn we can just ban it with a good error". I also backported that one to CppNix so the nix language simply doesn't have integer overflow in either implementation period. The other language features you could largely just catch with a parse check (or a linter! the reason we banned them was because they were unacceptable in nixpkgs for ages). |
Why are we setting |
MattSturgeon
left a comment
There was a problem hiding this comment.
We can then still discuss in a follow up:
- Do we want to keep or replace the concept of "minver"?
- If we keep "minver": Do we need to Eval with the exact minimum version, at least sometimes?
Yes, that SGTM. My earlier feedback wasn't intended to be actioned in this PR, but this PR felt like the most relevant place to have the discussion.
- I'm strongly in favour of removing the unmaintained
nix_2_3package. - I'm neutral to bumping the minver.
- I'd like the minver to get some eval testing, but in a separate PR.
Nits and discussion below:
ci/default.nix
Outdated
There was a problem hiding this comment.
Could we have a "TODO test the minimum version (2.18)" style comment?
Ideally referencing a relevant comment on this PR or a tracking issue.
There was a problem hiding this comment.
Could we have a "TODO test the minimum version (2.18)" style comment?
Since I don't agree with that TODO in this form, I'd rather not. I could add something like "TODO: Decide whether to test the minimum version..." etc, but even then I don't quite agree with it: As said earlier, I think the concept of "minimum version" doesn't make sense anymore.
Thus, I think these kinds of TODOs / comments should be discussed as part of the follow up about minimum version in general. We certainly still have the reference of this PR and we can easily look up the places to consider that way.
There was a problem hiding this comment.
Sure. I wouldn't expect you to add TODOs that you don't agree with.
I do feel like we should be testing eval against the minver, but we can discuss if/how/when/where to do that after this PR, as you say.
Sounds good. |
IIUC the dependency on |
0e14d40 to
7e1a1e4
Compare
|
Also extracted pythonix commits into its own PR: #433036 |
The concept of this alias becomes questionable once we move past 2.18, where Lix was forked. We should probably move to a feature-detection based approach for lib/minver.nix eventually, too.
This has been marked insecure a while ago, as some CVEs have not been backported. Even if *some* CVEs are fixed, we'd need **all** of them to be, to get it back into the cache. Not having it in the cache means, we can not test it in CI. This means we can't make sure to actually support this version to evaluate Nixpkgs.
7e1a1e4 to
fa0cba1
Compare
This comment was marked as resolved.
This comment was marked as resolved.
The follow up with my proposal on how to evolve "minver" towards a feature-based approach is in #433057. Also two more PRs with cleanups possible after bumping minver: #433055 and #433056. |
|
+1 on this PR. Unfortunately this means people who where still reluctant to flakes, and that might be for good reasons get their stability guarantees on lib dropped. One the other hand i understand that backporting all fixes to 2.3 is also not long term maintainable. I like this because it finally frees up the use of 'nix-unit' for our eval tests. which hasnt been backported yet to 2.3 So this inherently resolves the biggest blocker for my planned lib test migration. 😄 |
Nix 2.3 was marked insecure in #420974.
In #427437, we updated the pinned nixpkgs for CI at which point we were not able to test Nix 2.3 in CI anymore and had to remove it from the
parsecheck.This brought up #427437 (comment) and #427437 (comment). The same questions asked therein, are still open: What's the plan for Nix 2.3 going forward?
I have neither the ability, nor the intent to backport the patches myself, "removal" is the only suggestion I can practically make, thus this PR.
Things done
Add a 👍 reaction to pull requests you find important.