From 1f7ed1c7fe20d9b9d410c4f385a7d13ae1f4349e Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 29 Jan 2025 15:19:46 +0000 Subject: [PATCH 01/11] checks: remove `nixChannels` check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don’t think this is very important given the `nixPath` check, and it doesn’t fit very well into a post‐user‐activation world. --- modules/system/checks.nix | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index b466f4252..7fbe15905 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -152,25 +152,6 @@ let fi ''; - nixChannels = '' - channelsLink=$(readlink "$HOME/.nix-defexpr/channels") || true - case "$channelsLink" in - *"$USER"*) - ;; - "") - ;; - *) - echo "error: The ~/.nix-defexpr/channels symlink does not point your users channels, aborting activation" >&2 - echo "Running nix-channel will regenerate it" >&2 - echo >&2 - echo " rm ~/.nix-defexpr/channels" >&2 - echo " nix-channel --update" >&2 - echo >&2 - exit 2 - ;; - esac - ''; - nixInstaller = '' if grep -q 'etc/profile.d/nix-daemon.sh' /etc/profile; then echo "error: Found nix-daemon.sh reference in /etc/profile, aborting activation" >&2 @@ -315,6 +296,10 @@ let in { + imports = [ + (mkRemovedOptionModule [ "system" "checks" "verifyNixChannels" ] "This check has been removed.") + ]; + options = { system.checks.verifyNixPath = mkOption { type = types.bool; @@ -322,12 +307,6 @@ in description = "Whether to run the NIX_PATH validation checks."; }; - system.checks.verifyNixChannels = mkOption { - type = types.bool; - default = config.nix.channel.enable; - description = "Whether to run the nix-channels validation checks."; - }; - system.checks.verifyBuildUsers = mkOption { type = types.bool; default = @@ -361,7 +340,6 @@ in nixStore (mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector) (mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser) - (mkIf cfg.verifyNixChannels nixChannels) nixInstaller (mkIf cfg.verifyNixPath nixPath) oldSshAuthorizedKeysDirectory From 8f227c405e0d42dfdbfce9849c689152c083a48b Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 29 Jan 2025 01:08:02 +0000 Subject: [PATCH 02/11] nix: fix typo in assertion conditional --- modules/nix/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 857c4be81..b70487d71 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -759,7 +759,7 @@ in # Not in NixOS module { assertion = elem "nixbld" config.users.knownGroups -> elem "nixbld" createdGroups; message = "refusing to delete group nixbld in users.knownGroups, this would break nix"; } - { assertion = elem "_nixbld1" config.users.knownGroups -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; } + { assertion = elem "_nixbld1" config.users.knownUsers -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; } { assertion = config.users.groups ? "nixbld" -> config.users.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; } { From 9b9c9a57b626d72c4def5c2ddb7253bccb19c75d Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 19:30:20 +0000 Subject: [PATCH 03/11] =?UTF-8?q?nix:=20don=E2=80=99t=20set=20`$NIX=5FREMO?= =?UTF-8?q?TE`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NixOS doesn’t bother doing this, and Nix already matches this conditional behaviour when `$NIX_REMOTE` is unset. --- modules/nix/default.nix | 20 +++++--------------- tests/services-nix-daemon.nix | 3 --- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index b70487d71..b373e778a 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -785,21 +785,11 @@ in # Set up the environment variables for running Nix. environment.variables = cfg.envVars // { NIX_PATH = cfg.nixPath; }; - environment.extraInit = mkMerge [ - (mkIf cfg.channel.enable '' - if [ -e "$HOME/.nix-defexpr/channels" ]; then - export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}" - fi - '') - # Not in NixOS module - '' - # Set up secure multi-user builds: non-root users build through the - # Nix daemon. - if [ ! -w /nix/var/nix/db ]; then - export NIX_REMOTE=daemon - fi - '' - ]; + environment.extraInit = mkIf cfg.channel.enable '' + if [ -e "$HOME/.nix-defexpr/channels" ]; then + export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}" + fi + ''; environment.extraSetup = mkIf (!cfg.channel.enable) '' rm --force $out/bin/nix-channel diff --git a/tests/services-nix-daemon.nix b/tests/services-nix-daemon.nix index 3a217cbb3..86dbd57c4 100644 --- a/tests/services-nix-daemon.nix +++ b/tests/services-nix-daemon.nix @@ -27,8 +27,5 @@ in echo checking nix-daemon reload in /activate >&2 grep "launchctl kill HUP system/org.nixos.nix-daemon" ${config.out}/activate - - echo checking NIX_REMOTE=daemon in setEnvironment >&2 - grep "NIX_REMOTE=daemon" ${config.system.build.setEnvironment} ''; } From e182d8dff6bd3b0913ae6531c6abae3ed1e38364 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 18:40:29 +0000 Subject: [PATCH 04/11] nix: add `nix.enable` option to disable Nix management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an equivalent of the `nix.enable` option from NixOS and Home Manager. On NixOS, it mostly serves to allow building fixed‐configuration systems without any Nix installation at all. It should work for that purpose with nix-darwin too, and the implementation is largely the same, but the main use case is more similar to the Home Manager option: to allow the use of nix-darwin with an unmanaged system installation of Nix, including when there is another service expecting to manage it, as with Determinate. By providing an escape hatch to opt out of Nix management entirely, this will also allow us to consolidate and simplify our existing Nix installation management, by being more opinionated about things like taking ownership of the daemon and the build users. Porting one option from NixOS lets us drop two that only ever existed in nix-darwin and reduce overall complexity. --- modules/nix/default.nix | 52 +++++++++++++++++++++-- modules/services/nix-daemon.nix | 2 +- modules/system/checks.nix | 9 ++-- pkgs/darwin-uninstaller/configuration.nix | 12 +----- pkgs/darwin-uninstaller/default.nix | 9 ++-- release.nix | 1 + tests/nix-enable.nix | 14 ++++++ 7 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 tests/nix-enable.nix diff --git a/modules/nix/default.nix b/modules/nix/default.nix index b373e778a..39820dace 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -134,6 +134,26 @@ let namedPaths ++ searchPaths; }; + handleUnmanaged = managedConfig: mkMerge [ + (mkIf cfg.enable managedConfig) + (mkIf (!cfg.enable) { + system.activationScripts.nix-daemon.text = '' + # Restore unmanaged Nix daemon if present + unmanagedNixProfile=/nix/var/nix/profiles/default + if [[ + -e /run/current-system/Library/LaunchDaemons/org.nixos.nix-daemon.plist + && -e $unmanagedNixProfile/Library/LaunchDaemons/org.nixos.nix-daemon.plist + ]]; then + printf >&2 'restoring unmanaged Nix daemon...\n' + cp \ + "$unmanagedNixProfile/Library/LaunchDaemons/org.nixos.nix-daemon.plist" \ + /Library/LaunchDaemons + launchctl load -w /Library/LaunchDaemons/org.nixos.nix-daemon.plist + fi + ''; + }) + ]; + in { @@ -144,7 +164,6 @@ in in [ # Only ever in NixOS - (mkRemovedOptionModule [ "nix" "enable" ] "No `nix-darwin` equivalent to this NixOS option.") (mkRemovedOptionModule [ "nix" "daemonCPUSchedPolicy" ] (altOption "nix.daemonProcessType")) (mkRemovedOptionModule [ "nix" "daemonIOSchedClass" ] (altOption "nix.daemonProcessType")) (mkRemovedOptionModule [ "nix" "daemonIOSchedPriority" ] (altOption "nix.daemonIOLowPriority")) @@ -165,9 +184,36 @@ in nix = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to enable Nix. + + Disabling this will stop nix-darwin from managing the + installed version of Nix, the nix-daemon launchd daemon, and + the settings in {file}`/etc/nix/nix.conf`. + + This allows you to use nix-darwin without it taking over your + system installation of Nix. Some nix-darwin functionality + that relies on managing the Nix installation, like the + `nix.*` options to adjust Nix settings or configure a Linux + builder, will be unavailable. You will also have to upgrade + Nix yourself, as nix-darwin will no longer do so. + + ::: {.warning} + If you have already removed your global system installation + of Nix, this will break nix-darwin and you will have to + reinstall Nix to fix it. + ::: + ''; + }; + package = mkOption { type = types.package; - default = pkgs.nix; + default = warnIf (!cfg.enable) + "nix.package: accessed when `nix.enable` is off; this is a bug" + pkgs.nix; defaultText = literalExpression "pkgs.nix"; description = '' This option specifies the Nix package instance to use throughout the system. @@ -678,7 +724,7 @@ in ###### implementation - config = { + config = handleUnmanaged { environment.systemPackages = [ nixPackage diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index ffc7e651b..df3fa310e 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -10,7 +10,7 @@ in options = { services.nix-daemon.enable = mkOption { type = types.bool; - default = true; + default = config.nix.enable; description = "Whether to enable the nix-daemon service."; }; diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 7fbe15905..cc8048de4 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -303,15 +303,16 @@ in options = { system.checks.verifyNixPath = mkOption { type = types.bool; - default = true; + default = config.nix.enable; description = "Whether to run the NIX_PATH validation checks."; }; system.checks.verifyBuildUsers = mkOption { type = types.bool; default = - (config.nix.useDaemon && !(config.nix.settings.auto-allocate-uids or false)) - || config.nix.configureBuildUsers; + config.nix.enable && + ((config.nix.useDaemon && !(config.nix.settings.auto-allocate-uids or false)) + || config.nix.configureBuildUsers); description = "Whether to run the Nix build users validation checks."; }; @@ -336,7 +337,7 @@ in (mkIf cfg.verifyBuildUsers buildUsers) (mkIf cfg.verifyBuildUsers preSequoiaBuildUsers) (mkIf config.nix.configureBuildUsers buildGroupID) - nixDaemon + (mkIf config.nix.enable nixDaemon) nixStore (mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector) (mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser) diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index 56ab228fc..ce6be6ca0 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -12,8 +12,8 @@ with lib; launchd.daemons = mkForce {}; launchd.user.agents = mkForce {}; - # Don't try to reload `nix-daemon` - nix.useDaemon = mkForce false; + # Restore any unmanaged `nix-daemon`. + nix.enable = false; system.activationScripts.postUserActivation.text = mkAfter '' nix-channel --remove darwin || true @@ -30,14 +30,6 @@ with lib; rm /etc/static fi - # If the Nix Store is owned by root then we're on a multi-user system - if [[ -O /nix/store ]]; then - if [[ -e /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]]; then - sudo cp /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist /Library/LaunchDaemons/org.nixos.nix-daemon.plist - sudo launchctl load -w /Library/LaunchDaemons/org.nixos.nix-daemon.plist - fi - fi - # grep will return 1 when no lines matched which makes this line fail with `set -eo pipefail` dscl . -list /Users UserShell | { grep "\s/run/" || true; } | awk '{print $1}' | while read -r user; do shell=$(dscl . -read /Users/"$user" UserShell) diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index 0214652b5..6b43bcfc0 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -31,8 +31,11 @@ in writeShellApplication { echo >&2 " - remove /Applications/Nix Apps symlink" echo >&2 " - cleanup static /etc files" echo >&2 " - disable and remove all launchd services managed by nix-darwin" - if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then - echo >&2 " - restore nix-daemon service from nix installer as this is a multi-user install" + if [[ + -e /run/current-system/Library/LaunchDaemons/org.nixos.nix-daemon.plist + && -e /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist + ]]; then + echo >&2 " - restore nix-daemon service from the Nix installer" fi echo >&2 @@ -87,7 +90,7 @@ in writeShellApplication { launchctl print system/org.nixos.nix-daemon pgrep -l nix-daemon test -e /Library/LaunchDaemons/org.nixos.nix-daemon.plist - [[ "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" == "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" ]] + [[ "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" == "$(shasum -a 256 /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" ]] nix-store --store daemon -q --hash ${stdenv.shell} fi echo >&2 ok diff --git a/release.nix b/release.nix index b3e2df7ed..52b3c2aa7 100644 --- a/release.nix +++ b/release.nix @@ -88,6 +88,7 @@ in { tests.launchd-setenv = makeTest ./tests/launchd-setenv.nix; tests.networking-hostname = makeTest ./tests/networking-hostname.nix; tests.networking-networkservices = makeTest ./tests/networking-networkservices.nix; + tests.nix-enable = makeTest ./tests/nix-enable.nix; tests.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix; tests.programs-ssh = makeTest ./tests/programs-ssh.nix; tests.programs-tmux = makeTest ./tests/programs-tmux.nix; diff --git a/tests/nix-enable.nix b/tests/nix-enable.nix new file mode 100644 index 000000000..4e7a17822 --- /dev/null +++ b/tests/nix-enable.nix @@ -0,0 +1,14 @@ +{ config, ... }: + +{ + nix.enable = false; + nix.package = throw "`nix.package` used when `nix.enable` is turned off"; + + test = '' + printf >&2 'checking for unexpected Nix binary in /sw/bin\n' + [[ -e ${config.out}/sw/bin/nix-env ]] && exit 1 + + printf >&2 'checking for unexpected nix-daemon plist in /Library/LaunchDaemons\n' + [[ -e ${config.out}/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]] && exit 1 + ''; +} From c796587d2ef4ab06f84c4f740931f579f719b6f5 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 19:30:20 +0000 Subject: [PATCH 05/11] nix: remove `nix.useDaemon` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now assume the daemon is used unconditionally when we manage the Nix installation. The `nix.gc` and `nix.optimise` services lose their `$NIX_REMOTE` setting rather than making it unconditional, as the NixOS `nix.gc` module does not set it. Possibly it should, but I think uniformity between the two systems is better than diverging, even though I kind of hate that the non‐daemon method of access is even a thing. --- modules/nix/default.nix | 22 +++--- modules/services/buildkite-agents.nix | 3 +- modules/services/gitlab-runner.nix | 3 +- .../services/hercules-ci-agent/default.nix | 2 +- modules/services/nix-daemon.nix | 2 - modules/services/nix-gc/default.nix | 10 +-- modules/services/nix-optimise/default.nix | 10 +-- modules/system/checks.nix | 67 +++---------------- release.nix | 1 - tests/checks-nix-gc.nix | 19 ------ tests/services-nix-gc.nix | 6 -- tests/services-nix-optimise.nix | 6 -- 12 files changed, 26 insertions(+), 125 deletions(-) delete mode 100644 tests/checks-nix-gc.nix diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 39820dace..6028e6bb2 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -176,6 +176,10 @@ in (mkRenamedOptionModule [ "users" "nix" "nrBuildUsers" ] [ "nix" "nrBuildUsers" ]) (mkRenamedOptionModule [ "nix" "daemonIONice" ] [ "nix" "daemonIOLowPriority" ]) (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] (consider "nix.daemonProcessType")) + (mkRemovedOptionModule [ "nix" "useDaemon" ] '' + nix-darwin now only supports managing multi‐user daemon + installations of Nix. + '') ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; ###### interface @@ -220,17 +224,6 @@ in ''; }; - # Not in NixOS module - useDaemon = mkOption { - type = types.bool; - default = false; - description = '' - If set, Nix will use the daemon to perform operations. - Use this instead of services.nix-daemon.enable if you don't want the - daemon service to be managed for you. - ''; - }; - distributedBuilds = mkOption { type = types.bool; default = false; @@ -909,7 +902,7 @@ in if [[ -e /etc/nix/nix.custom.conf ]]; then mv /etc/nix/nix.custom.conf{,.before-nix-darwin} fi - '' + optionalString cfg.useDaemon '' + if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null || ! diff /etc/nix/machines /run/current-system/etc/nix/machines &> /dev/null; then echo "reloading nix-daemon..." >&2 launchctl kill HUP system/org.nixos.nix-daemon @@ -926,6 +919,9 @@ in trusted-users = [ "root" ]; substituters = mkAfter [ "https://cache.nixos.org/" ]; + # Not in NixOS module + build-users-group = "nixbld"; + # Not implemented yet # system-features = mkDefault ( # [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++ @@ -941,8 +937,6 @@ in (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; }) - # Not in NixOS module - (mkIf cfg.useDaemon { build-users-group = "nixbld"; }) ]; }; diff --git a/modules/services/buildkite-agents.nix b/modules/services/buildkite-agents.nix index 69bc1f65d..3c04d9046 100644 --- a/modules/services/buildkite-agents.nix +++ b/modules/services/buildkite-agents.nix @@ -227,8 +227,9 @@ in { path = cfg.runtimePackages ++ [ cfg.package pkgs.coreutils pkgs.darwin.DarwinTools ]; environment = { HOME = cfg.dataDir; + NIX_REMOTE = "daemon"; inherit (config.environment.variables) NIX_SSL_CERT_FILE; - } // (if config.nix.useDaemon then { NIX_REMOTE = "daemon"; } else {}); + }; ## NB: maximum care is taken so that secrets (ssh keys and the CI token) ## don't end up in the Nix store. diff --git a/modules/services/gitlab-runner.nix b/modules/services/gitlab-runner.nix index 94c291efd..329fd727e 100644 --- a/modules/services/gitlab-runner.nix +++ b/modules/services/gitlab-runner.nix @@ -551,8 +551,9 @@ in launchd.daemons.gitlab-runner = { environment = { #config.networking.proxy.envVars // { HOME = "${config.users.users.gitlab-runner.home}"; + NIX_REMOTE = "daemon"; NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - } // (if config.nix.useDaemon then { NIX_REMOTE = "daemon"; } else {}); + }; path = with pkgs; [ bash gawk diff --git a/modules/services/hercules-ci-agent/default.nix b/modules/services/hercules-ci-agent/default.nix index fc3d95200..391250659 100644 --- a/modules/services/hercules-ci-agent/default.nix +++ b/modules/services/hercules-ci-agent/default.nix @@ -74,7 +74,7 @@ in darwin.label = config.system.darwinLabel; darwin.revision = config.system.darwinRevision; darwin.version = config.system.darwinVersion; - darwin.nix.daemon = config.nix.useDaemon; + darwin.nix.daemon = true; darwin.nix.sandbox = config.nix.settings.sandbox; }; }; diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index df3fa310e..ee866a6ff 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -41,8 +41,6 @@ in config = mkIf cfg.enable { - nix.useDaemon = true; - launchd.daemons.nix-daemon = { command = lib.getExe' config.nix.package "nix-daemon"; serviceConfig.ProcessType = config.nix.daemonProcessType; diff --git a/modules/services/nix-gc/default.nix b/modules/services/nix-gc/default.nix index 9fe8e86dd..44278e649 100644 --- a/modules/services/nix-gc/default.nix +++ b/modules/services/nix-gc/default.nix @@ -14,6 +14,7 @@ in (mkRemovedOptionModule [ "nix" "gc" "dates" ] "Use `nix.gc.interval` instead.") (mkRemovedOptionModule [ "nix" "gc" "randomizedDelaySec" ] "No `nix-darwin` equivalent to this NixOS option.") (mkRemovedOptionModule [ "nix" "gc" "persistent" ] "No `nix-darwin` equivalent to this NixOS option.") + (mkRemovedOptionModule [ "nix" "gc" "user" ] "The garbage collection service now always runs as `root`.") ]; ###### interface @@ -28,13 +29,6 @@ in description = "Automatically run the garbage collector at a specific time."; }; - # Not in NixOS module - user = mkOption { - type = types.nullOr types.str; - default = null; - description = "User that runs the garbage collector."; - }; - interval = mkOption { type = launchdTypes.StartCalendarInterval; default = [{ Weekday = 7; Hour = 3; Minute = 15; }]; @@ -66,10 +60,8 @@ in launchd.daemons.nix-gc = { command = "${config.nix.package}/bin/nix-collect-garbage ${cfg.options}"; - environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon"; serviceConfig.RunAtLoad = false; serviceConfig.StartCalendarInterval = cfg.interval; - serviceConfig.UserName = cfg.user; }; }; diff --git a/modules/services/nix-optimise/default.nix b/modules/services/nix-optimise/default.nix index c0ee0a387..4eefc480b 100644 --- a/modules/services/nix-optimise/default.nix +++ b/modules/services/nix-optimise/default.nix @@ -20,6 +20,7 @@ in { imports = [ (mkRemovedOptionModule [ "nix" "optimise" "dates" ] "Use `nix.optimise.interval` instead.") + (mkRemovedOptionModule [ "nix" "optimise" "user" ] "The store optimisation service now always runs as `root`.") ]; ###### interface @@ -34,13 +35,6 @@ in description = "Automatically run the nix store optimiser at a specific time."; }; - # Not in NixOS module - user = mkOption { - type = types.nullOr types.str; - default = null; - description = "User that runs the store optimisation."; - }; - interval = mkOption { type = launchdTypes.StartCalendarInterval; default = [{ Weekday = 7; Hour = 4; Minute = 15; }]; @@ -61,12 +55,10 @@ in config = mkIf cfg.automatic { launchd.daemons.nix-optimise = { - environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon"; command = "${lib.getExe' config.nix.package "nix-store"} --optimise"; serviceConfig = { RunAtLoad = false; StartCalendarInterval = cfg.interval; - UserName = cfg.user; }; }; diff --git a/modules/system/checks.nix b/modules/system/checks.nix index cc8048de4..c3800385c 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -130,24 +130,19 @@ let fi ''; - nixDaemon = if config.nix.useDaemon then '' - if ! dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then - printf >&2 'error: The daemon should not be enabled for single-user installs, aborting activation\n' - printf >&2 'Disable the nix-daemon service:\n' + nixDaemon = '' + if [[ "$(stat --format='%u' /nix)" != 0 ]]; then + printf >&2 'error: single‐user install detected, aborting activation\n' + printf >&2 'nix-darwin now only supports managing multi‐user daemon installations\n' + printf >&2 'of Nix. You can uninstall nix-darwin and Nix and then reinstall both to\n' + printf >&2 'fix this.\n' printf >&2 '\n' - printf >&2 ' services.nix-daemon.enable = false;\n' + printf >&2 'If you don’t want to do that, you can disable management of the Nix\n' + printf >&2 'installation with:\n' printf >&2 '\n' - printf >&2 'and remove `nix.useDaemon` from your configuration if it is present.\n' - printf >&2 '\n' - exit 2 - fi - '' else '' - if dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then - printf >&2 'error: The daemon should be enabled for multi-user installs, aborting activation\n' - printf >&2 'Enable the nix-daemon service:\n' - printf >&2 '\n' - printf >&2 ' services.nix-daemon.enable = true;\n' + printf >&2 ' nix.enable = false;\n' printf >&2 '\n' + printf >&2 'See the `nix.enable` option documentation for caveats.\n' exit 2 fi ''; @@ -214,43 +209,6 @@ let fi ''; - nixStore = '' - if test -w /nix/var/nix/db -a ! -O /nix/store; then - echo >&2 "error: the store is not owned by this user, but /nix/var/nix/db is writable" - echo >&2 "If you are using the daemon:" - echo >&2 - echo >&2 " sudo chown -R root:wheel /nix/var/nix/db" - echo >&2 - echo >&2 "Otherwise:" - echo >&2 - echo >&2 " sudo chown -R $USER:staff /nix/store" - echo >&2 - exit 2 - fi - ''; - - nixGarbageCollector = '' - if test -O /nix/store; then - echo "error: A single-user install can't run gc as root, aborting activation" >&2 - echo "Configure the garbage collector to run as the current user:" >&2 - echo >&2 - echo " nix.gc.user = \"$USER\";" >&2 - echo >&2 - exit 2 - fi - ''; - - nixStoreOptimiser = '' - if test -O /nix/store; then - echo "error: A single-user install can't run optimiser as root, aborting activation" >&2 - echo "Configure the optimiser to run as the current user:" >&2 - echo >&2 - echo " nix.optimise.user = \"$USER\";" >&2 - echo >&2 - exit 2 - fi - ''; - # TODO: Remove this a couple years down the line when we can assume # that anyone who cares about security has upgraded. oldSshAuthorizedKeysDirectory = '' @@ -311,7 +269,7 @@ in type = types.bool; default = config.nix.enable && - ((config.nix.useDaemon && !(config.nix.settings.auto-allocate-uids or false)) + ((!(config.nix.settings.auto-allocate-uids or false)) || config.nix.configureBuildUsers); description = "Whether to run the Nix build users validation checks."; }; @@ -338,9 +296,6 @@ in (mkIf cfg.verifyBuildUsers preSequoiaBuildUsers) (mkIf config.nix.configureBuildUsers buildGroupID) (mkIf config.nix.enable nixDaemon) - nixStore - (mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector) - (mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser) nixInstaller (mkIf cfg.verifyNixPath nixPath) oldSshAuthorizedKeysDirectory diff --git a/release.nix b/release.nix index 52b3c2aa7..115025eed 100644 --- a/release.nix +++ b/release.nix @@ -80,7 +80,6 @@ in { tests.activation-scripts = makeTest ./tests/activation-scripts.nix; tests.autossh = makeTest ./tests/autossh.nix; - tests.checks-nix-gc = makeTest ./tests/checks-nix-gc.nix; tests.environment-path = makeTest ./tests/environment-path.nix; tests.environment-terminfo = makeTest ./tests/environment-terminfo.nix; tests.homebrew = makeTest ./tests/homebrew.nix; diff --git a/tests/checks-nix-gc.nix b/tests/checks-nix-gc.nix deleted file mode 100644 index e3dccd7f6..000000000 --- a/tests/checks-nix-gc.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ config, pkgs, ... }: - -let - nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; -in - -{ - nix.gc.automatic = true; - nix.package = nix; - - test = '' - echo checking nix-gc validation >&2 - grep "nix.gc.user = " ${config.out}/activate-user - - echo checking nix-gc service in /Library/LaunchDaemons >&2 - grep "org.nixos.nix-gc" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist - (! grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist) - ''; -} diff --git a/tests/services-nix-gc.nix b/tests/services-nix-gc.nix index 6d7cdef82..9c8ba8176 100644 --- a/tests/services-nix-gc.nix +++ b/tests/services-nix-gc.nix @@ -7,19 +7,13 @@ in { nix.gc.automatic = true; nix.gc.options = "--delete-older-than 30d"; - nix.gc.user = "nixuser"; nix.package = nix; test = '' echo checking nix-gc service in /Library/LaunchDaemons >&2 grep "org.nixos.nix-gc" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist grep "/bin/wait4path /nix/store && exec ${nix}/bin/nix-collect-garbage --delete-older-than 30d" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist - grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist - grep "nixuser" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist (! grep "KeepAlive" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist) - - echo checking nix-gc validation >&2 - (! grep "nix.gc.user = " ${config.out}/activate-user) ''; } diff --git a/tests/services-nix-optimise.nix b/tests/services-nix-optimise.nix index 4108eb0f2..acdc1dcef 100644 --- a/tests/services-nix-optimise.nix +++ b/tests/services-nix-optimise.nix @@ -6,7 +6,6 @@ in { nix.optimise.automatic = true; - nix.optimise.user = "nixuser"; nix.package = nix; test = '' @@ -15,11 +14,6 @@ in ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist grep "/bin/wait4path /nix/store && exec ${nix}/bin/nix-store --optimise" \ ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist - grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist - grep "nixuser" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist (! grep "KeepAlive" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist) - - echo checking nix-optimise validation >&2 - (! grep "nix.optimise.user = " ${config.out}/activate-user) ''; } From adc989f7ec9efd8bb4e1b6b48c15f4c0f41be018 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 19:30:20 +0000 Subject: [PATCH 06/11] nix: remove `nix.configureBuildUsers` We now manage the build users unconditionally when we manage the Nix installation. --- modules/examples/lnl.nix | 1 - modules/nix/default.nix | 25 +++++++++----------- modules/system/checks.nix | 50 ++++++--------------------------------- 3 files changed, 18 insertions(+), 58 deletions(-) diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index 90142f653..8dff10cc5 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -319,7 +319,6 @@ # path = /etc/per-user/lnl/gitconfig # environment.etc."per-user/lnl/gitconfig".text = builtins.readFile "${inputs.dotfiles}/git/gitconfig"; - nix.configureBuildUsers = true; nix.nrBuildUsers = 32; system.stateVersion = 6; diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 6028e6bb2..b201a692e 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -12,6 +12,8 @@ let isNixAtLeast = versionAtLeast (getVersion nixPackage); + configureBuildUsers = !(config.nix.settings.auto-allocate-uids or false); + makeNixBuildUser = nr: { name = "_nixbld${toString nr}"; value = { @@ -180,6 +182,10 @@ in nix-darwin now only supports managing multi‐user daemon installations of Nix. '') + (mkRemovedOptionModule [ "nix" "configureBuildUsers" ] '' + nix-darwin now manages build users unconditionally when + `nix.enable` is on. + '') ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; ###### interface @@ -397,15 +403,6 @@ in description = "Environment variables used by Nix."; }; - # Not in NixOS module - configureBuildUsers = mkOption { - type = types.bool; - default = false; - description = '' - Enable configuration for nixbld group and users. - ''; - }; - nrBuildUsers = mkOption { type = types.int; description = '' @@ -836,10 +833,10 @@ in nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)); - users.users = mkIf cfg.configureBuildUsers nixbldUsers; + users.users = mkIf configureBuildUsers nixbldUsers; # Not in NixOS module - users.groups.nixbld = mkIf cfg.configureBuildUsers { + users.groups.nixbld = mkIf configureBuildUsers { description = "Nix build group for nix-daemon"; gid = config.ids.gids.nixbld; members = attrNames nixbldUsers; @@ -847,11 +844,11 @@ in users.knownUsers = let nixbldUserNames = attrNames nixbldUsers; in - mkIf cfg.configureBuildUsers (mkMerge [ + mkMerge [ nixbldUserNames (map (removePrefix "_") nixbldUserNames) # delete old style nixbld users - ]); - users.knownGroups = mkIf cfg.configureBuildUsers [ "nixbld" ]; + ]; + users.knownGroups = [ "nixbld" ]; # The Determinate Systems installer puts user‐specified settings in # `/etc/nix/nix.custom.conf` since v0.33.0. Supplement the diff --git a/modules/system/checks.nix b/modules/system/checks.nix index c3800385c..f13f7db93 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -31,29 +31,13 @@ let fi ''; - oldBuildUsers = '' - if dscl . -list /Users | grep -q '^nixbld'; then - echo "error: Detected old style nixbld users, aborting activation" >&2 - echo "These can cause migration problems when upgrading to certain macOS versions" >&2 - echo "You can enable the following option to migrate to new style nixbld users" >&2 - echo >&2 - echo " nix.configureBuildUsers = true;" >&2 - echo >&2 - echo "or disable this check with" >&2 - echo >&2 - echo " system.checks.verifyBuildUsers = false;" >&2 - echo >&2 - exit 2 - fi - ''; - preSequoiaBuildUsers = '' - ${lib.optionalString config.nix.configureBuildUsers '' - # Don’t complain when we’re about to migrate old‐style build users… - if ! dscl . -list /Users | grep -q '^nixbld'; then - ''} firstBuildUserID=$(dscl . -read /Users/_nixbld1 UniqueID | awk '{print $2}') - if [[ $firstBuildUserID != ${toString (config.ids.uids.nixbld + 1)} ]]; then + if + # Don’t complain when we’re about to migrate old‐style build users… + [[ $firstBuildUserID != ${toString (config.ids.uids.nixbld + 1)} ]] \ + && ! dscl . -list /Users | grep -q '^nixbld' + then printf >&2 '\e[1;31merror: Build users have unexpected UIDs, aborting activation\e[0m\n' printf >&2 'The default Nix build user ID range has been adjusted for\n' printf >&2 'compatibility with macOS Sequoia 15. Your _nixbld1 user currently has\n' @@ -86,22 +70,6 @@ let printf >&2 '\n' exit 2 fi - ${lib.optionalString config.nix.configureBuildUsers "fi"} - ''; - - buildUsers = '' - buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true - if [[ -z "$buildUser" ]]; then - echo "error: Using the nix-daemon requires build users, aborting activation" >&2 - echo "Create the build users or disable the daemon:" >&2 - echo "$ darwin-install" >&2 - echo >&2 - echo "or set (this requires some manual intervention to restore permissions)" >&2 - echo >&2 - echo " services.nix-daemon.enable = false;" >&2 - echo >&2 - exit 2 - fi ''; buildGroupID = '' @@ -268,9 +236,7 @@ in system.checks.verifyBuildUsers = mkOption { type = types.bool; default = - config.nix.enable && - ((!(config.nix.settings.auto-allocate-uids or false)) - || config.nix.configureBuildUsers); + config.nix.enable && !(config.nix.settings.auto-allocate-uids or false); description = "Whether to run the Nix build users validation checks."; }; @@ -291,10 +257,8 @@ in system.checks.text = mkMerge [ (mkIf cfg.verifyMacOSVersion macOSVersion) - (mkIf (cfg.verifyBuildUsers && !config.nix.configureBuildUsers) oldBuildUsers) - (mkIf cfg.verifyBuildUsers buildUsers) (mkIf cfg.verifyBuildUsers preSequoiaBuildUsers) - (mkIf config.nix.configureBuildUsers buildGroupID) + (mkIf cfg.verifyBuildUsers buildGroupID) (mkIf config.nix.enable nixDaemon) nixInstaller (mkIf cfg.verifyNixPath nixPath) From 8a94b5b99bfa6aec7846bec63eba93d05f8f44d8 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 19:30:20 +0000 Subject: [PATCH 07/11] nix-daemon: remove `services.nix-daemon.enable` We now manage the launchd daemon unconditionally when we manage the Nix installation. --- modules/services/nix-daemon.nix | 17 +++++++++-------- tests/services-nix-daemon.nix | 1 - tests/sockets-nix-daemon.nix | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index ee866a6ff..404ca0571 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -3,17 +3,18 @@ let cfg = config.services.nix-daemon; - inherit (lib) mkDefault mkIf mkMerge mkOption types; + inherit (lib) mkRemovedOptionModule mkDefault mkIf mkMerge mkOption types; in { - options = { - services.nix-daemon.enable = mkOption { - type = types.bool; - default = config.nix.enable; - description = "Whether to enable the nix-daemon service."; - }; + imports = [ + (mkRemovedOptionModule [ "services" "nix-daemon" "enable" ] '' + nix-darwin now manages nix-daemon unconditionally when + `nix.enable` is on. + '') + ]; + options = { services.nix-daemon.enableSocketListener = mkOption { type = types.bool; default = false; @@ -39,7 +40,7 @@ in }; }; - config = mkIf cfg.enable { + config = mkIf config.nix.enable { launchd.daemons.nix-daemon = { command = lib.getExe' config.nix.package "nix-daemon"; diff --git a/tests/services-nix-daemon.nix b/tests/services-nix-daemon.nix index 86dbd57c4..f8f06e5d9 100644 --- a/tests/services-nix-daemon.nix +++ b/tests/services-nix-daemon.nix @@ -6,7 +6,6 @@ let in { - services.nix-daemon.enable = true; nix.package = nix; launchd.labelPrefix = "org.nix-darwin"; # should not have an effect on nix-daemon diff --git a/tests/sockets-nix-daemon.nix b/tests/sockets-nix-daemon.nix index 606b7b6fd..bafd6c109 100644 --- a/tests/sockets-nix-daemon.nix +++ b/tests/sockets-nix-daemon.nix @@ -5,7 +5,6 @@ let in { - services.nix-daemon.enable = true; services.nix-daemon.enableSocketListener = true; nix.package = nix; launchd.labelPrefix = "org.nix-darwin"; # should not have an effect on nix-daemon From fb2bc03f922d406621928a80b28225340cb2b070 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 28 Jan 2025 18:40:29 +0000 Subject: [PATCH 08/11] activation-scripts: add unmanaged system Nix to activation path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the `bin` directory of the configured system is embedded in the `$PATH` of activation scripts, but not other elements of the default `environment.systemPath` like `/nix/var/nix/profiles/default/bin` or `/usr/local/bin`. This means that when nix-darwin is not managing the Nix installation, activation scripts like Home Manager’s that want to look up the system‐managed Nix can’t find it. Search for it on the entire `environment.systemPath` and add the appropriate directory if found. We leave the launchd `activate-system` daemon alone, because it has erroneously referred to `@out@/sw/bin` forever and therefore never got a Nix on the path to begin with. That’s a problem for another time. (The more ideal solution is probably for Home Manager activation to be driven by launchd or something, but that’s a longer‐term goal.) --- modules/system/activation-scripts.nix | 34 +++++++++++++++++++++++++-- tests/nix-enable.nix | 3 +++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index b95ea3240..341e782e0 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -13,6 +13,32 @@ let mkTextDerivation = name: text: pkgs.writeScript "activate-${name}" text; }; + activationPath = + lib.makeBinPath [ + pkgs.gnugrep + pkgs.coreutils + ] + + lib.optionalString (!config.nix.enable) '' + $( + # If `nix.enable` is off, there might be an unmanaged Nix + # installation (say in `/nix/var/nix/profiles/default`) that + # activation scripts (such as Home Manager) want to find on the + # `$PATH`. Search for it directly to avoid polluting the + # activation script environment with everything on the + # `environment.systemPath`. + if nixEnvPath=$( + PATH="${config.environment.systemPath}" command -v nix-env + ); then + printf ':' + ${lib.getExe' pkgs.coreutils "dirname"} -- "$( + ${lib.getExe' pkgs.coreutils "readlink"} \ + --canonicalize-missing \ + -- "$nixEnvPath" + )" + fi + )'' + + ":@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin"; + in { @@ -40,7 +66,9 @@ in #! ${stdenv.shell} set -e set -o pipefail - export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin" + + PATH="${activationPath}" + export PATH systemConfig=@out@ @@ -86,7 +114,9 @@ in #! ${stdenv.shell} set -e set -o pipefail - export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin" + + PATH="${activationPath}" + export PATH systemConfig=@out@ diff --git a/tests/nix-enable.nix b/tests/nix-enable.nix index 4e7a17822..0828834f1 100644 --- a/tests/nix-enable.nix +++ b/tests/nix-enable.nix @@ -10,5 +10,8 @@ printf >&2 'checking for unexpected nix-daemon plist in /Library/LaunchDaemons\n' [[ -e ${config.out}/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]] && exit 1 + + printf >&2 'checking for late‐bound Nix lookup in /activate\n' + grep nixEnvPath= ${config.out}/activate ''; } From 03877755e9f67e584381ecde74ed2c030639aa0c Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 29 Jan 2025 15:48:54 +0000 Subject: [PATCH 09/11] checks: add check for Determinate This provides a more useful error message than the `/etc/nix/nix.conf` hash mismatch error that would otherwise occur. --- modules/system/checks.nix | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index f13f7db93..9bbaf2c7a 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -31,6 +31,24 @@ let fi ''; + determinate = '' + if [[ -e /usr/local/bin/determinate-nixd ]]; then + printf >&2 '\e[1;31merror: Determinate detected, aborting activation\e[0m\n' + printf >&2 'Determinate uses its own daemon to manage the Nix installation that\n' + printf >&2 'conflicts with nix-darwin’s native Nix management.\n' + printf >&2 '\n' + printf >&2 'To turn off nix-darwin’s management of the Nix installation, set:\n' + printf >&2 '\n' + printf >&2 ' nix.enable = false;\n' + printf >&2 '\n' + printf >&2 'This will allow you to use nix-darwin with Determinate. Some nix-darwin\n' + printf >&2 'functionality that relies on managing the Nix installation, like the\n' + printf >&2 '`nix.*` options to adjust Nix settings or configure a Linux builder,\n' + printf >&2 'will be unavailable.\n' + exit 2 + fi + ''; + preSequoiaBuildUsers = '' firstBuildUserID=$(dscl . -read /Users/_nixbld1 UniqueID | awk '{print $2}') if @@ -257,6 +275,7 @@ in system.checks.text = mkMerge [ (mkIf cfg.verifyMacOSVersion macOSVersion) + (mkIf config.nix.enable determinate) (mkIf cfg.verifyBuildUsers preSequoiaBuildUsers) (mkIf cfg.verifyBuildUsers buildGroupID) (mkIf config.nix.enable nixDaemon) From 00a8cb30fa7d52681f3445de672db95479b83d8c Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 29 Jan 2025 17:38:34 +0000 Subject: [PATCH 10/11] readme: update information about Determinate --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b0f095a1d..1a9900b18 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,19 @@ nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite ## Prerequisites -The only prerequisite is a Nix implementation, both Nix and Lix are supported. +The only prerequisite is a Nix implementation; both Nix and Lix are supported. As the official Nix installer does not include an automated uninstaller, and manual uninstallation on macOS is a complex process, we recommend using one of the following installers instead: -- The [Nix installer from Determinate Systems](https://github.com/DeterminateSystems/nix-installer?tab=readme-ov-file#determinate-nix-installer) is only recommended for use with flake-based setups. **Make sure you use it without the `--determinate` flag**. The `--determinate` flag installs the Determinate Nix distribution which does not work out of the box with nix-darwin. +* The [Nix installer from Determinate Systems](https://github.com/DeterminateSystems/nix-installer?tab=readme-ov-file#determinate-nix-installer) is only recommended for use with flake-based setups. + It can install one of two distributions of Nix: + + * By default, it will install vanilla upstream [Nix](https://nixos.org/) with flakes enabled. + + * When run with the `--determinate` flag, it will install the [Determinate](https://docs.determinate.systems/) distribution. + As Determinate manages the Nix installation itself, you will need to set `nix.enable = false;` in your configuration to disable nix-darwin’s own Nix management. + Some nix-darwin functionality that relies on managing the Nix installation, like the `nix.*` options to adjust Nix settings or configure a Linux builder, will be unavailable. + * The [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system) supports both flake-based and channel-based setups. From a2e44a84be1c6b951d1764a1d44fff37d8fc59f5 Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 29 Jan 2025 21:41:43 +0000 Subject: [PATCH 11/11] changelog: document changes to Nix installation management --- CHANGELOG | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ce1694034..74591effe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,15 @@ +2025-01-29 +- There is now a `nix.enable` toggle to disable management of the Nix + installation. Nix installation management has been made more + opinionated as a consequence; nix-darwin now only supports managing a + multi‐user daemon installation of Nix, and unconditionally takes + ownership of the nix-daemon launchd daemon and the `_nixbld*` build + users when Nix installation management is enabled. + + If the new constraints do not work with your setup, you can disable + the `nix.enable` option to opt out of Nix installation management + entirely; see the option documentation for caveats. + 2025-01-18 - The default configuration path for all new installations is `/etc/nix-darwin`. This was already the undocumented