LnL7 / nix-darwin

nix modules for darwin
MIT License
2.43k stars 407 forks source link

macOS Sequoia replaces `_nixbld{1,2,3,4}` with system users causing `darwin-rebuild` to fail #970

Open stepbrobd opened 3 weeks ago

stepbrobd commented 3 weeks ago

darwin-rebuild errors out after upgrading from macOS Sonoma to macOS Sequoia with the following error:

$ darwin-rebuild switch --flake .#macbook --show-trace
building the system configuration...
error: the user '_nixbld1' in the group 'nixbld' does not exist

Probably caused by the same reason as https://github.com/DeterminateSystems/nix-installer/issues/1001: Apple created couple users with uid ranging from 301~304, replacing _nixbld{1,2,3,4}

A temprory fix I found is executing all darwin-* commands with --option build-users-group ''

Users with uid starting from 300 (dscacheutil -q group could also be useful):

$ dscacheutil -q user
...
name: _aonsensed
password: *
uid: 300
gid: 300
dir: /var/db/aonsensed
shell: /usr/bin/false
gecos: Always On Sense Daemon

name: _modelmanagerd
password: *
uid: 301
gid: 301
dir: /var/db/modelmanagerd
shell: /usr/bin/false
gecos: Model Manager

name: _reportsystemmemory
password: *
uid: 302
gid: 302
dir: /var/empty
shell: /usr/bin/false
gecos: ReportSystemMemory

name: _swtransparencyd
password: *
uid: 303
gid: 303
dir: /var/db/swtransparencyd
shell: /usr/bin/false
gecos: Software Transparency Services

name: _naturallanguaged
password: *
uid: 304
gid: 304
dir: /var/db/com.apple.naturallanguaged
shell: /usr/bin/false
gecos: Natural Language Services

name: _nixbld5
password: ********
uid: 305
gid: 30000
dir: /var/empty
shell: /sbin/nologin
gecos: _nixbld5
...
malob commented 3 weeks ago

When running darwin-rebuild switch, I was getting the following error:

creating user _nixbld1...
<main> attribute status: eDSRecordAlreadyExists
<dscl_cmd> DS Error: -14135 (eDSRecordAlreadyExists)

Disabling the following resolved the issue:

nix.configureBuildUsers = true;
emilazy commented 2 weeks ago

I think you should also be able to override ids.uids.nixbld to work around this for now, which is arguably slightly cleaner than foregoing managing the Nix users entirely.

We should wait to see what the official installer and Determinate Systems settle on before changing the IDs ourselves, I think. Might be a bit messy in terms of migration. I’ll pin this for now to make the workarounds more discoverable.

stepbrobd commented 2 weeks ago

I think you should also be able to override ids.uids.nixbld to work around this for now, which is arguably slightly cleaner than foregoing managing the Nix users entirely.

For future reference, here's what I did:

  1. Add the following two lines of Nix code to your nix-darwin config:
nix.configureBuildUsers = true;
ids.uids.nixbld = lib.mkForce 30000; # or some other uid
  1. Run the rebuild with --option build-users-group '', for example:

DO NOT SKIP TO STEP 4 or you might end up with a system without any build user

darwin-rebuild switch --flake .#macbook --show-trace --option build-users-group ''
  1. You should see some warnings during the rebuild but that's expected:
warning: existing user '_nixbld5' has unexpected uid 305, skipping...
...
warning: existing user '_nixbld32' has unexpected uid 332, skipping...
  1. Take the start/end ID, then execute:
#     start  end
#         v  v
for i in {5..32}; do sudo dscl . -delete /Users/_nixbld$i; done
  1. Rebuild again
emilazy commented 2 weeks ago

You definitely want to use UIDs in the system range (200 to 400, I believe), as using high user IDs caused other problems in the past (though I don’t remember exactly what). Hopefully we can work out a clean migration solution once this shakes out upstream.

bestlem commented 2 weeks ago

For reference I did bit of googling lead me to this Super User Question

Question includes two relevant things

I used to use ids from 401 onwards for services, but I noticed that OS X 10.6 has started using that range for groups created by the Sharing pane in System Preferences.

and

There is an Apple supplied tool /usr/sbin/sysadminctl

Running with no parameters gives its options and some comments at the end. The relevant bits are I think

...
-addUser <user name> [-fullName <full name>] [-UID <user ID>] [-GID <group ID>] [-shell <path to shell>] [-password <user password>] [-hint <user hint>] [-home <full path to home>] [-admin] [-roleAccount] [-picture <full path to user image>] (interactive] || -adminUser <administrator user name> -adminPassword <administrator password>)
...
*Role accounts require name starting with _ and UID in 200-400 range.