Skip to content
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

nix: fix auto-allocate-uids #1335

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

andre4ik3
Copy link

@andre4ik3 andre4ik3 commented Feb 13, 2025

A few days ago, there was a change 1 that removed the nix.configureBuildUsers option, and made it so that the build users and group was always managed. Unfortunately this broke the auto-allocate-uids option:

  1. configureBuildUsers (internal variable) is set to false if auto-allocate-uids is set to true. Link

  2. The users and groups are configured when configureBuildUsers is true (so auto-allocate-uids is false)... Link

  3. ...but the users and groups are added to knownUsers and knownGroups regardless... Link

  4. ...which leads to the assertions on Line 798 always being false, and also leads to nix-darwin attempt to delete the nixbld group. Link

The error shown when rebuilding with the problematic change and auto-allocate-uids enabled is this:

error:
Failed assertions:
- refusing to delete group nixbld in users.knownGroups, this would break nix
- refusing to delete user _nixbld1 in users.knownUsers, this would break nix

This PR fixes both of these issues (failed assertion and attempt to delete nixbld group, which is still necessary for auto-allocate-uids despite no users being in the group), by only adding the user assertions when configureBuildUsers is true, and updating the users.knownUsers to also only be set in that case. Additionally, the nixbld group is now always created.

Footnotes

  1. Commit adc989f

Copy link
Collaborator

@emilazy emilazy left a comment

Choose a reason for hiding this comment

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

Thanks! I tried to accommodate auto-allocate-uids when making these changes but missed this detail. I’m surprised it has users since my experience was that it was pretty broken, but I definitely don’t want to make it harder for people to try out experimental features.

I didn’t realize that the nixbld group still has to exist for auto-allocate-uids; I guess for ownership of store paths being built or something?

modules/nix/default.nix Outdated Show resolved Hide resolved
modules/nix/default.nix Outdated Show resolved Hide resolved
@@ -836,18 +838,18 @@ in
users.users = mkIf configureBuildUsers nixbldUsers;

# Not in NixOS module
users.groups.nixbld = mkIf configureBuildUsers {
users.groups.nixbld = {
description = "Nix build group for nix-daemon";
gid = config.ids.gids.nixbld;
members = attrNames nixbldUsers;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should probably be empty if !configureBuildUsers.

Copy link
Author

@andre4ik3 andre4ik3 Feb 13, 2025

Choose a reason for hiding this comment

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

But then the group wouldn't be created if auto-allocate-uids is true? I mean, to be fair, I haven't seen it actually documented anywhere that the group is required. Maybe I'm wrong or my config is messed up somehow. But both on my NixOS and Darwin machines, if the group doesn't exist, it just gives the error:

error: the group 'nixbld' specified in 'build-users-group' does not exist

If the group is created, even though it has no members, it will work fine and create the UIDs. If the build-users-group is set to be empty, it will just build everything as root. (I am also using Lix, maybe could be because of that)

A few days ago, there was a change [^1] that removed the
`nix.configureBuildUsers` option, and made it so that the build users
and group was always managed. Unfortunately this broke the
`auto-allocate-uids` option:

1. `configureBuildUsers` (internal variable) is set to false if
   `auto-allocate-uids` is set to true. (Line 15)

2. The users and groups are configured when `configureBuildUsers` is
   true (so `auto-allocate-uids` is false)... (Line 841)

3. ...but the users and groups are added to `knownUsers` and
   `knownGroups` regardless... (Line 846)

4. ...which leads to the assertions on Line 798 always being false, and
   also leads to nix-darwin attempt to delete the `nixbld` group.

The error shown when rebuilding with the problematic change and
`auto-allocate-uids` enabled is this:

```
error:
Failed assertions:
- refusing to delete group nixbld in users.knownGroups, this would break nix
- refusing to delete user _nixbld1 in users.knownUsers, this would break nix
```

This PR fixes both of these issues (failed assertion and attempt to
delete `nixbld` group, which is still necessary for `auto-allocate-uids`
despite no users being in the group), by only adding the user assertions
when `configureBuildUsers` is true, and updating the `users.knownUsers`
to also only be set in that case. Additionally, the `nixbld` group is
now always created.

[^1]: Commit adc989f
@andre4ik3 andre4ik3 force-pushed the fix-auto-allocate-uids branch from c3fe32d to 7f6a969 Compare February 13, 2025 18:44
@andre4ik3
Copy link
Author

andre4ik3 commented Feb 13, 2025

This turned out to be a bit more involved than I originally anticipated. Whilst the original version of the PR did evaluate without errors, if it activated it would have probably broken everything, and by sheer coincidence I was on slow Wi-Fi and it needed to download some big updated packages, which just didn't work. So it never activated, which would have probably totally broken my computer and deleted the build group or something.

Now, I tested both options on my system, toggling between auto-allocate-uids on and off, and watching it delete and recreate the users properly. It turns out there was an activation check that would warn about pre-Sequoia build users, but it would break if no nixbld users existed. So I fixed it by adding a default of 0 as a fallback (let me know if there is a more "proper"/better way to do this) and skipping the check if no users exist, or if auto-allocate-uids is true (which aren't necessarily the same thing -- e.g. coming off of auto-allocate-uids and trying to get back to build users when none exist).

And also, in modules/users/default.nix, it would refuse to delete users with UID below 501, so if you turned on auto-allocate-uids it would leave a bunch of unused users, saying existing user '_nixbldXX' has unexpected uid XXX, skipping.... This was fixed by removing the check for UIDs below 501 (however I'm not sure why that check was there? Is there something else it was designed to be a safeguard against?), so now the users delete properly.

auto-allocate-uids.mp4

@andre4ik3 andre4ik3 requested a review from emilazy February 13, 2025 19:07
YorikSar added a commit to YorikSar/dotfiles that referenced this pull request Feb 16, 2025
Hold off updating nix-darwin past LnL7/nix-darwin#1313
until LnL7/nix-darwin#1335 is resolved, because
of auto-allocate-uids.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants