Skip to content

Conversation

thefossguy
Copy link
Member

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • Nixpkgs 25.11 Release Notes (or backporting 24.11 and 25.05 Nixpkgs Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
  • NixOS 25.11 Release Notes (or backporting 24.11 and 25.05 NixOS Release notes)
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Given this module has no maintainers in the file, I'm pinging some people who were involved in a PR related to this file. @SuperSandro2000 @Aleksanaa @0x4A6F @davidak @Ericson2314

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jun 8, 2025
@thefossguy thefossguy force-pushed the nixos-system-path-2025-06-08 branch from fb0ab8f to 5d80888 Compare June 8, 2025 19:06
@github-actions github-actions bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Jun 8, 2025
Comment on lines 17 to 20
if requiredPackagesPriority == null then
((pkg.meta.priority or lib.meta.defaultPriority) + 3)
else
requiredPackagesPriority
Copy link
Contributor

Choose a reason for hiding this comment

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

https://nix.dev/manual/nix/2.28/language/operators#attribute-selection

But:

  1. only works with full attrpaths, can't be used for single variables
  2. I MISUNDERSTOOD, it only check for defined/undefined, not null/non-null or truthy/falsy. Ignore my suggestion, I apologize for misinformation

@thefossguy thefossguy force-pushed the nixos-system-path-2025-06-08 branch from 5d80888 to 83f7041 Compare June 10, 2025 05:15
@github-actions github-actions bot added the 10.rebuild-linux: 1 This PR causes 1 package to rebuild on Linux. label Jun 10, 2025
@thefossguy thefossguy force-pushed the nixos-system-path-2025-06-08 branch from 83f7041 to adb0ec8 Compare June 10, 2025 05:22
@thefossguy thefossguy marked this pull request as draft June 10, 2025 05:24
…ages`

At the moment, we reduce the priority of `requiredPackages` by default
to ensure that said packages are installed in the system. This opens up
the possibility of a binary being used from an unintentional package.

I noticed this with the `xz` and the `rpi-imager` package so I will
explain with that as an example.

- The `xz` package has not set a priority using the `meta.priority`
  attribute. Given that it is in the `requiredPackages` list of
  packages, the `map` function assigns it the priority of 8 because
  `lib.meta.defaultPriority` is 5 and then a value of 3 is added to it
  for safe measure. Making it a priority of 8 using `lib.setPrio`.

- The `rpi-imager` package, like `xz` does not have a priority set
  either. But, when it is included in the `paths` attribute of
  `pkgs.buildEnv` function, if no priority is set, a default priority is
  provided to it of the value of `lib.meta.defaultPriority`[0]. Now
  making the priority value of `rpi-imager` 5.

This means, if there were ever to be a conflict of paths between
`rpi-imager` and `xz`, `rpi-imager` would have a higher priority.

And, given that both packages provide a binary called `xz` under
`${pkg}/bin`, this does indeed create a path collision for `sw/bin/xz`
between the `xz` and `rpi-imager` packages.

This is just one instance of such an error that I only happened to
notice because of a guide I was writing. To me, this behaviour was
unintentional and this commit adds a way for like minded individuals to
override the priority value assigned to `requiredPackages`, instead of
yak shaving if the priority value for `requiredPackages` should be
higher or lower.

[0]: https://github.com/NixOS/nixpkgs/blob/a8f509677f4a392d75b21b72de4bc74d52b177fb/pkgs/build-support/buildenv/default.nix#L83
@thefossguy thefossguy force-pushed the nixos-system-path-2025-06-08 branch from adb0ec8 to 641743b Compare June 10, 2025 07:50
@github-actions github-actions bot removed the 10.rebuild-linux: 1 This PR causes 1 package to rebuild on Linux. label Jun 10, 2025
@thefossguy thefossguy marked this pull request as ready for review June 10, 2025 07:56
Copy link
Member

@Ma27 Ma27 left a comment

Choose a reason for hiding this comment

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

What exactly is the motivation behind this?

I don't really understand why this is necessary given that you should be able to override stuff with hiPrio pkg already.

@thefossguy
Copy link
Member Author

@Ma27, the commit nixos/system-path: allow users to override priority for requiredPackages exists so that one can easily override the priority of requiredPackages without having to do it manually for every package. I also wanted to find what paths are conflicting by setting the ignoreCollisions attribute's value to false but found no way to override it (like a derivation) and that is why commit nixos/system-path: make system.path overridable exists. I tried my best to explain this in the commit messages themselves.

@alyssais alyssais requested review from K900 and removed request for acid-bong June 13, 2025 17:35
@K900
Copy link
Contributor

K900 commented Jun 13, 2025

Honestly this just feels wrong? Maybe we should just default priority to 0, and disallow collisions? At least that way the end users will hopefully be forced to choose.

@Ma27
Copy link
Member

Ma27 commented Jun 13, 2025

the commit nixos/system-path: allow users to override priority for requiredPackages exists

Ouch, apologies!
I guess my heuristic of "nothing in the PR comment -> no details in the commit either" was at fault here (and yes, that's a me problem).

This means, if there were ever to be a conflict of paths between
rpi-imager and xz, rpi-imager would have a higher priority.

So, I think there are two cases where you run into this:

  • if you choose a different implementation (e.g. GNU coreutils vs. uutils). Then doing hiPrio uutils-coreutils is IMHO the correct thing to override.

  • cases like rpi-imager vs xz: IMHO these sound like a packaging bug. I'd be very curious to learn about the reason why this cannot use the xz from pkgs.xz but needs to ship its own. I think this is kind of the job of a packager to clean these things up (and in this case the primary target is NixOS where xz is available by default even).

    So for me, the motivation seems like a giant workaround for a bug.

This is just one instance of such an error that I only happened to
notice because of a guide I was writing.

This is probably the interesting thing to discuss about: were the collisions you encountered accidental (such as the xz thing) or was there a different reason? Right now, I'm not aware of a third case which is the reason for my skepticism.

Instead of directly assigning a derivation to system.path, a "dummy"
option now exists (system.pathDrv) which contains the initial
system-path derivation.

I'm wondering if adding a environment.ignoreCollisions (or in whatever else namespace) would be better just like we do for e.g. environment.extraOutputsToInstall. I don't see much of a reason to override random buildEnv-attributes and this would also mean that there are two ways now to do the exact same thing (i.e. specifying which outputs to install).

@thefossguy
Copy link
Member Author

I agree that my commits don't actually solve the problem and feel wrong but I made them this way so that the user has more control over the knobs.

Another reason, as I mentioned in the first commit, is that if I come up with a PR to address this tree-wide, there's a very high probably it will not be a productive discussion. This is a temporary fix, until someone else can address it with more knowledge than me.

@thefossguy thefossguy force-pushed the nixos-system-path-2025-06-08 branch from 641743b to b3455e4 Compare June 20, 2025 04:18
@thefossguy
Copy link
Member Author

This means, if there were ever to be a conflict of paths between
rpi-imager and xz, rpi-imager would have a higher priority.

So, I think there are two cases where you run into this:

* if you choose a different implementation (e.g. GNU coreutils vs. uutils). Then doing `hiPrio uutils-coreutils` is IMHO the correct thing to override.

I agree. But IMHO, the packages in requiredPackages should have a higher priority and their output paths should not be overridden by any other packages.

This is just one instance of such an error that I only happened to
notice because of a guide I was writing.

This is probably the interesting thing to discuss about: were the collisions you encountered accidental (such as the xz thing) or was there a different reason? Right now, I'm not aware of a third case which is the reason for my skepticism.

I don't follow. I explained why I thought the collision occurred. I came to the conclusion that due to the current state, xz had the lower priority of 8 while rpi-imager had a higher priority of 5 and since the ${pkg}/bin/xz path collided, the higher priority of rpi-imager was used to link sw/bin/xz to ${pkgs.rpi-imager}/bin/xz instead of ${pkgs.xz}/bin/xz.

I don't know what you mean by "accidental." But I do believe that setting a lower priority for requiredPackages is plain wrong. They should either have the same priority as all other packages (to figure out collisions) or have a higher priority. The first commit allows one to set a negative value (say -15 for example) to ensure that all required packages have a high priority.

Instead of directly assigning a derivation to system.path, a "dummy"
option now exists (system.pathDrv) which contains the initial
system-path derivation.

I'm wondering if adding a environment.ignoreCollisions (or in whatever else namespace) would be better just like we do for e.g. environment.extraOutputsToInstall. I don't see much of a reason to override random buildEnv-attributes and this would also mean that there are two ways now to do the exact same thing (i.e. specifying which outputs to install).

Yeah that sounds better than my approach. I reworked the second commit and force pushed it.

@thefossguy
Copy link
Member Author

Honestly this just feels wrong? Maybe we should just default priority to 0, and disallow collisions? At least that way the end users will hopefully be forced to choose.

Yes, but that would cause a lot of breakage. And I'm not familiar enough with the entirety of nixpkgs to check for every breakage and fix it treewide.

@Ma27
Copy link
Member

Ma27 commented Jun 20, 2025

I don't follow. I explained why I thought the collision occurred. I came to the conclusion that due to the current state, xz had the lower priority of 8 while rpi-imager had a higher priority of 5 and since the ${pkg}/bin/xz path collided, the higher priority of rpi-imager was used to link sw/bin/xz to ${pkgs.rpi-imager}/bin/xz instead of ${pkgs.xz}/bin/xz.

My point is, the fact that rpi-imager has bin/xz in the first place sounds like a bug.
You were mentioning that this is just a single example amongst multiple issues. So I'm curious if all the other issues you faced could be classified as bug either.

If that's the case, I'd argue that this is the wrong knob, but instead we should establish explicit rules to not do this (unless they already exist and I just failed to find them) and fix the packages instead.

I agree. But IMHO, the packages in requiredPackages should have a higher priority and their output paths should not be overridden by any other packages.

Agreed, that's what you should use hiPrio for.
But then again, you still have requiredPriorityOffset = 3 by default which means that this isn't fixed, but people can fix it themselves easier, but with knowledge about package priorities required.

I'm not sure about what a sensible migration path would be, but I think I agree with @K900 here on how to fix this, i.e. by changing the requiredPackages-priority.

@thefossguy
Copy link
Member Author

I get your point. Would it be better if the first commit were to set a priority value of 0 for all (requiredPackages and config.environment.systemPackages) packages? And the second commit were to set options.environment.ignoreCollisions.default to false?

I'll also work on finding and resolving as many conflicts as I can.

@Ma27
Copy link
Member

Ma27 commented Jun 22, 2025

Sounds reasonable to me. @K900 wdyt?

also cc @anthonyroussel for rpi-imager.

@K900
Copy link
Contributor

K900 commented Jun 22, 2025

Sounds reasonable.

@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants