From b2dff2033d72b7e9ed9a3a135327fead70c61b08 Mon Sep 17 00:00:00 2001 From: Francesc Esplugas <2720+fesplugas@users.noreply.github.com> Date: Mon, 16 Oct 2023 23:31:15 +0200 Subject: [PATCH 001/139] fix: initdb missing data area directory Use `PGDATA` environment variable instead of `-D` to maintain consistency with NixOS module. Co-Authored-By: Michael Hoang --- modules/services/postgresql/default.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/services/postgresql/default.nix b/modules/services/postgresql/default.nix index 018b46eb..64a2ecec 100644 --- a/modules/services/postgresql/default.nix +++ b/modules/services/postgresql/default.nix @@ -237,10 +237,10 @@ in for an overview of `postgresql.conf`. ::: {.note} - + String values will automatically be enclosed in single quotes. Single quotes will be escaped with two single quotes as described by the upstream documentation linked above. - + ::: ''; example = literalExpression '' @@ -355,11 +355,14 @@ in "${cfg.dataDir}/recovery.conf" ''} - exec ${postgresql}/bin/postgres -D ${cfg.dataDir} + exec ${postgresql}/bin/postgres ''; serviceConfig.KeepAlive = true; serviceConfig.RunAtLoad = true; + serviceConfig.EnvironmentVariables = { + PGDATA = cfg.dataDir; + }; }; }; From 2839ef54aaaa0ca797659a1db45876260b93b1eb Mon Sep 17 00:00:00 2001 From: Trevor Opiyo Date: Wed, 20 Mar 2024 20:12:46 -0500 Subject: [PATCH 002/139] Add support for zsh-fast-syntax-highlighting --- modules/programs/zsh/default.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index bbf8ad9e..c7ff47c4 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -107,6 +107,12 @@ in default = false; description = "Enable zsh-syntax-highlighting."; }; + + programs.zsh.enableFastSyntaxHighlighting = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Enable zsh-fast-syntax-highlighting."; + }; }; config = mkIf cfg.enable { @@ -115,7 +121,8 @@ in [ # Include zsh package pkgs.zsh ] ++ optional cfg.enableCompletion pkgs.nix-zsh-completions - ++ optional cfg.enableSyntaxHighlighting pkgs.zsh-syntax-highlighting; + ++ optional cfg.enableSyntaxHighlighting pkgs.zsh-syntax-highlighting + ++ optional cfg.enableFastSyntaxHighlighting pkgs.zsh-fast-syntax-highlighting; environment.pathsToLink = [ "/share/zsh" ]; @@ -196,6 +203,10 @@ in "source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" } + ${optionalString cfg.enableFastSyntaxHighlighting + "source ${pkgs.zsh-fast-syntax-highlighting}/share/zsh-fast-syntax-highlighting/zsh-fast-syntax-highlighting.zsh" + } + ${optionalString cfg.enableFzfCompletion "source ${fzfCompletion}"} ${optionalString cfg.enableFzfGit "source ${fzfGit}"} ${optionalString cfg.enableFzfHistory "source ${fzfHistory}"} From 44c88484c4c386f3eae8a5398e9b22a78d606e43 Mon Sep 17 00:00:00 2001 From: Trevor Opiyo Date: Wed, 29 May 2024 12:23:59 -0500 Subject: [PATCH 003/139] add warning for enabling syntax highlighting and fast syntax highlighting --- modules/programs/zsh/default.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index c7ff47c4..d3b2f5c6 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -117,6 +117,9 @@ in config = mkIf cfg.enable { + warnings = mkIf (cfg.enableFastSyntaxHighlighting && cfg.enableSyntaxHighlighting) [ + "zsh-fast-syntax-highlighting and zsh-syntax-highlighting are mutually exclusive. Disable one of them." + ]; environment.systemPackages = [ # Include zsh package pkgs.zsh From 4054d5caea22367763a8cc7781d5723e86e3d1fb Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Tue, 2 Jul 2024 09:40:18 -0700 Subject: [PATCH 004/139] Use the correct file location for `SoftwareUpdate` plist. --- modules/system/defaults-write.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index 7e1fc443..c3e2683b 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -14,7 +14,7 @@ let alf = defaultsToList "/Library/Preferences/com.apple.alf" cfg.alf; loginwindow = defaultsToList "/Library/Preferences/com.apple.loginwindow" cfg.loginwindow; smb = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.smb.server" cfg.smb; - SoftwareUpdate = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.SoftwareUpdate" cfg.SoftwareUpdate; + SoftwareUpdate = defaultsToList "/Library/Preferences/com.apple.SoftwareUpdate" cfg.SoftwareUpdate; # userDefaults GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences"; From c9fd4820d5e33422d2a9311898e098ba492dbd34 Mon Sep 17 00:00:00 2001 From: isabel Date: Mon, 30 Sep 2024 16:30:50 +0100 Subject: [PATCH 005/139] programs/bash: move to completion.* a port of https://github.com/NixOS/nixpkgs/pull/291552 for darwin --- modules/examples/hydra.nix | 2 +- modules/examples/lnl.nix | 2 +- modules/nix/default.nix | 2 +- modules/programs/bash/default.nix | 30 +++++++++++++++++++----------- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/modules/examples/hydra.nix b/modules/examples/hydra.nix index 15808d92..31604985 100644 --- a/modules/examples/hydra.nix +++ b/modules/examples/hydra.nix @@ -12,7 +12,7 @@ in { # Create /etc/bashrc that loads the nix-darwin environment. programs.bash.enable = true; - programs.bash.enableCompletion = false; + programs.bash.completion.enable = false; # Recreate /run/current-system symlink after boot. services.activate-system.enable = true; diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index 96954d22..010dff5a 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -199,7 +199,7 @@ # Dotfiles. # programs.vim.package = mkForce pkgs.lnl.vim; - programs.bash.enableCompletion = true; + programs.bash.completion.enable = true; programs.zsh.enable = true; programs.zsh.enableBashCompletion = true; diff --git a/modules/nix/default.nix b/modules/nix/default.nix index b91521a7..6bce1e35 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -686,7 +686,7 @@ in nixPackage pkgs.nix-info ] - ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions; + ++ optional (config.programs.bash.completion.enable) pkgs.nix-bash-completions; environment.etc."nix/nix.conf".source = nixConf; diff --git a/modules/programs/bash/default.nix b/modules/programs/bash/default.nix index 3abb3e84..2518c9c5 100644 --- a/modules/programs/bash/default.nix +++ b/modules/programs/bash/default.nix @@ -7,6 +7,10 @@ let in { + imports = [ + (mkRenamedOptionModule [ "programs" "bash" "enableCompletion" ] [ "programs" "bash" "completion" "enable" ]) + ]; + options = { programs.bash.enable = mkOption { @@ -21,14 +25,18 @@ in type = types.lines; }; - programs.bash.enableCompletion = mkOption { - type = types.bool; - default = false; - description = '' - Enable bash completion for all interactive bash shells. + programs.bash.completion = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable bash completion for all interactive bash shells. - NOTE. This doesn't work with bash 3.2, which is the default on macOS. - ''; + NOTE: This doesn't work with bash 3.2, which is installed by default on macOS by Apple. + ''; + }; + + package = mkPackageOption pkgs "bash-completion" { }; }; }; @@ -38,9 +46,9 @@ in environment.systemPackages = [ # Include bash package pkgs.bashInteractive - ] ++ optional cfg.enableCompletion pkgs.bash-completion; + ] ++ optional cfg.completion.enable cfg.completion.package; - environment.pathsToLink = + environment.pathsToLink = optionals cfg.completion.enable [ "/etc/bash_completion.d" "/share/bash-completion/completions" ]; @@ -70,9 +78,9 @@ in ${config.environment.interactiveShellInit} ${cfg.interactiveShellInit} - ${optionalString cfg.enableCompletion '' + ${optionalString cfg.completion.enable '' if [ "$TERM" != "dumb" ]; then - source "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" + source "${cfg.completion.package}/etc/profile.d/bash_completion.sh" nullglobStatus=$(shopt -p nullglob) shopt -s nullglob From d32e6de094e87ba8eeef0be8c5696f7b14365af2 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Wed, 9 Oct 2024 21:57:33 +1100 Subject: [PATCH 006/139] defaults: don't output Dock PID --- modules/system/defaults-write.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index 827a7d31..c109767d 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -113,7 +113,7 @@ in ${optionalString (length dock > 0) '' # Only restart Dock if current user is logged in - if pgrep -xu $UID Dock; then + if pgrep -xu $UID Dock >/dev/null; then echo >&2 "restarting Dock..." killall Dock || true fi From 6347a9dcd1e43b9a5d43b837cfa4ca0073c2eb0e Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 14 Oct 2024 17:18:08 +1100 Subject: [PATCH 007/139] skhd: add `skhd` to `PATH` --- modules/services/skhd/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/skhd/default.nix b/modules/services/skhd/default.nix index 72b52d4b..1f5d0cf6 100644 --- a/modules/services/skhd/default.nix +++ b/modules/services/skhd/default.nix @@ -29,6 +29,7 @@ in }; config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; environment.etc."skhdrc".text = cfg.skhdConfig; From 72e93853c2d16d1ce04a5e8eee6695e2493ca80d Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Sun, 13 Oct 2024 12:52:55 +0100 Subject: [PATCH 008/139] module: add aerospace service --- modules/module-list.nix | 1 + modules/services/aerospace/default.nix | 156 +++++++++++++++++++++++++ release.nix | 1 + tests/services-aerospace.nix | 36 ++++++ 4 files changed, 194 insertions(+) create mode 100644 modules/services/aerospace/default.nix create mode 100644 tests/services-aerospace.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 3280682c..6604eb92 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -52,6 +52,7 @@ ./fonts ./launchd ./services/activate-system + ./services/aerospace ./services/autossh.nix ./services/buildkite-agents.nix ./services/chunkwm.nix diff --git a/modules/services/aerospace/default.nix b/modules/services/aerospace/default.nix new file mode 100644 index 00000000..efbe9a14 --- /dev/null +++ b/modules/services/aerospace/default.nix @@ -0,0 +1,156 @@ +{ + config, + lib, + pkgs, + ... +}: + +with lib; + +let + cfg = config.services.aerospace; + + format = pkgs.formats.toml { }; + configFile = format.generate "aerospace.toml" cfg.settings; +in + +{ + options = with types; { + services.aerospace = { + enable = mkEnableOption "AeroSpace window manager"; + + package = mkOption { + type = types.path; + default = pkgs.aerospace; + description = "The AeroSpace package to use."; + }; + + settings = mkOption { + type = submodule { + freeformType = format.type; + options = { + start-at-login = mkOption { + type = addCheck bool (b: !false || !cfg.enable); + default = false; + description = "Do not start AeroSpace at login. (Managed by launchd instead)"; + }; + after-login-command = mkOption { + type = addCheck (listOf str) (l: l == [ ] || !cfg.enable); + default = [ ]; + description = "Do not use AeroSpace to run commands after login. (Managed by launchd instead)"; + }; + after-startup-command = mkOption { + type = addCheck (listOf str) (l: l == [ ] || !cfg.enable); + default = [ ]; + description = "Do not use AeroSpace to run commands after startup. (Managed by launchd instead)"; + }; + enable-normalization-flatten-containers = mkOption { + type = bool; + default = true; + description = "Containers that have only one child are \"flattened\"."; + }; + enable-normalization-opposite-orientation-for-nested-containers = mkOption { + type = bool; + default = true; + description = "Containers that nest into each other must have opposite orientations."; + }; + accordion-padding = mkOption { + type = int; + default = 30; + description = "Padding between windows in an accordion container."; + }; + default-root-container-layout = mkOption { + type = enum [ + "tiles" + "accordion" + ]; + default = "tiles"; + description = "Default layout for the root container."; + }; + default-root-container-orientation = mkOption { + type = enum [ + "horizontal" + "vertical" + "auto" + ]; + default = "auto"; + description = "Default orientation for the root container."; + }; + on-window-detected = mkOption { + type = listOf str; + default = [ ]; + description = "Commands to run every time a new window is detected."; + }; + on-focus-changed = mkOption { + type = listOf str; + default = [ ]; + description = "Commands to run every time focused window or workspace changes."; + }; + on-focused-monitor-changed = mkOption { + type = listOf str; + default = [ "move-mouse monitor-lazy-center" ]; + description = "Commands to run every time focused monitor changes."; + }; + exec-on-workspace-change = mkOption { + type = listOf str; + default = [ ]; + example = [ + "/bin/bash" + "-c" + "sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE" + ]; + description = "Commands to run every time workspace changes."; + }; + key-mapping.preset = mkOption { + type = enum [ + "qwerty" + "dvorak" + ]; + default = "qwerty"; + description = "Keymapping preset."; + }; + }; + }; + default = { }; + example = literalExpression '' + { + gaps = { + outer.left = 8; + outer.bottom = 8; + outer.top = 8; + outer.right = 8; + }; + mode.main.binding = { + alt-h = "focus left"; + alt-j = "focus down"; + alt-k = "focus up"; + alt-l = "focus right"; + }; + } + ''; + description = '' + AeroSpace configuration, see + + for supported values. + ''; + }; + }; + }; + + config = mkMerge [ + (mkIf (cfg.enable) { + environment.systemPackages = [ cfg.package ]; + + launchd.user.agents.aerospace.serviceConfig = { + ProgramArguments = + [ "${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" ] + ++ optionals (cfg.settings != { }) [ + "--config-path" + "${configFile}" + ]; + KeepAlive = true; + RunAtLoad = true; + }; + }) + ]; +} diff --git a/release.nix b/release.nix index ac0e31a6..0d754fc0 100644 --- a/release.nix +++ b/release.nix @@ -129,6 +129,7 @@ let tests.services-lorri = makeTest ./tests/services-lorri.nix; tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix; tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix; + tests.services-aerospace = makeTest ./tests/services-aerospace.nix; tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix; tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix; tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix; diff --git a/tests/services-aerospace.nix b/tests/services-aerospace.nix new file mode 100644 index 00000000..7656cafd --- /dev/null +++ b/tests/services-aerospace.nix @@ -0,0 +1,36 @@ +{ config, pkgs, ... }: + +let + aerospace = pkgs.runCommand "aerospace-0.0.0" { } "mkdir $out"; +in + +{ + services.aerospace.enable = true; + services.aerospace.package = aerospace; + services.aerospace.settings = { + gaps = { + outer.left = 8; + outer.bottom = 8; + outer.top = 8; + outer.right = 8; + }; + mode.main.binding = { + alt-h = "focus left"; + alt-j = "focus down"; + alt-k = "focus up"; + alt-l = "focus right"; + }; + }; + + test = '' + echo >&2 "checking aerospace service in ~/Library/LaunchAgents" + grep "org.nixos.aerospace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist + grep "${aerospace}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist + + conf=`sed -En '/--config-path<\/string>/{n; s/\s+?<\/?string>//g; p;}' \ + ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist` + + echo >&2 "checking config in $conf" + if [ `cat $conf | wc -l` -eq "27" ]; then echo "aerospace.toml config correctly contains 27 lines"; else return 1; fi + ''; +} From 7ebf95a73e3b54e0f9c48f50fde29e96257417ac Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Thu, 17 Oct 2024 23:30:31 +0100 Subject: [PATCH 009/139] style fixes --- modules/services/aerospace/default.nix | 89 ++++++++++++++------------ tests/services-aerospace.nix | 2 +- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/modules/services/aerospace/default.nix b/modules/services/aerospace/default.nix index efbe9a14..50d47b3b 100644 --- a/modules/services/aerospace/default.nix +++ b/modules/services/aerospace/default.nix @@ -5,8 +5,6 @@ ... }: -with lib; - let cfg = config.services.aerospace; @@ -15,51 +13,47 @@ let in { - options = with types; { - services.aerospace = { - enable = mkEnableOption "AeroSpace window manager"; + options = { + services.aerospace = with lib.types; { + enable = lib.mkEnableOption "AeroSpace window manager"; - package = mkOption { - type = types.path; - default = pkgs.aerospace; - description = "The AeroSpace package to use."; - }; + package = lib.mkPackageOption pkgs "aerospace" { }; - settings = mkOption { + settings = lib.mkOption { type = submodule { freeformType = format.type; options = { - start-at-login = mkOption { - type = addCheck bool (b: !false || !cfg.enable); + start-at-login = lib.mkOption { + type = bool; default = false; description = "Do not start AeroSpace at login. (Managed by launchd instead)"; }; - after-login-command = mkOption { - type = addCheck (listOf str) (l: l == [ ] || !cfg.enable); + after-login-command = lib.mkOption { + type = listOf str; default = [ ]; description = "Do not use AeroSpace to run commands after login. (Managed by launchd instead)"; }; - after-startup-command = mkOption { - type = addCheck (listOf str) (l: l == [ ] || !cfg.enable); + after-startup-command = lib.mkOption { + type = listOf str; default = [ ]; description = "Do not use AeroSpace to run commands after startup. (Managed by launchd instead)"; }; - enable-normalization-flatten-containers = mkOption { + enable-normalization-flatten-containers = lib.mkOption { type = bool; default = true; description = "Containers that have only one child are \"flattened\"."; }; - enable-normalization-opposite-orientation-for-nested-containers = mkOption { + enable-normalization-opposite-orientation-for-nested-containers = lib.mkOption { type = bool; default = true; description = "Containers that nest into each other must have opposite orientations."; }; - accordion-padding = mkOption { + accordion-padding = lib.mkOption { type = int; default = 30; description = "Padding between windows in an accordion container."; }; - default-root-container-layout = mkOption { + default-root-container-layout = lib.mkOption { type = enum [ "tiles" "accordion" @@ -67,7 +61,7 @@ in default = "tiles"; description = "Default layout for the root container."; }; - default-root-container-orientation = mkOption { + default-root-container-orientation = lib.mkOption { type = enum [ "horizontal" "vertical" @@ -76,22 +70,22 @@ in default = "auto"; description = "Default orientation for the root container."; }; - on-window-detected = mkOption { + on-window-detected = lib.mkOption { type = listOf str; default = [ ]; description = "Commands to run every time a new window is detected."; }; - on-focus-changed = mkOption { + on-focus-changed = lib.mkOption { type = listOf str; default = [ ]; description = "Commands to run every time focused window or workspace changes."; }; - on-focused-monitor-changed = mkOption { + on-focused-monitor-changed = lib.mkOption { type = listOf str; default = [ "move-mouse monitor-lazy-center" ]; description = "Commands to run every time focused monitor changes."; }; - exec-on-workspace-change = mkOption { + exec-on-workspace-change = lib.mkOption { type = listOf str; default = [ ]; example = [ @@ -101,7 +95,7 @@ in ]; description = "Commands to run every time workspace changes."; }; - key-mapping.preset = mkOption { + key-mapping.preset = lib.mkOption { type = enum [ "qwerty" "dvorak" @@ -112,7 +106,7 @@ in }; }; default = { }; - example = literalExpression '' + example = lib.literalExpression '' { gaps = { outer.left = 8; @@ -137,20 +131,33 @@ in }; }; - config = mkMerge [ - (mkIf (cfg.enable) { + config = ( + lib.mkIf (cfg.enable) { + assertions = [ + { + assertion = !cfg.settings.start-at-login; + message = "AeroSpace started at login is managed by home-manager and launchd instead of itself via this option."; + } + { + assertion = cfg.settings.after-login-command == [ ]; + message = "AeroSpace will not run these commands as it does not start itself."; + } + { + assertion = cfg.settings.after-startup-command == [ ]; + message = "AeroSpace will not run these commands as it does not start itself."; + } + ]; environment.systemPackages = [ cfg.package ]; - launchd.user.agents.aerospace.serviceConfig = { - ProgramArguments = - [ "${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" ] - ++ optionals (cfg.settings != { }) [ - "--config-path" - "${configFile}" - ]; - KeepAlive = true; - RunAtLoad = true; + launchd.user.agents.aerospace = { + command = + "${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" + + (lib.optionalString (cfg.settings != { }) " --config-path ${configFile}"); + serviceConfig = { + KeepAlive = true; + RunAtLoad = true; + }; }; - }) - ]; + } + ); } diff --git a/tests/services-aerospace.nix b/tests/services-aerospace.nix index 7656cafd..8cbd292f 100644 --- a/tests/services-aerospace.nix +++ b/tests/services-aerospace.nix @@ -27,7 +27,7 @@ in grep "org.nixos.aerospace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist grep "${aerospace}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist - conf=`sed -En '/--config-path<\/string>/{n; s/\s+?<\/?string>//g; p;}' \ + conf=`sed -En 's/^[[:space:]]*.*--config-path (.*)<\/string>$/\1/p' \ ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist` echo >&2 "checking config in $conf" From 8724129dc862432dc5e5c548f1af48f38c4368c4 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 14:07:25 +1100 Subject: [PATCH 010/139] ci: don't run tests twice for PRs from forks By only triggering on pushes to `master`, when users push to non-`master` branches on forks, this workflow won't get triggered and will only get triggered when users make a PR to the main repo. --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6583817f..f375aa8d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,8 @@ name: "Test" on: pull_request: push: + branches: + - master env: CURRENT_STABLE_CHANNEL: nixpkgs-24.05-darwin From cbb190eccbc01f9b492fab11185a9cd729562ec6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 14:48:39 +1100 Subject: [PATCH 011/139] ci: update Nix to match versions in nixpkgs --- .github/workflows/test.yml | 38 ++++++++++++----------------- .github/workflows/update-manual.yml | 2 +- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6583817f..feec41d2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,13 +12,10 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v3 - # We use the Determinate Systems installer for 2.18 because the - # Sequoia UID/GID changes have not yet been backported to the - # official installer for that version. - name: Install nix corresponding to latest stable channel - uses: DeterminateSystems/nix-installer-action@main + uses: cachix/install-nix-action@v30 with: - nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz + install_url: https://releases.nixos.org/nix/nix-2.18.8/install - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A manpages - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple @@ -29,9 +26,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 with: - install_url: https://releases.nixos.org/nix/nix-2.24.6/install + install_url: https://releases.nixos.org/nix/nix-2.24.9/install - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A manpages - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple @@ -41,20 +38,18 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v3 - # We use the Determinate Systems installer for 2.18 because the - # Sequoia UID/GID changes have not yet been backported to the - # official installer for that version. - name: Install nix corresponding to latest stable channel - uses: DeterminateSystems/nix-installer-action@main + uses: cachix/install-nix-action@v30 with: - nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz + install_url: https://releases.nixos.org/nix/nix-2.18.8/install + nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} - name: Install ${{ env.CURRENT_STABLE_CHANNEL }} channel run: | nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs nix-channel --update - name: Install nix-darwin and test run: | - export NIX_PATH=nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} + export NIX_PATH=$HOME/.nix-defexpr/channels # We run nix-darwin twice to test that it can create darwin-configuration correctly for us # but we expect it to fail setting up /etc/nix/nix.conf @@ -89,9 +84,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 with: - install_url: https://releases.nixos.org/nix/nix-2.24.6/install + install_url: https://releases.nixos.org/nix/nix-2.24.9/install nix_path: nixpkgs=channel:nixpkgs-unstable - name: Install nixpkgs-unstable channel run: | @@ -133,13 +128,10 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v3 - # We use the Determinate Systems installer for 2.18 because the - # Sequoia UID/GID changes have not yet been backported to the - # official installer for that version. - - name: Install nix corresponding to latest stable channel - uses: DeterminateSystems/nix-installer-action@main + - name: Install nix version corresponding to latest stable channel + uses: cachix/install-nix-action@v30 with: - nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz + install_url: https://releases.nixos.org/nix/nix-2.18.8/install - name: Install nix-darwin run: | mkdir -p ~/.config/nix-darwin @@ -220,9 +212,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 with: - install_url: https://releases.nixos.org/nix/nix-2.24.6/install + install_url: https://releases.nixos.org/nix/nix-2.24.9/install - name: Install nix-darwin run: | mkdir -p ~/.config/nix-darwin diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index c66244d8..4bd5a0b2 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -17,7 +17,7 @@ jobs: fetch-depth: 0 - name: Install Nix - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 - name: Build manual run: | From 2788e4fa981566e34fa40938705cd7f595f05e74 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Mon, 17 Jun 2024 11:56:58 -0700 Subject: [PATCH 012/139] Use `sysadminctl` instead of `dscl` Co-authored-by: Michael Hoang --- modules/users/default.nix | 23 +++++++++++----------- tests/users-groups.nix | 40 ++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index cd0986d8..ead996c3 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -147,28 +147,28 @@ in ${concatMapStringsSep "\n" (v: '' ${optionalString cfg.forceRecreate '' - u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true - u=''${u#UniqueID: } + u=$(id -u '${v.name}' 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 - dscl . -delete '/Users/${v.name}' 2> /dev/null + sysadminctl -deleteUser '${v.name}' 2> /dev/null else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 fi ''} - u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true - u=''${u#UniqueID: } + u=$(id -u '${v.name}' 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 else if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - dscl . -create '/Users/${v.name}' UniqueID ${toString v.uid} - dscl . -create '/Users/${v.name}' PrimaryGroupID ${toString v.gid} + sysadminctl -addUser '${v.name}' \ + -UID ${toString v.uid} \ + -GID ${toString v.gid} \ + -fullName '${v.description}' \ + -home '${v.home}' \ + -shell ${lib.escapeShellArg (shellPath v.shell)} dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"} - dscl . -create '/Users/${v.name}' RealName '${v.description}' - dscl . -create '/Users/${v.name}' NFSHomeDirectory '${v.home}' ${optionalString v.createHome "createhomedir -cu '${v.name}'"} fi # Always set the shell path, in case it was updated @@ -177,12 +177,11 @@ in '') createdUsers} ${concatMapStringsSep "\n" (name: '' - u=$(dscl . -read '/Users/${name}' UniqueID 2> /dev/null) || true - u=''${u#UniqueID: } + u=$(id -u '${name}' 2> /dev/null) || true if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 - dscl . -delete '/Users/${name}' 2> /dev/null + sysadminctl -deleteUser '${name}' 2> /dev/null else echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2 fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index feaaf2bd..b619f9b4 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -22,13 +22,15 @@ users.users."unknown.user".uid = 42002; test = '' - echo "checking group creation in /activate" >&2 + set -v + + # checking group creation in /activate grep "dscl . -create '/Groups/foo' PrimaryGroupID 42000" ${config.out}/activate grep "dscl . -create '/Groups/foo' RealName 'Foo group'" ${config.out}/activate grep "dscl . -create '/Groups/created.group' PrimaryGroupID 42001" ${config.out}/activate grep -qv "dscl . -delete '/Groups/created.group'" ${config.out}/activate - echo "checking group deletion in /activate" >&2 + # checking group deletion in /activate grep "dscl . -delete '/Groups/deleted.group'" ${config.out}/activate grep -qv "dscl . -create '/Groups/deleted.group'" ${config.out}/activate @@ -36,28 +38,28 @@ grep "dscl . -create '/Groups/foo' GroupMembership 'admin' 'foo'" ${config.out}/activate grep "dscl . -create '/Groups/created.group' GroupMembership" ${config.out}/activate - echo "checking unknown group in /activate" >&2 + # checking unknown group in /activate grep -qv "dscl . -create '/Groups/unknown.group'" ${config.out}/activate grep -qv "dscl . -delete '/Groups/unknown.group'" ${config.out}/activate - echo "checking user creation in /activate" >&2 - grep "dscl . -create '/Users/foo' UniqueID 42000" ${config.out}/activate - grep "dscl . -create '/Users/foo' PrimaryGroupID 42000" ${config.out}/activate - grep "dscl . -create '/Users/foo' IsHidden 0" ${config.out}/activate - grep "dscl . -create '/Users/foo' RealName 'Foo user'" ${config.out}/activate - grep "dscl . -create '/Users/foo' NFSHomeDirectory '/Users/foo'" ${config.out}/activate - grep "dscl . -create '/Users/foo' UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate - grep "dscl . -create '/Users/created.user' UniqueID 42001" ${config.out}/activate - grep "dscl . -create '/Users/created.user' UserShell ${lib.escapeShellArg "/sbin/nologin"}" ${config.out}/activate + # checking user creation in /activate + grep -zoP "sysadminctl -addUser 'foo' (.|\n)* -UID 42000 (.|\n)* -GID 42000 (.|\n)* -fullName 'Foo user' (.|\n)* -home '/Users/foo' (.|\n)* -shell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate grep "createhomedir -cu 'foo'" ${config.out}/activate - grep -qv "dscl . -delete '/Groups/created.user'" ${config.out}/activate + grep -zoP "sysadminctl -addUser 'created.user' (.|\n)* -UID 42001 (.|\n)* -shell ${lib.escapeShellArg "/sbin/nologin"}" ${config.out}/activate + grep -qv "sysadminctl -deleteUser 'created.user'" ${config.out}/activate + grep -qv "sysadminctl -deleteUser 'created.user'" ${config.out}/activate - echo "checking user deletion in /activate" >&2 - grep "dscl . -delete '/Users/deleted.user'" ${config.out}/activate - grep -qv "dscl . -create '/Users/deleted.user'" ${config.out}/activate + # checking user properties always get updated in /activate + grep "dscl . -create '/Users/foo' UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate - echo "checking unknown user in /activate" >&2 - grep -qv "dscl . -create '/Users/unknown.user'" ${config.out}/activate - grep -qv "dscl . -delete '/Users/unknown.user'" ${config.out}/activate + # checking user deletion in /activate + grep "sysadminctl -deleteUser 'deleted.user'" ${config.out}/activate + grep -qv "sysadminctl -addUser 'deleted.user'" ${config.out}/activate + + # checking unknown user in /activate + grep -qv "sysadminctl -addUser 'unknown.user'" ${config.out}/activate + grep -qv "sysadminctl -deleteUser 'unknown.user'" ${config.out}/activate + + set +v ''; } From 5b873c48ace1ee08186d88288cf4f565202c0f28 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 19 Oct 2024 16:13:33 +1100 Subject: [PATCH 013/139] users: set `default` for `users.users..name` --- modules/users/group.nix | 13 ++++--------- modules/users/user.nix | 13 ++++--------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/modules/users/group.nix b/modules/users/group.nix index 0e74085d..da3feb1b 100644 --- a/modules/users/group.nix +++ b/modules/users/group.nix @@ -1,11 +1,12 @@ { name, lib, ... }: -with lib; - { - options = { + options = let + inherit (lib) mkOption types; + in { name = mkOption { type = types.str; + default = name; description = '' The group's name. If undefined, the name of the attribute set will be used. @@ -29,10 +30,4 @@ with lib; description = "The group's description."; }; }; - - config = { - - name = mkDefault name; - - }; } diff --git a/modules/users/user.nix b/modules/users/user.nix index 4e3f1c94..363c3004 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -1,11 +1,12 @@ { name, lib, ... }: -with lib; - { - options = { + options = let + inherit (lib) literalExpression mkOption types; + in { name = mkOption { type = types.str; + default = name; description = '' The name of the user account. If undefined, the name of the attribute set will be used. @@ -75,10 +76,4 @@ with lib; ''; }; }; - - config = { - - name = mkDefault name; - - }; } From 9a6b12b9ef35cf4ac4970f94791b3dd734c0da96 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 06:58:23 +1100 Subject: [PATCH 014/139] users: use `lib.escapeShellArg` for `id -u` --- modules/users/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index ead996c3..ffceb9b9 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -147,7 +147,7 @@ in ${concatMapStringsSep "\n" (v: '' ${optionalString cfg.forceRecreate '' - u=$(id -u '${v.name}' 2> /dev/null) || true + u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 sysadminctl -deleteUser '${v.name}' 2> /dev/null @@ -156,7 +156,7 @@ in fi ''} - u=$(id -u '${v.name}' 2> /dev/null) || true + u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 else @@ -177,7 +177,7 @@ in '') createdUsers} ${concatMapStringsSep "\n" (name: '' - u=$(id -u '${name}' 2> /dev/null) || true + u=$(id -u ${lib.escapeShellArg name} 2> /dev/null) || true if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 From cb2e5fa6c5d99c581f9669e66e61ac1585ab56ad Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 07:05:10 +1100 Subject: [PATCH 015/139] users: use `lib.escapeShellArg` for `sysadminctl -deleteUser` --- modules/users/default.nix | 4 ++-- tests/users-groups.nix | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index ffceb9b9..83a60846 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -150,7 +150,7 @@ in u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 - sysadminctl -deleteUser '${v.name}' 2> /dev/null + sysadminctl -deleteUser ${lib.escapeShellArg v.name} 2> /dev/null else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 fi @@ -181,7 +181,7 @@ in if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 - sysadminctl -deleteUser '${name}' 2> /dev/null + sysadminctl -deleteUser ${lib.escapeShellArg name} 2> /dev/null else echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2 fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index b619f9b4..a4aaf2ae 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -46,19 +46,19 @@ grep -zoP "sysadminctl -addUser 'foo' (.|\n)* -UID 42000 (.|\n)* -GID 42000 (.|\n)* -fullName 'Foo user' (.|\n)* -home '/Users/foo' (.|\n)* -shell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate grep "createhomedir -cu 'foo'" ${config.out}/activate grep -zoP "sysadminctl -addUser 'created.user' (.|\n)* -UID 42001 (.|\n)* -shell ${lib.escapeShellArg "/sbin/nologin"}" ${config.out}/activate - grep -qv "sysadminctl -deleteUser 'created.user'" ${config.out}/activate - grep -qv "sysadminctl -deleteUser 'created.user'" ${config.out}/activate + grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate + grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate # checking user properties always get updated in /activate grep "dscl . -create '/Users/foo' UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate # checking user deletion in /activate - grep "sysadminctl -deleteUser 'deleted.user'" ${config.out}/activate + grep "sysadminctl -deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate grep -qv "sysadminctl -addUser 'deleted.user'" ${config.out}/activate # checking unknown user in /activate grep -qv "sysadminctl -addUser 'unknown.user'" ${config.out}/activate - grep -qv "sysadminctl -deleteUser 'unknown.user'" ${config.out}/activate + grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate set +v ''; From 26f7e45fb117171c9e8b27a34cfccb91ef50f068 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 09:29:56 +1100 Subject: [PATCH 016/139] users: use `lib.escapeShellArgs` for `sysadminctl -addUser` --- modules/users/default.nix | 7 +------ tests/users-groups.nix | 8 ++++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 83a60846..f43b1392 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -162,12 +162,7 @@ in else if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - sysadminctl -addUser '${v.name}' \ - -UID ${toString v.uid} \ - -GID ${toString v.gid} \ - -fullName '${v.description}' \ - -home '${v.home}' \ - -shell ${lib.escapeShellArg (shellPath v.shell)} + sysadminctl -addUser ${lib.escapeShellArgs [ v.name "-UID" v.uid "-GID" v.gid "-fullName" v.description "-home" v.home "-shell" (shellPath v.shell) ]} dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"} ${optionalString v.createHome "createhomedir -cu '${v.name}'"} fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index a4aaf2ae..bdbabe1e 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -43,9 +43,9 @@ grep -qv "dscl . -delete '/Groups/unknown.group'" ${config.out}/activate # checking user creation in /activate - grep -zoP "sysadminctl -addUser 'foo' (.|\n)* -UID 42000 (.|\n)* -GID 42000 (.|\n)* -fullName 'Foo user' (.|\n)* -home '/Users/foo' (.|\n)* -shell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate + grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu 'foo'" ${config.out}/activate - grep -zoP "sysadminctl -addUser 'created.user' (.|\n)* -UID 42001 (.|\n)* -shell ${lib.escapeShellArg "/sbin/nologin"}" ${config.out}/activate + grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate @@ -54,10 +54,10 @@ # checking user deletion in /activate grep "sysadminctl -deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate - grep -qv "sysadminctl -addUser 'deleted.user'" ${config.out}/activate + grep -qv "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate # checking unknown user in /activate - grep -qv "sysadminctl -addUser 'unknown.user'" ${config.out}/activate + grep -qv "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate set +v From 7bb6366f40dd4ef6efe3223e6dffb3dd7f8dea66 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 09:43:19 +1100 Subject: [PATCH 017/139] users: use `lib.escapeShellArgs` instead of custom version --- modules/users/default.nix | 3 +-- tests/users-groups.nix | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index f43b1392..90e55344 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -8,7 +8,6 @@ let group = import ./group.nix; user = import ./user.nix; - toArguments = concatMapStringsSep " " (v: "'${v}'"); toGID = v: { "${toString v.gid}" = v.name; }; toUID = v: { "${toString v.uid}" = v.name; }; @@ -121,7 +120,7 @@ in g=$(dscl . -read '/Groups/${v.name}' GroupMembership 2> /dev/null) || true if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then echo "updating group members ${v.name}..." >&2 - dscl . -create '/Groups/${v.name}' GroupMembership ${toArguments v.members} + dscl . -create '/Groups/${v.name}' GroupMembership ${lib.escapeShellArgs v.members} fi else echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 diff --git a/tests/users-groups.nix b/tests/users-groups.nix index bdbabe1e..17b8c0d2 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -35,7 +35,7 @@ grep -qv "dscl . -create '/Groups/deleted.group'" ${config.out}/activate echo "checking group membership in /activate" >&2 - grep "dscl . -create '/Groups/foo' GroupMembership 'admin' 'foo'" ${config.out}/activate + grep "dscl . -create '/Groups/foo' GroupMembership ${lib.escapeShellArgs [ "admin" "foo" ]}" ${config.out}/activate grep "dscl . -create '/Groups/created.group' GroupMembership" ${config.out}/activate # checking unknown group in /activate From 7a3ec6459c4394767ebcc136c0da0bb0c73d76ed Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 09:34:25 +1100 Subject: [PATCH 018/139] networking: use `lib.escapeShellArgs` instead of custom version --- modules/networking/default.nix | 9 ++++----- tests/networking-networkservices.nix | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/networking/default.nix b/modules/networking/default.nix index 1065c268..099c705e 100644 --- a/modules/networking/default.nix +++ b/modules/networking/default.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, ... }: with lib; @@ -8,15 +8,14 @@ let hostnameRegEx = ''^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$''; emptyList = lst: if lst != [] then lst else ["empty"]; - quoteStrings = concatMapStringsSep " " (str: "'${str}'"); setNetworkServices = optionalString (cfg.knownNetworkServices != []) '' networkservices=$(networksetup -listallnetworkservices) ${concatMapStringsSep "\n" (srv: '' case "$networkservices" in - *'${srv}'*) - networksetup -setdnsservers '${srv}' ${quoteStrings (emptyList cfg.dns)} - networksetup -setsearchdomains '${srv}' ${quoteStrings (emptyList cfg.search)} + *${lib.escapeShellArg srv}*) + networksetup -setdnsservers ${lib.escapeShellArgs ([ srv ] ++ (emptyList cfg.dns))} + networksetup -setsearchdomains ${lib.escapeShellArgs ([ srv ] ++ (emptyList cfg.search))} ;; esac '') cfg.knownNetworkServices} diff --git a/tests/networking-networkservices.nix b/tests/networking-networkservices.nix index 46213175..a6573424 100644 --- a/tests/networking-networkservices.nix +++ b/tests/networking-networkservices.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, lib, ... }: { networking.knownNetworkServices = [ "Wi-Fi" "Thunderbolt Ethernet" ]; @@ -6,10 +6,10 @@ test = '' echo checking dns settings in /activate >&2 - grep "networksetup -setdnsservers 'Wi-Fi' '8.8.8.8' '8.8.4.4'" ${config.out}/activate - grep "networksetup -setdnsservers 'Thunderbolt Ethernet' '8.8.8.8' '8.8.4.4'" ${config.out}/activate + grep "networksetup -setdnsservers ${lib.escapeShellArgs [ "Wi-Fi" "8.8.8.8" "8.8.4.4" ]}" ${config.out}/activate + grep "networksetup -setdnsservers ${lib.escapeShellArgs [ "Thunderbolt Ethernet" "8.8.8.8" "8.8.4.4" ]}" ${config.out}/activate echo checking empty searchdomain settings in /activate >&2 - grep "networksetup -setsearchdomains 'Wi-Fi' 'empty'" ${config.out}/activate - grep "networksetup -setsearchdomains 'Thunderbolt Ethernet' 'empty'" ${config.out}/activate + grep "networksetup -setsearchdomains ${lib.escapeShellArgs [ "Wi-Fi" "empty" ]}" ${config.out}/activate + grep "networksetup -setsearchdomains ${lib.escapeShellArgs [ "Thunderbolt Ethernet" "empty" ]}" ${config.out}/activate ''; } From 8451125cf8eab07056da090a4616ce46a1952ff9 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 10:08:41 +1100 Subject: [PATCH 019/139] users: use `lib.escapeShellArg` for `dscl` paths --- modules/users/default.nix | 34 ++++++++++++++++++++-------------- tests/users-groups.nix | 22 +++++++++++----------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 90e55344..f57dfa56 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -95,45 +95,49 @@ in system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) '' echo "setting up groups..." >&2 - ${concatMapStringsSep "\n" (v: '' + ${concatMapStringsSep "\n" (v: let + dsclGroup = lib.escapeShellArg "/Groups/${v.name}"; + in '' ${optionalString cfg.forceRecreate '' - g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true + g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [[ "$g" -eq ${toString v.gid} ]]; then echo "deleting group ${v.name}..." >&2 - dscl . -delete '/Groups/${v.name}' 2> /dev/null + dscl . -delete ${dsclGroup} 2> /dev/null else echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 fi ''} - g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true + g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [ -z "$g" ]; then echo "creating group ${v.name}..." >&2 - dscl . -create '/Groups/${v.name}' PrimaryGroupID ${toString v.gid} - dscl . -create '/Groups/${v.name}' RealName '${v.description}' + dscl . -create ${dsclGroup} PrimaryGroupID ${toString v.gid} + dscl . -create ${dsclGroup} RealName '${v.description}' g=${toString v.gid} fi if [ "$g" -eq ${toString v.gid} ]; then - g=$(dscl . -read '/Groups/${v.name}' GroupMembership 2> /dev/null) || true + g=$(dscl . -read ${dsclGroup} GroupMembership 2> /dev/null) || true if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then echo "updating group members ${v.name}..." >&2 - dscl . -create '/Groups/${v.name}' GroupMembership ${lib.escapeShellArgs v.members} + dscl . -create ${dsclGroup} GroupMembership ${lib.escapeShellArgs v.members} fi else echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 fi '') createdGroups} - ${concatMapStringsSep "\n" (name: '' - g=$(dscl . -read '/Groups/${name}' PrimaryGroupID 2> /dev/null) || true + ${concatMapStringsSep "\n" (name: let + dsclGroup = lib.escapeShellArg "/Groups/${name}"; + in '' + g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [ -n "$g" ]; then if [ "$g" -gt 501 ]; then echo "deleting group ${name}..." >&2 - dscl . -delete '/Groups/${name}' 2> /dev/null + dscl . -delete ${dsclGroup} 2> /dev/null else echo "warning: existing group '${name}' has unexpected gid $g, skipping..." >&2 fi @@ -144,7 +148,9 @@ in system.activationScripts.users.text = mkIf (cfg.knownUsers != []) '' echo "setting up users..." >&2 - ${concatMapStringsSep "\n" (v: '' + ${concatMapStringsSep "\n" (v: let + dsclUser = lib.escapeShellArg "/Users/${v.name}"; + in '' ${optionalString cfg.forceRecreate '' u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then @@ -162,11 +168,11 @@ in if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 sysadminctl -addUser ${lib.escapeShellArgs [ v.name "-UID" v.uid "-GID" v.gid "-fullName" v.description "-home" v.home "-shell" (shellPath v.shell) ]} - dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"} + dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} ${optionalString v.createHome "createhomedir -cu '${v.name}'"} fi # Always set the shell path, in case it was updated - dscl . -create '/Users/${v.name}' UserShell ${lib.escapeShellArg (shellPath v.shell)} + dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)} fi '') createdUsers} diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 17b8c0d2..72c6e0c1 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -25,22 +25,22 @@ set -v # checking group creation in /activate - grep "dscl . -create '/Groups/foo' PrimaryGroupID 42000" ${config.out}/activate - grep "dscl . -create '/Groups/foo' RealName 'Foo group'" ${config.out}/activate - grep "dscl . -create '/Groups/created.group' PrimaryGroupID 42001" ${config.out}/activate - grep -qv "dscl . -delete '/Groups/created.group'" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} PrimaryGroupID 42000" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} RealName 'Foo group'" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} PrimaryGroupID 42001" ${config.out}/activate + grep -qv "dscl . -delete ${lib.escapeShellArg "/Groups/created.group"}" ${config.out}/activate # checking group deletion in /activate - grep "dscl . -delete '/Groups/deleted.group'" ${config.out}/activate - grep -qv "dscl . -create '/Groups/deleted.group'" ${config.out}/activate + grep "dscl . -delete ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate + grep -qv "dscl . -create ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate echo "checking group membership in /activate" >&2 - grep "dscl . -create '/Groups/foo' GroupMembership ${lib.escapeShellArgs [ "admin" "foo" ]}" ${config.out}/activate - grep "dscl . -create '/Groups/created.group' GroupMembership" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} GroupMembership ${lib.escapeShellArgs [ "admin" "foo" ]}" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} GroupMembership" ${config.out}/activate # checking unknown group in /activate - grep -qv "dscl . -create '/Groups/unknown.group'" ${config.out}/activate - grep -qv "dscl . -delete '/Groups/unknown.group'" ${config.out}/activate + grep -qv "dscl . -create ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate + grep -qv "dscl . -delete ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate # checking user creation in /activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate @@ -50,7 +50,7 @@ grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate # checking user properties always get updated in /activate - grep "dscl . -create '/Users/foo' UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate # checking user deletion in /activate grep "sysadminctl -deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate From ea7e178ad4113c2134c5b734e3198ebbc591af0b Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 10:20:43 +1100 Subject: [PATCH 020/139] users: use `lib.escapeShellArg` for `createhomedir` --- modules/users/default.nix | 9 +++++---- tests/users-groups.nix | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index f57dfa56..08785be8 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -149,19 +149,20 @@ in echo "setting up users..." >&2 ${concatMapStringsSep "\n" (v: let + name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; in '' ${optionalString cfg.forceRecreate '' - u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true + u=$(id -u ${name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 - sysadminctl -deleteUser ${lib.escapeShellArg v.name} 2> /dev/null + sysadminctl -deleteUser ${name} 2> /dev/null else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 fi ''} - u=$(id -u ${lib.escapeShellArg v.name} 2> /dev/null) || true + u=$(id -u ${name} 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 else @@ -169,7 +170,7 @@ in echo "creating user ${v.name}..." >&2 sysadminctl -addUser ${lib.escapeShellArgs [ v.name "-UID" v.uid "-GID" v.gid "-fullName" v.description "-home" v.home "-shell" (shellPath v.shell) ]} dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} - ${optionalString v.createHome "createhomedir -cu '${v.name}'"} + ${optionalString v.createHome "createhomedir -cu ${name}"} fi # Always set the shell path, in case it was updated dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)} diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 72c6e0c1..87babb3a 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -44,7 +44,7 @@ # checking user creation in /activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate - grep "createhomedir -cu 'foo'" ${config.out}/activate + grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate From ac7932f9de36b8126abcb9d4966d5d95fcadd807 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 10:24:06 +1100 Subject: [PATCH 021/139] users: use `lib.escapeShellArg` for group description --- modules/users/default.nix | 2 +- tests/users-groups.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 08785be8..9f906b32 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -114,7 +114,7 @@ in if [ -z "$g" ]; then echo "creating group ${v.name}..." >&2 dscl . -create ${dsclGroup} PrimaryGroupID ${toString v.gid} - dscl . -create ${dsclGroup} RealName '${v.description}' + dscl . -create ${dsclGroup} RealName ${lib.escapeShellArg v.description} g=${toString v.gid} fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 87babb3a..d15909b3 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -26,7 +26,7 @@ # checking group creation in /activate grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} PrimaryGroupID 42000" ${config.out}/activate - grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} RealName 'Foo group'" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} RealName ${lib.escapeShellArg "Foo group"}" ${config.out}/activate grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} PrimaryGroupID 42001" ${config.out}/activate grep -qv "dscl . -delete ${lib.escapeShellArg "/Groups/created.group"}" ${config.out}/activate From 11c777c7198f4cfcd55fe81646e503c58ceb9f4a Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 10:24:06 +1100 Subject: [PATCH 022/139] users: change default `description` to `null` --- modules/users/default.nix | 2 +- modules/users/user.nix | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 9f906b32..e9e3ac4a 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -168,7 +168,7 @@ in else if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - sysadminctl -addUser ${lib.escapeShellArgs [ v.name "-UID" v.uid "-GID" v.gid "-fullName" v.description "-home" v.home "-shell" (shellPath v.shell) ]} + sysadminctl -addUser ${lib.escapeShellArgs ([ v.name "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) ++ [ "-home" v.home "-shell" (shellPath v.shell) ])} dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} ${optionalString v.createHome "createhomedir -cu ${name}"} fi diff --git a/modules/users/user.nix b/modules/users/user.nix index 363c3004..1a8e877f 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -14,12 +14,18 @@ }; description = mkOption { - type = types.str; - default = ""; + type = types.nullOr types.nonEmptyStr; + default = null; example = "Alice Q. User"; description = '' A short description of the user account, typically the user's full name. + + This defaults to `null` which means, on creation, `sysadminctl` + will pick the description which is usually always {option}`name`. + + Using an empty name is not supported and breaks macOS like + making the user not appear in Directory Utility. ''; }; From 0a686597faa81831e027505b149dd77b2524ab18 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 19:49:13 +1100 Subject: [PATCH 023/139] users: don't allow `name` to be empty --- modules/users/user.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/user.nix b/modules/users/user.nix index 1a8e877f..a0c8aab5 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -5,7 +5,7 @@ inherit (lib) literalExpression mkOption types; in { name = mkOption { - type = types.str; + type = types.nonEmptyStr; default = name; description = '' The name of the user account. If undefined, the name of the From 9ee30f253432d3a059411d28aa05638a92ea8c71 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 23:57:13 +1100 Subject: [PATCH 024/139] darwin-rebuild: add comments explaining the custom `sudo` logic --- pkgs/nix-tools/darwin-rebuild.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index aa066865..c0ea55b7 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -18,7 +18,11 @@ showSyntax() { } sudo() { + # REMOVEME when support for macOS 10.13 is dropped + # macOS 10.13 does not support sudo --preserve-env so we make this conditional if command sudo --help | grep -- --preserve-env= >/dev/null; then + # We use `env` before our command to ensure the preserved PATH gets checked + # when trying to resolve the command to execute command sudo -H --preserve-env=PATH env "$@" else command sudo -H "$@" From 8c02940d702170feea7947f768aa807c11b65a41 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 22 Oct 2024 22:38:17 +1100 Subject: [PATCH 025/139] users: ensure Full Disk Access is granted before trying to delete users --- modules/users/default.nix | 40 ++++++++++++++++++++++++++++++-- pkgs/nix-tools/darwin-rebuild.sh | 2 +- tests/users-groups.nix | 8 +++---- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index e9e3ac4a..ce77d4d9 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -148,6 +148,42 @@ in system.activationScripts.users.text = mkIf (cfg.knownUsers != []) '' echo "setting up users..." >&2 + deleteUser() { + fullDiskAccess=false + + if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then + fullDiskAccess=true + fi + + if [[ "$fullDiskAccess" != true ]]; then + printf >&2 '\e[1;31merror: users cannot be deleted without Full Disk Access, aborting activation\e[0m\n' + printf >&2 'The user %s could not be deleted as `darwin-rebuild` was not executed with Full Disk Access.' "$1" + + printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' + printf >&2 '\n' + # This command will fail if run as root and System Settings is already running + # even if System Settings was launched by root. + sudo -u $SUDO_USER open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles" + + if [[ -n "$SSH_CONNECTION" ]]; then + printf >&2 'Please enable Full Disk Access for programs over SSH by flipping\n' + printf >&2 'the switch for `sshd-keygen-wrapper`.\n' + else + printf >&2 'Please enable Full Disk Access for your terminal emulator by flipping\n' + printf >&2 'the switch in System Settings.\n' + fi + + exit 1 + fi + + sysadminctl -deleteUser "$1" 2> /dev/null + + if id -u "$1" > /dev/null 2>&1; then + printf >&2 '\e[1;31merror: failed to delete user %s, aborting activation\e[0m\n', "$1" + exit 1 + fi + } + ${concatMapStringsSep "\n" (v: let name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; @@ -156,7 +192,7 @@ in u=$(id -u ${name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 - sysadminctl -deleteUser ${name} 2> /dev/null + deleteUser ${name} else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 fi @@ -182,7 +218,7 @@ in if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 - sysadminctl -deleteUser ${lib.escapeShellArg name} 2> /dev/null + deleteUser ${lib.escapeShellArg name} else echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2 fi diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index c0ea55b7..325cf501 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -23,7 +23,7 @@ sudo() { if command sudo --help | grep -- --preserve-env= >/dev/null; then # We use `env` before our command to ensure the preserved PATH gets checked # when trying to resolve the command to execute - command sudo -H --preserve-env=PATH env "$@" + command sudo -H --preserve-env=PATH --preserve-env=SSH_CONNECTION env "$@" else command sudo -H "$@" fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index d15909b3..7df92ba8 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -46,19 +46,19 @@ grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate - grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate - grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate + grep -qv "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate + grep -qv "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate # checking user properties always get updated in /activate grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate # checking user deletion in /activate - grep "sysadminctl -deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate + grep "deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate grep -qv "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate # checking unknown user in /activate grep -qv "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate - grep -qv "sysadminctl -deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate + grep -qv "deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate set +v ''; From bbe1917238b3ea22890e5aa3fe51ed6910ee9429 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 14:14:15 +1100 Subject: [PATCH 026/139] users: ensure users' shells are installed --- modules/users/default.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/users/default.nix b/modules/users/default.nix index ce77d4d9..e4be46af 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -31,6 +31,12 @@ let then "/run/current-system/sw${v.shellPath}" else v; + systemShells = + let + shells = mapAttrsToList (_: u: u.shell) cfg.users; + in + filter types.shellPackage.check shells; + in { @@ -226,6 +232,9 @@ in '') deletedUsers} ''; + # Install all the user shells + environment.systemPackages = systemShells; + environment.etc = mapAttrs' (name: { packages, ... }: { name = "profiles/per-user/${name}"; value.source = pkgs.buildEnv { From 467a0d3d0c27ed7e688c040281aced98d37120d2 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 02:00:15 +1100 Subject: [PATCH 027/139] users: prevent deleting the user calling `darwin-rebuild` `sysadminctl -deleteUser` will only prevent you from deleting the current user if it's not the last admin and not the last secure token user, otherwise it will happily oblige. --- modules/users/default.nix | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index ce77d4d9..e8a030b4 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -149,6 +149,15 @@ in echo "setting up users..." >&2 deleteUser() { + # TODO: add `darwin.primaryUser` as well + if [[ "$1" == "$SUDO_USER" ]]; then + printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" + exit 1 + elif [[ "$1" == "root" ]]; then + printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n', "$1" + exit 1 + fi + fullDiskAccess=false if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then @@ -191,8 +200,15 @@ in ${optionalString cfg.forceRecreate '' u=$(id -u ${name} 2> /dev/null) || true if [[ "$u" -eq ${toString v.uid} ]]; then - echo "deleting user ${v.name}..." >&2 - deleteUser ${name} + # TODO: add `darwin.primaryUser` as well + if [[ ${name} == "$SUDO_USER" ]]; then + printf >&2 'warning: not going to recreate the user calling `darwin-rebuild` (%s), skipping...\n' "$SUDO_USER" + elif [[ ${name} == "root" ]]; then + printf >&2 'warning: not going to recreate root, skipping...\n' + else + printf >&2 'deleting user ${v.name}...\n' + deleteUser ${name} + fi else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 fi From 2be05de06ed8e634c839ad58ffb895d5bed98c0a Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 12:44:45 +1100 Subject: [PATCH 028/139] users: add missing newlines for FDA prompt --- modules/users/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index e8a030b4..1d7127aa 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -166,8 +166,8 @@ in if [[ "$fullDiskAccess" != true ]]; then printf >&2 '\e[1;31merror: users cannot be deleted without Full Disk Access, aborting activation\e[0m\n' - printf >&2 'The user %s could not be deleted as `darwin-rebuild` was not executed with Full Disk Access.' "$1" - + printf >&2 'The user %s could not be deleted as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" + printf >&2 '\n' printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' printf >&2 '\n' # This command will fail if run as root and System Settings is already running From b702750226a86abb029440641bfa994ff650cf99 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 13:13:52 +1100 Subject: [PATCH 029/139] users: ensure Full Disk Access is granted before trying to create users --- modules/users/default.nix | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 1d7127aa..9227080d 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -148,16 +148,7 @@ in system.activationScripts.users.text = mkIf (cfg.knownUsers != []) '' echo "setting up users..." >&2 - deleteUser() { - # TODO: add `darwin.primaryUser` as well - if [[ "$1" == "$SUDO_USER" ]]; then - printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" - exit 1 - elif [[ "$1" == "root" ]]; then - printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n', "$1" - exit 1 - fi - + requireFDA() { fullDiskAccess=false if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then @@ -165,8 +156,8 @@ in fi if [[ "$fullDiskAccess" != true ]]; then - printf >&2 '\e[1;31merror: users cannot be deleted without Full Disk Access, aborting activation\e[0m\n' - printf >&2 'The user %s could not be deleted as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" + printf >&2 '\e[1;31merror: users cannot be %s without Full Disk Access, aborting activation\e[0m\n' "$2" + printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" "$2" printf >&2 '\n' printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' printf >&2 '\n' @@ -184,10 +175,24 @@ in exit 1 fi + } + + deleteUser() { + # FIXME: add `darwin.primaryUser` as well + if [[ "$1" == "$SUDO_USER" ]]; then + printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" + exit 1 + elif [[ "$1" == "root" ]]; then + printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n', "$1" + exit 1 + fi + + requireFDA "$1" deleted sysadminctl -deleteUser "$1" 2> /dev/null - if id -u "$1" > /dev/null 2>&1; then + # We need to check as `sysadminctl -deleteUser` still exits with exit code 0 when there's an error + if id "$1" &> /dev/null; then printf >&2 '\e[1;31merror: failed to delete user %s, aborting activation\e[0m\n', "$1" exit 1 fi @@ -220,7 +225,17 @@ in else if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - sysadminctl -addUser ${lib.escapeShellArgs ([ v.name "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) ++ [ "-home" v.home "-shell" (shellPath v.shell) ])} + + requireFDA ${name} "created" + + sysadminctl -addUser ${lib.escapeShellArgs ([ v.name "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) ++ [ "-home" v.home "-shell" (shellPath v.shell) ])} 2> /dev/null + + # We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error + if ! id ${name} &> /dev/null; then + printf >&2 '\e[1;31merror: failed to create user %s, aborting activation\e[0m\n' ${name} + exit 1 + fi + dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} ${optionalString v.createHome "createhomedir -cu ${name}"} fi From 5907cbbb31d9de387349efb825864a9ee598e6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20B=C3=B8rgesen?= Date: Sat, 18 Nov 2023 14:18:06 +0100 Subject: [PATCH 030/139] networking: Add wakeOnLan option --- modules/networking/default.nix | 16 ++++++++++++++++ tests/networking-wakeonlan.nix | 10 ++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/networking-wakeonlan.nix diff --git a/modules/networking/default.nix b/modules/networking/default.nix index 099c705e..b53a9e4a 100644 --- a/modules/networking/default.nix +++ b/modules/networking/default.nix @@ -9,6 +9,8 @@ let emptyList = lst: if lst != [] then lst else ["empty"]; + onOff = cond: if cond then "on" else "off"; + setNetworkServices = optionalString (cfg.knownNetworkServices != []) '' networkservices=$(networksetup -listallnetworkservices) ${concatMapStringsSep "\n" (srv: '' @@ -93,6 +95,16 @@ in default = []; description = "The list of search paths used when resolving domain names."; }; + + networking.wakeOnLan.enable = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Enable Wake-on-LAN for the device. + + Battery powered devices may require being connected to power. + ''; + }; }; config = { @@ -116,6 +128,10 @@ in ''} ${setNetworkServices} + + ${optionalString (cfg.wakeOnLan.enable != null) '' + systemsetup -setWakeOnNetworkAccess '${onOff cfg.wakeOnLan.enable}' &> /dev/null + ''} ''; }; diff --git a/tests/networking-wakeonlan.nix b/tests/networking-wakeonlan.nix new file mode 100644 index 00000000..745c39c9 --- /dev/null +++ b/tests/networking-wakeonlan.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + networking.wakeOnLan.enable = true; + + test = '' + echo checking wake on network access settings in /activate >&2 + grep "systemsetup -setWakeOnNetworkAccess 'on'" ${config.out}/activate + ''; +} From f737259769ef4722ed956bcaaab67509b96c23cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20B=C3=B8rgesen?= Date: Sun, 19 Nov 2023 00:52:02 +0100 Subject: [PATCH 031/139] power,sleep: Add options to control restart and sleep behavior --- modules/module-list.nix | 2 + modules/power/default.nix | 47 ++++++++++++++++ modules/power/sleep.nix | 80 +++++++++++++++++++++++++++ modules/system/activation-scripts.nix | 1 + tests/power-restart.nix | 12 ++++ tests/power-sleep.nix | 16 ++++++ 6 files changed, 158 insertions(+) create mode 100644 modules/power/default.nix create mode 100644 modules/power/sleep.nix create mode 100644 tests/power-restart.nix create mode 100644 tests/power-sleep.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 6604eb92..effdff76 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -51,6 +51,8 @@ ./environment ./fonts ./launchd + ./power + ./power/sleep.nix ./services/activate-system ./services/aerospace ./services/autossh.nix diff --git a/modules/power/default.nix b/modules/power/default.nix new file mode 100644 index 00000000..a99905ff --- /dev/null +++ b/modules/power/default.nix @@ -0,0 +1,47 @@ +{ config, lib, ... }: + +let + cfg = config.power; + + types = lib.types; + + onOff = cond: if cond then "on" else "off"; +in + +{ + options = { + power.restartAfterPowerFailure = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to restart the computer after a power failure. + ''; + }; + + power.restartAfterFreeze = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to restart the computer after a system freeze. + ''; + }; + }; + + config = { + + system.activationScripts.power.text = '' + echo "configuring power..." >&2 + + ${lib.optionalString (cfg.restartAfterPowerFailure != null) '' + systemsetup -setRestartPowerFailure \ + '${onOff cfg.restartAfterPowerFailure}' &> /dev/null + ''} + + ${lib.optionalString (cfg.restartAfterFreeze != null) '' + systemsetup -setRestartFreeze \ + '${onOff cfg.restartAfterFreeze}' &> /dev/null + ''} + ''; + + }; +} diff --git a/modules/power/sleep.nix b/modules/power/sleep.nix new file mode 100644 index 00000000..ab5862cf --- /dev/null +++ b/modules/power/sleep.nix @@ -0,0 +1,80 @@ +{ config, lib, ... }: + +let + cfg = config.power.sleep; + + types = lib.types; + + onOff = cond: if cond then "on" else "off"; +in + +{ + options = { + power.sleep.computer = lib.mkOption { + type = types.nullOr (types.either types.ints.positive (types.enum ["never"])); + default = null; + example = "never"; + description = '' + Amount of idle time (in minutes) until the computer sleeps. + + `"never"` disables computer sleeping. + + The system might not be considered idle before connected displays sleep, as + per the `power.sleep.display` option. + ''; + }; + + power.sleep.display = lib.mkOption { + type = types.nullOr (types.either types.ints.positive (types.enum ["never"])); + default = null; + example = "never"; + description = '' + Amount of idle time (in minutes) until displays sleep. + + `"never"` disables display sleeping. + ''; + }; + + power.sleep.harddisk = lib.mkOption { + type = types.nullOr (types.either types.ints.positive (types.enum ["never"])); + default = null; + example = "never"; + description = '' + Amount of idle time (in minutes) until hard disks sleep. + + `"never"` disables hard disk sleeping. + ''; + }; + + power.sleep.allowSleepByPowerButton = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether the power button can sleep the computer. + ''; + }; + }; + + config = { + + system.activationScripts.power.text = lib.mkAfter '' + ${lib.optionalString (cfg.computer != null) '' + systemsetup -setComputerSleep '${toString cfg.computer}' &> /dev/null + ''} + + ${lib.optionalString (cfg.display != null) '' + systemsetup -setDisplaySleep '${toString cfg.display}' &> /dev/null + ''} + + ${lib.optionalString (cfg.harddisk != null) '' + systemsetup -setHardDiskSleep '${toString cfg.harddisk}' &> /dev/null + ''} + + ${lib.optionalString (cfg.allowSleepByPowerButton != null) '' + systemsetup -setAllowPowerButtonToSleepComputer \ + '${onOff cfg.allowSleepByPowerButton}' &> /dev/null + ''} + ''; + + }; +} diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index 83251998..da8eb5c9 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -67,6 +67,7 @@ in ${cfg.activationScripts.nix-daemon.text} ${cfg.activationScripts.time.text} ${cfg.activationScripts.networking.text} + ${cfg.activationScripts.power.text} ${cfg.activationScripts.keyboard.text} ${cfg.activationScripts.fonts.text} ${cfg.activationScripts.nvram.text} diff --git a/tests/power-restart.nix b/tests/power-restart.nix new file mode 100644 index 00000000..ade98514 --- /dev/null +++ b/tests/power-restart.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + power.restartAfterPowerFailure = true; + power.restartAfterFreeze = true; + + test = '' + echo checking restart power settings in /activate >&2 + grep "systemsetup -setRestartPowerFailure 'on'" ${config.out}/activate + grep "systemsetup -setRestartFreeze 'on'" ${config.out}/activate + ''; +} diff --git a/tests/power-sleep.nix b/tests/power-sleep.nix new file mode 100644 index 00000000..5d779a60 --- /dev/null +++ b/tests/power-sleep.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + power.sleep.computer = "never"; + power.sleep.display = 15; + power.sleep.harddisk = 5; + power.sleep.allowSleepByPowerButton = false; + + test = '' + echo checking power sleep settings in /activate >&2 + grep "systemsetup -setComputerSleep 'never'" ${config.out}/activate + grep "systemsetup -setDisplaySleep '15'" ${config.out}/activate + grep "systemsetup -setHardDiskSleep '5'" ${config.out}/activate + grep "systemsetup -setAllowPowerButtonToSleepComputer 'off'" ${config.out}/activate + ''; +} From b089e7e7266403ddda9f96bfd8c5adf9a0f0f6b5 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 18:30:55 +1100 Subject: [PATCH 032/139] users: switch back to using `dscl` for deleting users The previous default behaviour when nix-darwin deletes users is that their home directories are left intact, however as the `-keepHome` flag for `sysadminctl -deleteUser` is broken, we'll need to switch back for now. --- modules/users/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 9227080d..0cb43503 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -189,8 +189,10 @@ in requireFDA "$1" deleted - sysadminctl -deleteUser "$1" 2> /dev/null + dscl . -delete "/Users/$1" 2> /dev/null + # `dscl . -delete` should exit with a non-zero exit code when there's an error, but we'll leave + # this code here just in case and for when we switch to `sysadminctl -deleteUser` # We need to check as `sysadminctl -deleteUser` still exits with exit code 0 when there's an error if id "$1" &> /dev/null; then printf >&2 '\e[1;31merror: failed to delete user %s, aborting activation\e[0m\n', "$1" From c98bb238b16ba2cfc8eb9d5d5a18b79f8caacf25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20B=C3=B8rgesen?= Date: Tue, 22 Oct 2024 23:10:34 +0200 Subject: [PATCH 033/139] darwin-rebuild: Align usage description with implementation This change updates the usage description of darwin-rebuild.sh as follows: * Add options: --print-build-logs / -L --no-registries --commit-lock-file --no-write-lock-file --override-input * Specify that --no-flake and the flake related options are mutually exclusive. * Specify that --keep-going and -k are aliases. * Specify that --keep-failed and -K are aliases. * Correct the description of --update-input; only one value follows. The --no-build-hook argument remains undocumented, like for nix. --- pkgs/nix-tools/darwin-rebuild.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index aa066865..1967272f 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -9,11 +9,15 @@ showSyntax() { echo " [--list-generations] [{--profile-name | -p} name] [--rollback]" >&2 echo " [{--switch-generation | -G} generation] [--verbose...] [-v...]" >&2 echo " [-Q] [{--max-jobs | -j} number] [--cores number] [--dry-run]" >&2 - echo " [--keep-going] [-k] [--keep-failed] [-K] [--fallback] [--show-trace]" >&2 - echo " [-I path] [--option name value] [--arg name value] [--argstr name value]" >&2 - echo " [--flake flake] [--no-flake] [--update-input input flake] [--impure]" >&2 - echo " [--recreate-lock-file] [--no-update-lock-file] [--refresh]" >&2 - echo " [--offline] [--substituters substituters-list] ..." >&2 + echo " [--keep-going | -k] [--keep-failed | -K] [--fallback] [--show-trace]" >&2 + echo " [--print-build-logs | -L] [--impure] [-I path]" >&2 + echo " [--option name value] [--arg name value] [--argstr name value]" >&2 + echo " [--no-flake | [--flake flake]" >&2 + echo " [--commit-lock-file] [--recreate-lock-file]" >&2 + echo " [--no-update-lock-file] [--no-write-lock-file]" >&2 + echo " [--override-input input flake] [--update-input input]" >&2 + echo " [--no-registries] [--offline] [--refresh]]" >&2 + echo " [--substituters substituters-list] ..." >&2 exit 1 } From 445c6bfc65b4f9df882d6bb089d46014204f8523 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Sat, 26 Oct 2024 12:08:45 -0400 Subject: [PATCH 034/139] Add keepalive flag for emacs service --- modules/services/emacs.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/services/emacs.nix b/modules/services/emacs.nix index 4b9a3cb0..ec98950b 100644 --- a/modules/services/emacs.nix +++ b/modules/services/emacs.nix @@ -44,9 +44,11 @@ in { launchd.user.agents.emacs = { path = cfg.additionalPath ++ [ config.environment.systemPath ]; - serviceConfig.ProgramArguments = - [ "${cfg.package}/bin/${cfg.exec}" "--fg-daemon" ]; - serviceConfig.RunAtLoad = true; + serviceConfig = { + ProgramArguments = [ "${cfg.package}/bin/${cfg.exec}" "--fg-daemon" ]; + RunAtLoad = true; + KeepAlive = true; + }; }; }; From fd6660cb9182fde5e593246e311dc3c2dd4b9d13 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 23:55:25 +1100 Subject: [PATCH 035/139] tests: fix negative asserts with `grep` not working Using `grep -v` without `-z` will return 0 even if there is a match found as all the non-matching lines will be matched. Instead of using `grep -vqz`, `(! grep ...)` is more readable. The brackets are necessary as `! grep` will not trigger `set -e`[0], so we run it inside a subshell to use its non-zero exit code. [0]: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin --- pkgs/darwin-installer/default.nix | 2 +- tests/programs-zsh.nix | 2 +- tests/users-groups.nix | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index 36643a36..37a391c0 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -118,7 +118,7 @@ stdenv.mkDerivation { test -e /etc/static echo >&2 "checking profile" cat /etc/profile - grep -v nix-daemon.sh /etc/profile + (! grep nix-daemon.sh /etc/profile) echo >&2 "checking /run/current-system" readlink /run test -e /run diff --git a/tests/programs-zsh.nix b/tests/programs-zsh.nix index 9c98c335..18680a5d 100644 --- a/tests/programs-zsh.nix +++ b/tests/programs-zsh.nix @@ -34,7 +34,7 @@ echo >&2 "checking compinit in /etc/zshrc" grep 'autoload -U compinit && compinit' ${config.out}/etc/zshrc echo >&2 "checking bashcompinit in /etc/zshrc" - grep -vq 'bashcompinit' ${config.out}/etc/zshrc + (! grep 'bashcompinit' ${config.out}/etc/zshrc) echo >&2 "checking zprofile.d in /etc/zprofile" grep 'source /etc/zprofile.d/\*.conf' ${config.out}/etc/zprofile diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 7df92ba8..5b4f1ae0 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -28,37 +28,37 @@ grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} PrimaryGroupID 42000" ${config.out}/activate grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} RealName ${lib.escapeShellArg "Foo group"}" ${config.out}/activate grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} PrimaryGroupID 42001" ${config.out}/activate - grep -qv "dscl . -delete ${lib.escapeShellArg "/Groups/created.group"}" ${config.out}/activate + (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.group"}" ${config.out}/activate) # checking group deletion in /activate grep "dscl . -delete ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate - grep -qv "dscl . -create ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate + (! grep "dscl . -create ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate) echo "checking group membership in /activate" >&2 grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} GroupMembership ${lib.escapeShellArgs [ "admin" "foo" ]}" ${config.out}/activate grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} GroupMembership" ${config.out}/activate # checking unknown group in /activate - grep -qv "dscl . -create ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate - grep -qv "dscl . -delete ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate + (! grep "dscl . -create ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate) + (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate) # checking user creation in /activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate - grep -qv "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate - grep -qv "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate + (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) + (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) # checking user properties always get updated in /activate grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate # checking user deletion in /activate grep "deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate - grep -qv "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate + (! grep "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate) # checking unknown user in /activate - grep -qv "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate - grep -qv "deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate + (! grep "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) + (! grep "deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) set +v ''; From 13816f682d1f604271651fec193961ee76610670 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Oct 2024 01:07:34 +1100 Subject: [PATCH 036/139] tests: fix old test getting messed up in refactor https://github.com/LnL7/nix-darwin/commit/2788e4fa981566e34fa40938705cd7f595f05e74#diff-0642dcb4e551dcf07032904ee7f6b7ea645db36939f159908ccb2b85a2bbd1b8L53 --- tests/users-groups.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 5b4f1ae0..fa6dcc30 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -47,7 +47,7 @@ grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) - (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) + (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) # checking user properties always get updated in /activate grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate From c9af5c2d1394d1bc34f4722998bcd51714ccd68c Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 22:58:35 +1100 Subject: [PATCH 037/139] users: update properties on known users --- modules/users/default.nix | 5 ++++- tests/users-groups.nix | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index b636d6fe..f293f779 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -247,7 +247,10 @@ in dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} ${optionalString v.createHome "createhomedir -cu ${name}"} fi - # Always set the shell path, in case it was updated + + # Update properties on known users to keep them inline with configuration + dscl . -create ${dsclUser} PrimaryGroupID ${toString v.gid} + ${optionalString (v.description != null) "dscl . -create ${dsclUser} RealName ${lib.escapeShellArg v.description}"} dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)} fi '') createdUsers} diff --git a/tests/users-groups.nix b/tests/users-groups.nix index fa6dcc30..d06eedd8 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -19,6 +19,8 @@ users.users.foo.shell = pkgs.bashInteractive; users.users."created.user".uid = 42001; + users.users."created.user".description = null; + users.users."unknown.user".uid = 42002; test = '' @@ -39,6 +41,7 @@ grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} GroupMembership" ${config.out}/activate # checking unknown group in /activate + # checking groups not in knownGroups don't appear in /activate (! grep "dscl . -create ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate) @@ -50,15 +53,23 @@ (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) # checking user properties always get updated in /activate + grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} PrimaryGroupID 42000" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} RealName ${lib.escapeShellArg "Foo user"}" ${config.out}/activate + grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate + grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} IsHidden 0" ${config.out}/activate + + # checking user properties that are null don't get updated in /activate + (! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} RealName" ${config.out}/activate) # checking user deletion in /activate grep "deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate) - # checking unknown user in /activate + # checking that users not specified in knownUsers doesn't get changed in /activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) (! grep "deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) + (! grep "dscl . -create ${lib.escapeShellArg "/Users/unknown.user"}" ${config.out}/activate) set +v ''; From bd161d61d6f322e1c16543b67b1dbd13934e763c Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 24 Oct 2024 23:19:27 +1100 Subject: [PATCH 038/139] users: allow `home` to be managed by macOS --- modules/users/default.nix | 13 +++++++++++-- modules/users/user.nix | 14 +++++++++++--- tests/users-groups.nix | 2 ++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index f293f779..0b2ffd91 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -236,7 +236,13 @@ in requireFDA ${name} "created" - sysadminctl -addUser ${lib.escapeShellArgs ([ v.name "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) ++ [ "-home" v.home "-shell" (shellPath v.shell) ])} 2> /dev/null + sysadminctl -addUser ${lib.escapeShellArgs ([ + v.name + "-UID" v.uid + "-GID" v.gid ] + ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) + ++ (lib.optionals (v.home != null) [ "-home" v.home ]) + ++ [ "-shell" (shellPath v.shell) ])} 2> /dev/null # We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error if ! id ${name} &> /dev/null; then @@ -245,7 +251,10 @@ in fi dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"} - ${optionalString v.createHome "createhomedir -cu ${name}"} + + # `sysadminctl -addUser` won't create the home directory if we use the `-home` + # flag so we need to do it ourselves + ${optionalString (v.home != null && v.createHome) "createhomedir -cu ${name} > /dev/null"} fi # Update properties on known users to keep them inline with configuration diff --git a/modules/users/user.nix b/modules/users/user.nix index a0c8aab5..b9c97997 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -53,9 +53,17 @@ # }; home = mkOption { - type = types.path; - default = "/var/empty"; - description = "The user's home directory."; + type = types.nullOr types.path; + default = null; + description = '' + The user's home directory. This defaults to `null`. + + When this is set to `null`, the value is managed by macOS instead of + `nix-darwin`. This means if the user has not been created yet, + `sysadminctl` will be called without the `-home` flag which means the + user will have a default home directory of `/Users/` which will + be created by `sysadminctl`. + ''; }; createHome = mkOption { diff --git a/tests/users-groups.nix b/tests/users-groups.nix index d06eedd8..8fc435ae 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -20,6 +20,7 @@ users.users."created.user".uid = 42001; users.users."created.user".description = null; + users.users."created.user".home = null; users.users."unknown.user".uid = 42002; @@ -49,6 +50,7 @@ grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate + (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) From 3712ff78ccacd65c819435a310fe8b1a8a2de2ee Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 26 Oct 2024 11:35:34 +1100 Subject: [PATCH 039/139] users: change default shell to `/usr/bin/false` to match macOS --- modules/users/user.nix | 2 +- tests/users-groups.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/user.nix b/modules/users/user.nix index b9c97997..281b7e65 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -74,7 +74,7 @@ shell = mkOption { type = types.either types.shellPackage types.path; - default = "/sbin/nologin"; + default = "/usr/bin/false"; example = literalExpression "pkgs.bashInteractive"; description = "The user's shell."; }; diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 8fc435ae..290b94b5 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -49,7 +49,7 @@ # checking user creation in /activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate - grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/sbin/nologin" ]}" ${config.out}/activate + grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ]}" ${config.out}/activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) From dc6f754fe5d3b0d1ee6b033495c87ec3199a7f68 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 25 Oct 2024 01:16:19 +1100 Subject: [PATCH 040/139] users: allow `shell` to be managed by macOS --- modules/system/shells.nix | 12 +++++++++--- modules/users/default.nix | 4 ++-- modules/users/user.nix | 13 ++++++++++--- tests/users-groups.nix | 4 +++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/modules/system/shells.nix b/modules/system/shells.nix index 0b599d98..025936d4 100644 --- a/modules/system/shells.nix +++ b/modules/system/shells.nix @@ -14,9 +14,15 @@ in example = literalExpression "[ pkgs.bashInteractive pkgs.zsh ]"; description = '' A list of permissible login shells for user accounts. - No need to mention `/bin/sh` - and other shells that are available by default on - macOS. + + The default macOS shells will be automatically included: + - /bin/bash + - /bin/csh + - /bin/dash + - /bin/ksh + - /bin/sh + - /bin/tcsh + - /bin/zsh ''; apply = map (v: if types.shellPackage.check v then "/run/current-system/sw${v.shellPath}" else v); }; diff --git a/modules/users/default.nix b/modules/users/default.nix index 0b2ffd91..aee8fecc 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -242,7 +242,7 @@ in "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) ++ (lib.optionals (v.home != null) [ "-home" v.home ]) - ++ [ "-shell" (shellPath v.shell) ])} 2> /dev/null + ++ [ "-shell" (if v.shell != null then shellPath v.shell else "/usr/bin/false") ])} 2> /dev/null # We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error if ! id ${name} &> /dev/null; then @@ -260,7 +260,7 @@ in # Update properties on known users to keep them inline with configuration dscl . -create ${dsclUser} PrimaryGroupID ${toString v.gid} ${optionalString (v.description != null) "dscl . -create ${dsclUser} RealName ${lib.escapeShellArg v.description}"} - dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)} + ${optionalString (v.shell != null) "dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)}"} fi '') createdUsers} diff --git a/modules/users/user.nix b/modules/users/user.nix index 281b7e65..72ae07b8 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -73,10 +73,17 @@ }; shell = mkOption { - type = types.either types.shellPackage types.path; - default = "/usr/bin/false"; + type = types.nullOr (types.either types.shellPackage types.path); + default = null; example = literalExpression "pkgs.bashInteractive"; - description = "The user's shell."; + description = '' + The user's shell. This defaults to `null`. + + When this is set to `null`, if the user has not been created yet, + they will be created with the shell `/usr/bin/false` to prevent + interactive login. If the user already exists, the value is + considered managed by macOS and `nix-darwin` will not change it. + ''; }; packages = mkOption { diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 290b94b5..cf2f0084 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -21,6 +21,7 @@ users.users."created.user".uid = 42001; users.users."created.user".description = null; users.users."created.user".home = null; + users.users."created.user".shell = null; users.users."unknown.user".uid = 42002; @@ -49,7 +50,7 @@ # checking user creation in /activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate - grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ]}" ${config.out}/activate + grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ] }" ${config.out}/activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) @@ -63,6 +64,7 @@ # checking user properties that are null don't get updated in /activate (! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} RealName" ${config.out}/activate) + (! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} UserShell" ${config.out}/activate) # checking user deletion in /activate grep "deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate From 55be3e1a5f9c816f30baf0d9de8ba77c954847dd Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 26 Oct 2024 12:31:53 +1100 Subject: [PATCH 041/139] users: move checks to `system.checks` --- modules/system/activation-scripts.nix | 1 + modules/users/default.nix | 120 +++++++++++++++++--------- 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index da8eb5c9..5f8916cc 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -86,6 +86,7 @@ in exit $_status ''; + # FIXME: activationScripts.checks should be system level system.activationScripts.userScript.text = '' #! ${stdenv.shell} set -e diff --git a/modules/users/default.nix b/modules/users/default.nix index aee8fecc..a618792b 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -98,6 +98,84 @@ in users.gids = mkMerge gids; users.uids = mkMerge uids; + # NOTE: We put this in `system.checks` as we want this to run first to avoid partial activations + # however currently that runs at user level activation as that runs before system level activation + # TODO: replace `$USER` with `$SUDO_USER` when system.checks runs from system level + system.checks.text = lib.mkAfter '' + requireFDA() { + fullDiskAccess=false + + if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then + fullDiskAccess=true + fi + + if [[ "$fullDiskAccess" != true ]]; then + printf >&2 '\e[1;31merror: users cannot be %s without Full Disk Access, aborting activation\e[0m\n' "$2" + printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" "$2" + printf >&2 '\n' + printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' + printf >&2 '\n' + # This command will fail if run as root and System Settings is already running + # even if System Settings was launched by root. + open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles" + + if [[ -n "$SSH_CONNECTION" ]]; then + printf >&2 'Please enable Full Disk Access for programs over SSH by flipping\n' + printf >&2 'the switch for `sshd-keygen-wrapper`.\n' + else + printf >&2 'Please enable Full Disk Access for your terminal emulator by flipping\n' + printf >&2 'the switch in System Settings.\n' + fi + + exit 1 + fi + } + + ensureDeletable() { + # TODO: add `darwin.primaryUser` as well + if [[ "$1" == "$USER" ]]; then + printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" + exit 1 + elif [[ "$1" == "root" ]]; then + printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' + exit 1 + fi + + requireFDA "$1" deleted + } + + ${concatMapStringsSep "\n" (v: let + name = lib.escapeShellArg v.name; + dsclUser = lib.escapeShellArg "/Users/${v.name}"; + in '' + ${optionalString cfg.forceRecreate '' + u=$(id -u ${name} 2> /dev/null) || true + if [[ "$u" -eq ${toString v.uid} ]]; then + # TODO: add `darwin.primaryUser` as well + if [[ ${name} != "$USER" && ${name} != "root" ]]; then + ensureDeletable ${name} + fi + fi + ''} + + u=$(id -u ${name} 2> /dev/null) || true + if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then + if [ -z "$u" ]; then + requireFDA ${name} created + fi + fi + '') createdUsers} + + ${concatMapStringsSep "\n" (name: '' + u=$(id -u ${lib.escapeShellArg name} 2> /dev/null) || true + if [ -n "$u" ]; then + if [ "$u" -gt 501 ]; then + ensureDeletable ${lib.escapeShellArg name} + fi + fi + '') deletedUsers} + ''; + system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) '' echo "setting up groups..." >&2 @@ -154,47 +232,7 @@ in system.activationScripts.users.text = mkIf (cfg.knownUsers != []) '' echo "setting up users..." >&2 - requireFDA() { - fullDiskAccess=false - - if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then - fullDiskAccess=true - fi - - if [[ "$fullDiskAccess" != true ]]; then - printf >&2 '\e[1;31merror: users cannot be %s without Full Disk Access, aborting activation\e[0m\n' "$2" - printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" "$2" - printf >&2 '\n' - printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' - printf >&2 '\n' - # This command will fail if run as root and System Settings is already running - # even if System Settings was launched by root. - sudo -u $SUDO_USER open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles" - - if [[ -n "$SSH_CONNECTION" ]]; then - printf >&2 'Please enable Full Disk Access for programs over SSH by flipping\n' - printf >&2 'the switch for `sshd-keygen-wrapper`.\n' - else - printf >&2 'Please enable Full Disk Access for your terminal emulator by flipping\n' - printf >&2 'the switch in System Settings.\n' - fi - - exit 1 - fi - } - deleteUser() { - # FIXME: add `darwin.primaryUser` as well - if [[ "$1" == "$SUDO_USER" ]]; then - printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" - exit 1 - elif [[ "$1" == "root" ]]; then - printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n', "$1" - exit 1 - fi - - requireFDA "$1" deleted - dscl . -delete "/Users/$1" 2> /dev/null # `dscl . -delete` should exit with a non-zero exit code when there's an error, but we'll leave @@ -234,8 +272,6 @@ in if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - requireFDA ${name} "created" - sysadminctl -addUser ${lib.escapeShellArgs ([ v.name "-UID" v.uid From 9cd3976486fd0d189cbb3ad3e71c345502a3b1f5 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 26 Oct 2024 12:31:53 +1100 Subject: [PATCH 042/139] users: ensure all users' home directories in the config are correct --- modules/users/default.nix | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/users/default.nix b/modules/users/default.nix index a618792b..3f614c69 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -94,6 +94,14 @@ in }; config = { + assertions = [ + { + # We don't check `root` like the rest of the users as on some systems `root`'s + # home directory is set to `/var/root /private/var/root` + assertion = cfg.users ? root -> (cfg.users.root.home == null || cfg.users.root.home == "/var/root"); + message = "`users.users.root.home` must be set to either `null` or `/var/root`."; + } + ]; users.gids = mkMerge gids; users.uids = mkMerge uids; @@ -163,6 +171,22 @@ in if [ -z "$u" ]; then requireFDA ${name} created fi + + ${optionalString (v.home != null && v.name != "root") '' + homeDirectory=$(dscl . -read ${dsclUser} NFSHomeDirectory) + homeDirectory=''${homeDirectory#NFSHomeDirectory: } + if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then + printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} + printf >&2 'nix-darwin does not support changing the home directory of existing users. + printf >&2 '\n' + printf >&2 'Please set:\n' + printf >&2 '\n' + printf >&2 ' users.users.%s.home = "%s";\n' ${name} "$homeDirectory" + printf >&2 '\n' + printf >&2 'or remove it from your configuration.\n' + exit 1 + fi + ''} fi '') createdUsers} From 32f0cf2140af6a852f8c8b6c8f15e4855d461b87 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 00:37:55 +1100 Subject: [PATCH 043/139] users: replace FDA check with more fine grained permissions check --- modules/users/default.nix | 78 +++++++++++++++++++-------------------- tests/users-groups.nix | 6 +-- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 3f614c69..c6c66f35 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -110,32 +110,44 @@ in # however currently that runs at user level activation as that runs before system level activation # TODO: replace `$USER` with `$SUDO_USER` when system.checks runs from system level system.checks.text = lib.mkAfter '' - requireFDA() { - fullDiskAccess=false - - if cat /Library/Preferences/com.apple.TimeMachine.plist > /dev/null 2>&1; then - fullDiskAccess=true - fi - - if [[ "$fullDiskAccess" != true ]]; then - printf >&2 '\e[1;31merror: users cannot be %s without Full Disk Access, aborting activation\e[0m\n' "$2" - printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access.\n' "$1" "$2" - printf >&2 '\n' - printf >&2 'Opening "Privacy & Security" > "Full Disk Access" in System Settings\n' - printf >&2 '\n' - # This command will fail if run as root and System Settings is already running - # even if System Settings was launched by root. - open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles" + ensurePerms() { + homeDirectory=$(dscl . -read /Users/nobody NFSHomeDirectory) + homeDirectory=''${homeDirectory#NFSHomeDirectory: } + if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then if [[ -n "$SSH_CONNECTION" ]]; then - printf >&2 'Please enable Full Disk Access for programs over SSH by flipping\n' - printf >&2 'the switch for `sshd-keygen-wrapper`.\n' + printf >&2 '\e[1;31merror: users cannot be %s over SSH without Full Disk Access, aborting activation\e[0m\n' "$2" + printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access over SSH.\n' "$1" "$2" + printf >&2 'You can either:\n' + printf >&2 '\n' + printf >&2 ' grant Full Disk Access to all programs run over SSH\n' + printf >&2 '\n' + printf >&2 'or\n' + printf >&2 '\n' + printf >&2 ' run `darwin-rebuild` in a graphical session.\n' + printf >&2 '\n' + printf >&2 'The option "Allow full disk access for remote users" can be found by\n' + printf >&2 'navigating to System Settings > General > Sharing > Remote Login\n' + printf >&2 'and then pressing on the i icon next to the switch.\n' + exit 1 else - printf >&2 'Please enable Full Disk Access for your terminal emulator by flipping\n' - printf >&2 'the switch in System Settings.\n' + # The TCC service required to change home directories is `kTCCServiceSystemPolicySysAdminFiles` + # and we can reset it to ensure the user gets another prompt + tccutil reset SystemPolicySysAdminFiles > /dev/null + + if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then + printf >&2 '\e[1;31merror: permission denied when trying to %s user %s, aborting activation\e[0m\n' "$2" "$1" + printf >&2 '`darwin-rebuild` requires permissions to administrate your computer,\n' "$1" "$2" + printf >&2 'please accept the dialog that pops up.\n' + printf >&2 '\n' + printf >&2 'If you do not wish to be prompted every time `darwin-rebuild updates your users,\n' + printf >&2 'you can grant Full Disk Access to your terminal emulator in System Settings.\n' + printf >&2 '\n' + printf >&2 'This can be found in System Settings > Privacy & Security > Full Disk Access.\n' + exit 1 + fi fi - exit 1 fi } @@ -149,7 +161,7 @@ in exit 1 fi - requireFDA "$1" deleted + ensurePerms "$1" delete } ${concatMapStringsSep "\n" (v: let @@ -169,7 +181,7 @@ in u=$(id -u ${name} 2> /dev/null) || true if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then if [ -z "$u" ]; then - requireFDA ${name} created + ensurePerms ${name} create fi ${optionalString (v.home != null && v.name != "root") '' @@ -211,7 +223,7 @@ in g=''${g#PrimaryGroupID: } if [[ "$g" -eq ${toString v.gid} ]]; then echo "deleting group ${v.name}..." >&2 - dscl . -delete ${dsclGroup} 2> /dev/null + dscl . -delete ${dsclGroup} else echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 fi @@ -245,7 +257,7 @@ in if [ -n "$g" ]; then if [ "$g" -gt 501 ]; then echo "deleting group ${name}..." >&2 - dscl . -delete ${dsclGroup} 2> /dev/null + dscl . -delete ${dsclGroup} else echo "warning: existing group '${name}' has unexpected gid $g, skipping..." >&2 fi @@ -256,18 +268,6 @@ in system.activationScripts.users.text = mkIf (cfg.knownUsers != []) '' echo "setting up users..." >&2 - deleteUser() { - dscl . -delete "/Users/$1" 2> /dev/null - - # `dscl . -delete` should exit with a non-zero exit code when there's an error, but we'll leave - # this code here just in case and for when we switch to `sysadminctl -deleteUser` - # We need to check as `sysadminctl -deleteUser` still exits with exit code 0 when there's an error - if id "$1" &> /dev/null; then - printf >&2 '\e[1;31merror: failed to delete user %s, aborting activation\e[0m\n', "$1" - exit 1 - fi - } - ${concatMapStringsSep "\n" (v: let name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; @@ -282,7 +282,7 @@ in printf >&2 'warning: not going to recreate root, skipping...\n' else printf >&2 'deleting user ${v.name}...\n' - deleteUser ${name} + dscl . -delete ${dsclUser} fi else echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 @@ -329,7 +329,7 @@ in if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 - deleteUser ${lib.escapeShellArg name} + dscl . -delete ${lib.escapeShellArg "/Users/${name}"} else echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2 fi diff --git a/tests/users-groups.nix b/tests/users-groups.nix index cf2f0084..34ee5c24 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -52,7 +52,7 @@ grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ] }" ${config.out}/activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) - (! grep "deleteUser ${lib.escapeShellArg "created.user"}" ${config.out}/activate) + (! grep "dscl . -delete ${lib.escapeShellArg "/Users/created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) # checking user properties always get updated in /activate @@ -67,12 +67,12 @@ (! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} UserShell" ${config.out}/activate) # checking user deletion in /activate - grep "deleteUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate + grep "dscl . -delete ${lib.escapeShellArg "/Users/deleted.user"}" ${config.out}/activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate) # checking that users not specified in knownUsers doesn't get changed in /activate (! grep "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) - (! grep "deleteUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate) + (! grep "dscl . -delete ${lib.escapeShellArg "/Users/unknown.user"}" ${config.out}/activate) (! grep "dscl . -create ${lib.escapeShellArg "/Users/unknown.user"}" ${config.out}/activate) set +v From febc3b3f514d1e3d46182975430737d0232e6af0 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 26 Oct 2024 16:13:23 +1100 Subject: [PATCH 044/139] users: remove `with lib;` --- modules/users/default.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index c6c66f35..a23251dc 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -1,8 +1,9 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) concatStringsSep concatMapStringsSep elem filter filterAttrs + mapAttrs' mapAttrsToList mkIf mkMerge mkOption mkOrder optionalString types; + cfg = config.users; group = import ./group.nix; From a15a3d9f1f9fadd455b38b3833e1ee6db6b59186 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 10:47:15 +1100 Subject: [PATCH 045/139] users: fix unclosed string --- modules/users/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index a23251dc..92c0cd8a 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -190,7 +190,7 @@ in homeDirectory=''${homeDirectory#NFSHomeDirectory: } if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} - printf >&2 'nix-darwin does not support changing the home directory of existing users. + printf >&2 'nix-darwin does not support changing the home directory of existing users.\n' printf >&2 '\n' printf >&2 'Please set:\n' printf >&2 '\n' From c908607e8a8ac1aaa0db60955800be4b02e500cc Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 01:05:16 +1100 Subject: [PATCH 046/139] users: remove `users.forceRecreate` option --- modules/users/default.nix | 78 +++++++++------------------------------ 1 file changed, 18 insertions(+), 60 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 92c0cd8a..58156d24 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -41,6 +41,10 @@ let in { + imports = [ + (lib.mkRemovedOptionModule [ "users" "forceRecreate" ] "") + ]; + options = { users.knownGroups = mkOption { type = types.listOf types.str; @@ -85,13 +89,6 @@ in type = types.attrsOf types.str; default = {}; }; - - users.forceRecreate = mkOption { - internal = true; - type = types.bool; - default = false; - description = "Remove and recreate existing groups/users."; - }; }; config = { @@ -152,33 +149,11 @@ in fi } - ensureDeletable() { - # TODO: add `darwin.primaryUser` as well - if [[ "$1" == "$USER" ]]; then - printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" - exit 1 - elif [[ "$1" == "root" ]]; then - printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' - exit 1 - fi - - ensurePerms "$1" delete - } ${concatMapStringsSep "\n" (v: let name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - u=$(id -u ${name} 2> /dev/null) || true - if [[ "$u" -eq ${toString v.uid} ]]; then - # TODO: add `darwin.primaryUser` as well - if [[ ${name} != "$USER" && ${name} != "root" ]]; then - ensureDeletable ${name} - fi - fi - ''} - u=$(id -u ${name} 2> /dev/null) || true if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then if [ -z "$u" ]; then @@ -203,11 +178,22 @@ in fi '') createdUsers} - ${concatMapStringsSep "\n" (name: '' - u=$(id -u ${lib.escapeShellArg name} 2> /dev/null) || true + ${concatMapStringsSep "\n" (v: let + name = lib.escapeShellArg v; + in '' + u=$(id -u ${name} 2> /dev/null) || true if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then - ensureDeletable ${lib.escapeShellArg name} + # TODO: add `darwin.primaryUser` as well + if [[ ${name} == "$USER" ]]; then + printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', ${name} + exit 1 + elif [[ ${name} == "root" ]]; then + printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' + exit 1 + fi + + ensurePerms ${name} delete fi fi '') deletedUsers} @@ -219,17 +205,6 @@ in ${concatMapStringsSep "\n" (v: let dsclGroup = lib.escapeShellArg "/Groups/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true - g=''${g#PrimaryGroupID: } - if [[ "$g" -eq ${toString v.gid} ]]; then - echo "deleting group ${v.name}..." >&2 - dscl . -delete ${dsclGroup} - else - echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 - fi - ''} - g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [ -z "$g" ]; then @@ -273,23 +248,6 @@ in name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - u=$(id -u ${name} 2> /dev/null) || true - if [[ "$u" -eq ${toString v.uid} ]]; then - # TODO: add `darwin.primaryUser` as well - if [[ ${name} == "$SUDO_USER" ]]; then - printf >&2 'warning: not going to recreate the user calling `darwin-rebuild` (%s), skipping...\n' "$SUDO_USER" - elif [[ ${name} == "root" ]]; then - printf >&2 'warning: not going to recreate root, skipping...\n' - else - printf >&2 'deleting user ${v.name}...\n' - dscl . -delete ${dsclUser} - fi - else - echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 - fi - ''} - u=$(id -u ${name} 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 From f380194f3dac82e63dc72db160490dcb58208534 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 10:30:02 +1100 Subject: [PATCH 047/139] users: create users with home directory `/var/empty` by default --- modules/users/default.nix | 2 +- modules/users/user.nix | 8 +++----- tests/users-groups.nix | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 58156d24..a945fb48 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -260,7 +260,7 @@ in "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) - ++ (lib.optionals (v.home != null) [ "-home" v.home ]) + ++ [ "-home" (if v.home != null then v.home else "/var/empty") ] ++ [ "-shell" (if v.shell != null then shellPath v.shell else "/usr/bin/false") ])} 2> /dev/null # We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error diff --git a/modules/users/user.nix b/modules/users/user.nix index 72ae07b8..9689e052 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -58,11 +58,9 @@ description = '' The user's home directory. This defaults to `null`. - When this is set to `null`, the value is managed by macOS instead of - `nix-darwin`. This means if the user has not been created yet, - `sysadminctl` will be called without the `-home` flag which means the - user will have a default home directory of `/Users/` which will - be created by `sysadminctl`. + When this is set to `null`, if the user has not been created yet, + they will be created with the home directory `/var/empty` to match + the old default. ''; }; diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 34ee5c24..81261057 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -51,7 +51,7 @@ grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ] }" ${config.out}/activate - (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) + grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* ${lib.escapeShellArgs [ "-home" "/var/empty" ]}" ${config.out}/activate (! grep "dscl . -delete ${lib.escapeShellArg "/Users/created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate) From 6eea6b4a759be83e6d9310408aebeea54c404094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Fri, 25 Oct 2024 13:04:41 +0200 Subject: [PATCH 048/139] Reuse nixpkgs instead of accessing channel This fixes pure evaluation in flakes --- release.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.nix b/release.nix index 0d754fc0..a9105912 100644 --- a/release.nix +++ b/release.nix @@ -61,7 +61,7 @@ let in buildFromConfig configuration (config: config.system.build.run-test); - release = import { + release = import (nixpkgs + "/pkgs/top-level/release-lib.nix") { inherit supportedSystems scrubJobs; packageSet = import nixpkgs; }; From 6c8d45fb20c40a8ccc73130d026d487b887a3de4 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Mon, 28 Oct 2024 04:10:45 +0100 Subject: [PATCH 049/139] module: add prometheus-node-exporter service --- modules/misc/ids.nix | 2 + modules/module-list.nix | 1 + .../monitoring/prometheus-node-exporter.nix | 117 ++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 modules/services/monitoring/prometheus-node-exporter.nix diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index c0f3a197..34b36859 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -38,10 +38,12 @@ in ids.uids = { nixbld = lib.mkDefault 350; + _prometheus-node-exporter = 534; }; ids.gids = { nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350); + _prometheus-node-exporter = 534; }; }; diff --git a/modules/module-list.nix b/modules/module-list.nix index effdff76..2e6d9430 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -74,6 +74,7 @@ ./services/mopidy.nix ./services/monitoring/telegraf.nix ./services/monitoring/netdata.nix + ./services/monitoring/prometheus-node-exporter.nix ./services/netbird.nix ./services/nix-daemon.nix ./services/nix-gc diff --git a/modules/services/monitoring/prometheus-node-exporter.nix b/modules/services/monitoring/prometheus-node-exporter.nix new file mode 100644 index 00000000..752dc0f2 --- /dev/null +++ b/modules/services/monitoring/prometheus-node-exporter.nix @@ -0,0 +1,117 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + concatStringsSep + escapeShellArgs + getExe + mkEnableOption + mkIf + mkOption + mkPackageOption + mkRemovedOptionModule + types + ; + + cfg = config.services.prometheus.exporters.node; +in { + imports = [ + (mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "openFirewall" ] "No nix-darwin equivalent to this NixOS option.") + (mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "firewallFilter" ] "No nix-darwin equivalent to this NixOS option.") + (mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "firewallRules" ] "No nix-darwin equivalent to this NixOS option.") + ]; + + options = { + services.prometheus.exporters.node = { + enable = mkEnableOption "Prometheus Node exporter"; + + package = mkPackageOption pkgs "prometheus-node-exporter" { }; + + listenAddress = mkOption { + type = types.str; + default = ""; + example = "0.0.0.0"; + description = '' + Address where Node exporter exposes its HTTP interface. Leave empty to bind to all addresses. + ''; + }; + + port = mkOption { + type = types.port; + default = 9100; + description = '' + Port where the Node exporter exposes its HTTP interface. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--log.level=debug" ]; + description = '' + Extra commandline options to pass to the Node exporter executable. + ''; + }; + + enabledCollectors = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + Collectors to enable in addition to the ones that are [enabled by default](https://github.com/prometheus/node_exporter#enabled-by-default). + ''; + }; + + disabledCollectors = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "boottime" ]; + description = '' + Collectors to disable from the list of collectors that are [enabled by default](https://github.com/prometheus/node_exporter#enabled-by-default). + ''; + }; + }; + }; + + config = mkIf cfg.enable { + users.users._prometheus-node-exporter = { + uid = config.ids.uids._prometheus-node-exporter; + gid = config.ids.gids._prometheus-node-exporter; + home = "/var/empty"; + shell = "/usr/bin/false"; + description = "System user for the Prometheus Node exporter"; + }; + + users.groups._prometheus-node-exporter = { + gid = config.ids.gids._prometheus-node-exporter; + description = "System group for the Prometheus Node exporter"; + }; + + users.knownGroups = [ "_prometheus-node-exporter" ]; + users.knownUsers = [ "_prometheus-node-exporter" ]; + + launchd.daemons.prometheus-node-exporter = { + script = concatStringsSep " " + ([ + (getExe cfg.package) + "--web.listen-address" + "${cfg.listenAddress}:${toString cfg.port}" + ] + ++ (map (collector: "--collector.${collector}") cfg.enabledCollectors) + ++ (map (collector: "--no-collector.${collector}") cfg.disabledCollectors) + ) + escapeShellArgs cfg.extraFlags; + serviceConfig = { + KeepAlive = true; + RunAtLoad = true; + StandardErrorPath = "/var/log/prometheus-node-exporter.log"; + StandardOutPath = "/var/log/prometheus-node-exporter.log"; + GroupName = "_prometheus-node-exporter"; + UserName = "_prometheus-node-exporter"; + }; + }; + }; +} From 470f87c1827b51169ed4f91cdbdfd48417bfff3d Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 31 Oct 2024 15:02:36 +1100 Subject: [PATCH 050/139] zsh: enable by default as zsh is the default shell on macOS Historically this was a footgun because users would not always have this enabled leading to `darwin-rebuild` and other programs not being found. --- modules/examples/flake/flake.nix | 3 +-- modules/examples/simple.nix | 3 +-- modules/programs/zsh/default.nix | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index 94c600ed..e6eaefc7 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -23,8 +23,7 @@ # Necessary for using flakes on this system. nix.settings.experimental-features = "nix-command flakes"; - # Create /etc/zshrc that loads the nix-darwin environment. - programs.zsh.enable = true; # default shell on catalina + # Enable alternative shell support in nix-darwin. # programs.fish.enable = true; # Set Git commit hash for darwin-version. diff --git a/modules/examples/simple.nix b/modules/examples/simple.nix index 1133da82..5baf009f 100644 --- a/modules/examples/simple.nix +++ b/modules/examples/simple.nix @@ -15,8 +15,7 @@ # services.nix-daemon.enable = true; # nix.package = pkgs.nix; - # Create /etc/zshrc that loads the nix-darwin environment. - programs.zsh.enable = true; # default shell on catalina + # Enable alternative shell support in nix-darwin. # programs.fish.enable = true; # Used for backwards compatibility, please read the changelog before changing. diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index bfbfc59e..1665fcd8 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -18,7 +18,7 @@ in options = { programs.zsh.enable = mkOption { type = types.bool; - default = false; + default = true; description = "Whether to configure zsh as an interactive shell."; }; From 1588cb2e997fb37a4eab78da13808faf49df903f Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 31 Oct 2024 15:02:36 +1100 Subject: [PATCH 051/139] environment: remove misleading `environment.loginShell` option --- modules/environment/default.nix | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/environment/default.nix b/modules/environment/default.nix index 00d58c09..994c77a3 100644 --- a/modules/environment/default.nix +++ b/modules/environment/default.nix @@ -18,6 +18,11 @@ in { imports = [ (mkRenamedOptionModule ["environment" "postBuild"] ["environment" "extraSetup"]) + (mkRemovedOptionModule [ "environment" "loginShell" ] '' + This option was only used to change the default command in tmux. + + This has been removed in favour of changing the default command or default shell in tmux directly. + '') ]; options = { @@ -74,12 +79,6 @@ in ''; }; - environment.loginShell = mkOption { - type = types.str; - default = "$SHELL -l"; - description = "Configure default login shell."; - }; - environment.variables = mkOption { type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; From 63f4d40e551e7b29fbe586967c03eea1e6a70ce4 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 31 Oct 2024 15:59:09 +1100 Subject: [PATCH 052/139] tmux: remove `programs.tmux.defaultCommand` --- modules/examples/lnl.nix | 1 - modules/programs/tmux.nix | 12 +----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index 010dff5a..d944158a 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -277,7 +277,6 @@ zle -N up-line-or-beginning-search ''; - environment.loginShell = "${pkgs.zsh}/bin/zsh -l"; environment.variables.SHELL = "${pkgs.zsh}/bin/zsh"; environment.variables.LANG = "en_US.UTF-8"; diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index ae6fcbf9..d70dab18 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -41,6 +41,7 @@ in { imports = [ (mkRenamedOptionModule [ "programs" "tmux" "tmuxConfig" ] [ "programs" "tmux" "extraConfig" ]) + (mkRemovedOptionModule [ "programs" "tmux" "defaultCommand" ] "Use `programs.tmux.extraConfig` to configure the default command instead. If unset, tmux will default to using your system configured login shell.") ]; options = { programs.tmux.enable = mkOption { @@ -84,11 +85,6 @@ in description = "Cater to iTerm2 and its tmux integration, as appropriate."; }; - programs.tmux.defaultCommand = mkOption { - type = types.either types.str types.package; - description = "The default command to use for tmux panes."; - }; - programs.tmux.tmuxOptions = mkOption { internal = true; type = types.attrsOf (types.submodule text); @@ -120,12 +116,6 @@ in source-file -q /etc/tmux.conf.local ''; - programs.tmux.defaultCommand = mkDefault config.environment.loginShell; - - programs.tmux.tmuxOptions.login-shell.text = '' - set -g default-command "${cfg.defaultCommand}" - ''; - programs.tmux.tmuxOptions.sensible.text = mkIf cfg.enableSensible '' set -g default-terminal "screen-256color" setw -g aggressive-resize on From 331fd8d3b596999e731ede69a8cbf6524968d936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20de=20Chezelles?= Date: Thu, 31 Oct 2024 16:51:05 +0100 Subject: [PATCH 053/139] karabiner-elements: allow use of custom package --- .../services/karabiner-elements/default.nix | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/services/karabiner-elements/default.nix b/modules/services/karabiner-elements/default.nix index 27645050..8be2ddff 100644 --- a/modules/services/karabiner-elements/default.nix +++ b/modules/services/karabiner-elements/default.nix @@ -9,18 +9,19 @@ let in { - options = { - services.karabiner-elements.enable = mkEnableOption "Karabiner-Elements"; + options.services.karabiner-elements = { + enable = mkEnableOption "Karabiner-Elements"; + package = mkPackageOption pkgs "karabiner-elements" { }; }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.karabiner-elements ]; + environment.systemPackages = [ cfg.package ]; system.activationScripts.preActivation.text = '' rm -rf ${parentAppDir} mkdir -p ${parentAppDir} # Kernel extensions must reside inside of /Applications, they cannot be symlinks - cp -r ${pkgs.karabiner-elements.driver}/Applications/.Karabiner-VirtualHIDDevice-Manager.app ${parentAppDir} + cp -r ${cfg.package.driver}/Applications/.Karabiner-VirtualHIDDevice-Manager.app ${parentAppDir} ''; system.activationScripts.postActivation.text = '' @@ -49,7 +50,7 @@ in launchd.daemons.karabiner_grabber = { serviceConfig.ProgramArguments = [ - "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_grabber" + "${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_grabber" ]; serviceConfig.ProcessType = "Interactive"; serviceConfig.Label = "org.pqrs.karabiner.karabiner_grabber"; @@ -60,7 +61,7 @@ in launchd.daemons.karabiner_observer = { serviceConfig.ProgramArguments = [ - "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_observer" + "${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_observer" ]; serviceConfig.Label = "org.pqrs.karabiner.karabiner_observer"; @@ -70,7 +71,7 @@ in }; launchd.daemons.Karabiner-DriverKit-VirtualHIDDeviceClient = { - command = "\"${pkgs.karabiner-elements.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient\""; + command = "\"${cfg.package.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient\""; serviceConfig.ProcessType = "Interactive"; serviceConfig.Label = "org.pqrs.Karabiner-DriverKit-VirtualHIDDeviceClient"; serviceConfig.KeepAlive = true; @@ -91,7 +92,7 @@ in script = '' rm -rf /run/wrappers mkdir -p /run/wrappers/bin - install -m4555 "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin + install -m4555 "${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin ''; serviceConfig.RunAtLoad = true; serviceConfig.KeepAlive.SuccessfulExit = false; @@ -106,8 +107,8 @@ in serviceConfig.KeepAlive = true; }; - environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_grabber.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_grabber.plist"; - environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_observer.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_observer.plist"; - environment.userLaunchAgents."org.pqrs.karabiner.karabiner_console_user_server.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist"; + environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_grabber.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_grabber.plist"; + environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_observer.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_observer.plist"; + environment.userLaunchAgents."org.pqrs.karabiner.karabiner_console_user_server.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist"; }; } From 318df382e61e6116034017454ae596f3980c4613 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 2 Nov 2024 10:31:40 +1100 Subject: [PATCH 054/139] users: don't check home directory is correct before creating user --- modules/users/default.nix | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index a945fb48..6a1cd2e6 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -158,23 +158,24 @@ in if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then if [ -z "$u" ]; then ensurePerms ${name} create - fi - ${optionalString (v.home != null && v.name != "root") '' - homeDirectory=$(dscl . -read ${dsclUser} NFSHomeDirectory) - homeDirectory=''${homeDirectory#NFSHomeDirectory: } - if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then - printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} - printf >&2 'nix-darwin does not support changing the home directory of existing users.\n' - printf >&2 '\n' - printf >&2 'Please set:\n' - printf >&2 '\n' - printf >&2 ' users.users.%s.home = "%s";\n' ${name} "$homeDirectory" - printf >&2 '\n' - printf >&2 'or remove it from your configuration.\n' - exit 1 - fi - ''} + ${optionalString (v.home != null && v.name != "root") '' + else + homeDirectory=$(dscl . -read ${dsclUser} NFSHomeDirectory) + homeDirectory=''${homeDirectory#NFSHomeDirectory: } + if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then + printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} + printf >&2 'nix-darwin does not support changing the home directory of existing users.\n' + printf >&2 '\n' + printf >&2 'Please set:\n' + printf >&2 '\n' + printf >&2 ' users.users.%s.home = "%s";\n' ${name} "$homeDirectory" + printf >&2 '\n' + printf >&2 'or remove it from your configuration.\n' + exit 1 + fi + ''} + fi fi '') createdUsers} From 0dacfdea635b664812b8065e6b5449c43bf1a586 Mon Sep 17 00:00:00 2001 From: April Schleck Date: Fri, 25 Oct 2024 13:21:56 -0700 Subject: [PATCH 055/139] Configure the folder that new Finder windows open --- modules/system/defaults/finder.nix | 54 ++++++++++++++++++- .../system-defaults-write/activate-user.txt | 10 ++++ tests/system-defaults-write.nix | 2 + 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/modules/system/defaults/finder.nix b/modules/system/defaults/finder.nix index 1da93c04..51fff74f 100644 --- a/modules/system/defaults/finder.nix +++ b/modules/system/defaults/finder.nix @@ -1,7 +1,10 @@ { config, lib, ... }: -with lib; +let + inherit (lib) mkOption types; + cfg = config.system.defaults.finder; +in { options = { @@ -96,5 +99,54 @@ with lib; ''; }; + system.defaults.finder.NewWindowTarget = mkOption { + type = types.nullOr (types.enum [ + "Computer" + "OS volume" + "Home" + "Desktop" + "Documents" + "Recents" + "iCloud Drive" + "Other" + ]); + apply = key: if key == null then null else { + "Computer" = "PfCm"; + "OS volume" = "PfVo"; + "Home" = "PfHm"; + "Desktop" = "PfDe"; + "Documents" = "PfDo"; + "Recents" = "PfAF"; + "iCloud Drive" = "PfID"; + "Other" = "PfLo"; + }.${key}; + default = null; + description = '' + Change the default folder shown in Finder windows. "Other" corresponds to the value of + NewWindowTargetPath. The default is unset ("Recents"). + ''; + }; + + system.defaults.finder.NewWindowTargetPath = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Sets the URI to open when NewWindowTarget is "Other". Spaces and similar characters must be + escaped. If the value is invalid, Finder will open your home directory. + Example: "file:///Users/foo/long%20cat%20pics". + The default is unset. + ''; + }; + }; + + config = { + assertions = [{ + assertion = cfg.NewWindowTargetPath != null -> cfg.NewWindowTarget == "PfLo"; + message = "`system.defaults.finder.NewWindowTarget` should be set to `Other` when `NewWindowTargetPath` is non-null."; + } + { + assertion = cfg.NewWindowTarget == "PfLo" -> cfg.NewWindowTargetPath != null; + message = "`system.defaults.finder.NewWindowTargetPath` should be non-null when `NewWindowTarget` is set to `Other`."; + }]; }; } diff --git a/tests/fixtures/system-defaults-write/activate-user.txt b/tests/fixtures/system-defaults-write/activate-user.txt index f3e01a64..11d36355 100644 --- a/tests/fixtures/system-defaults-write/activate-user.txt +++ b/tests/fixtures/system-defaults-write/activate-user.txt @@ -329,6 +329,16 @@ defaults write com.apple.finder 'FXPreferredViewStyle' $' Flwv ' +defaults write com.apple.finder 'NewWindowTarget' $' + + +PfLo +' +defaults write com.apple.finder 'NewWindowTargetPath' $' + + +file:///Library/Apple +' defaults write com.apple.finder 'QuitMenuItem' $' diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix index eae6199d..8da9f4e0 100644 --- a/tests/system-defaults-write.nix +++ b/tests/system-defaults-write.nix @@ -57,6 +57,8 @@ system.defaults.finder.FXPreferredViewStyle = "Flwv"; system.defaults.finder.AppleShowAllExtensions = true; system.defaults.finder.CreateDesktop = false; + system.defaults.finder.NewWindowTarget = "Other"; + system.defaults.finder.NewWindowTargetPath = "file:///Library/Apple"; system.defaults.finder.QuitMenuItem = true; system.defaults.finder._FXShowPosixPathInTitle = true; system.defaults.finder._FXSortFoldersFirst = true; From 21809c4261a421eb06b2d7b3ccd18ebadd921f96 Mon Sep 17 00:00:00 2001 From: April Schleck Date: Sun, 27 Oct 2024 23:37:08 -0700 Subject: [PATCH 056/139] Allow configuring the fn key action --- modules/module-list.nix | 1 + modules/system/defaults-write.nix | 3 ++ modules/system/defaults/hitoolbox.nix | 29 +++++++++++++++++++ .../system-defaults-write/activate-user.txt | 5 ++++ tests/system-defaults-write.nix | 1 + 5 files changed, 39 insertions(+) create mode 100644 modules/system/defaults/hitoolbox.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index effdff76..5477fad6 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -21,6 +21,7 @@ ./system/defaults/clock.nix ./system/defaults/dock.nix ./system/defaults/finder.nix + ./system/defaults/hitoolbox.nix ./system/defaults/screencapture.nix ./system/defaults/screensaver.nix ./system/defaults/alf.nix diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index e7f2c034..7af972d6 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -23,6 +23,7 @@ let menuExtraClock = defaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock; dock = defaultsToList "com.apple.dock" cfg.dock; finder = defaultsToList "com.apple.finder" cfg.finder; + hitoolbox = defaultsToList "com.apple.HIToolbox" cfg.hitoolbox; magicmouse = defaultsToList "com.apple.AppleMultitouchMouse" cfg.magicmouse; magicmouseBluetooth = defaultsToList "com.apple.driver.AppleMultitouchMouse.mouse" cfg.magicmouse; screencapture = defaultsToList "com.apple.screencapture" cfg.screencapture; @@ -76,6 +77,7 @@ in menuExtraClock dock finder + hitoolbox magicmouse magicmouseBluetooth screencapture @@ -99,6 +101,7 @@ in ${concatStringsSep "\n" menuExtraClock} ${concatStringsSep "\n" dock} ${concatStringsSep "\n" finder} + ${concatStringsSep "\n" hitoolbox} ${concatStringsSep "\n" magicmouse} ${concatStringsSep "\n" magicmouseBluetooth} ${concatStringsSep "\n" screencapture} diff --git a/modules/system/defaults/hitoolbox.nix b/modules/system/defaults/hitoolbox.nix new file mode 100644 index 00000000..c2e336b7 --- /dev/null +++ b/modules/system/defaults/hitoolbox.nix @@ -0,0 +1,29 @@ +{ lib, ... }: + +{ + options = { + + system.defaults.hitoolbox.AppleFnUsageType = lib.mkOption { + type = lib.types.nullOr (lib.types.enum [ + "Do Nothing" + "Change Input Source" + "Show Emoji & Symbols" + "Start Dictation" + ]); + apply = key: if key == null then null else { + "Do Nothing" = 0; + "Change Input Source" = 1; + "Show Emoji & Symbols" = 2; + "Start Dictation" = 3; + }.${key}; + default = null; + description = '' + Chooses what happens when you press the Fn key on the keyboard. A restart is required for + this setting to take effect. + + The default is unset ("Show Emoji & Symbols"). + ''; + }; + + }; +} diff --git a/tests/fixtures/system-defaults-write/activate-user.txt b/tests/fixtures/system-defaults-write/activate-user.txt index f3e01a64..34ff7283 100644 --- a/tests/fixtures/system-defaults-write/activate-user.txt +++ b/tests/fixtures/system-defaults-write/activate-user.txt @@ -354,6 +354,11 @@ defaults write com.apple.finder '_FXSortFoldersFirst' $' ' +defaults write com.apple.HIToolbox 'AppleFnUsageType' $' + + +2 +' defaults write com.apple.screencapture 'location' $' diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix index eae6199d..d5e0d08b 100644 --- a/tests/system-defaults-write.nix +++ b/tests/system-defaults-write.nix @@ -61,6 +61,7 @@ system.defaults.finder._FXShowPosixPathInTitle = true; system.defaults.finder._FXSortFoldersFirst = true; system.defaults.finder.FXEnableExtensionChangeWarning = false; + system.defaults.hitoolbox.AppleFnUsageType = "Show Emoji & Symbols"; system.defaults.screencapture.location = "/tmp"; system.defaults.screensaver.askForPassword = true; system.defaults.screensaver.askForPasswordDelay = 5; From 406cb56d06247487386667162131703f7d6cc68f Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 12:01:00 +1100 Subject: [PATCH 057/139] Back out "Add support for submodules in flakes" This backs out commit 5452c8c638b59b5d6b123d81d3fa6bad07d00617. --- pkgs/nix-tools/darwin-rebuild.sh | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index e627b3ce..ba9c2e8b 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -157,19 +157,12 @@ fi # For convenience, use the hostname as the default configuration to # build from the flake. -if [ -n "$flake" ]; then - # Offical regex from https://www.rfc-editor.org/rfc/rfc3986#appendix-B - if [[ "${flake}" =~ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? ]]; then - scheme=${BASH_REMATCH[1]} # eg. http: - authority=${BASH_REMATCH[3]} # eg. //www.ics.uci.edu - path=${BASH_REMATCH[5]} # eg. /pub/ietf/uri/ - queryWithQuestion=${BASH_REMATCH[6]} - fragment=${BASH_REMATCH[9]} - - flake=${scheme}${authority}${path}${queryWithQuestion} - flakeAttr=${fragment} +if [[ -n "$flake" ]]; then + if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then + flake="${BASH_REMATCH[1]}" + flakeAttr="${BASH_REMATCH[2]}" fi - if [ -z "$flakeAttr" ]; then + if [[ -z "$flakeAttr" ]]; then flakeAttr=$(scutil --get LocalHostName) fi flakeAttr=darwinConfigurations.${flakeAttr} @@ -182,16 +175,7 @@ if [ -n "$flake" ]; then cmd=info fi - metadata=$(nix "${flakeFlags[@]}" flake "$cmd" --json "${extraMetadataFlags[@]}" "${extraLockFlags[@]}" -- "$flake") - flake=$(jq -r .url <<<"${metadata}") - - if [ "$(jq -r .resolved.submodules <<<"${metadata}")" = "true" ]; then - if [[ "$flake" == *'?'* ]]; then - flake="${flake}&submodules=1" - else - flake="${flake}?submodules=1" - fi - fi + flake=$(nix "${flakeFlags[@]}" flake "$cmd" --json "${extraMetadataFlags[@]}" "${extraLockFlags[@]}" -- "$flake" | jq -r .url) fi if [ "$action" != build ]; then From 1d8c91b40e82853e76a0a308cfc5ddc5a72667d3 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 12:30:47 +1100 Subject: [PATCH 058/139] darwin-rebuild: do not resolve flake path Backport of https://github.com/NixOS/nixpkgs/commit/c274d045ac254afe96b1f8139e974ada2c42059e Fixes #549 --- pkgs/nix-tools/darwin-rebuild.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index ba9c2e8b..7824913d 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -168,16 +168,6 @@ if [[ -n "$flake" ]]; then flakeAttr=darwinConfigurations.${flakeAttr} fi -if [ -n "$flake" ]; then - if nix "${flakeFlags[@]}" flake metadata --version &>/dev/null; then - cmd=metadata - else - cmd=info - fi - - flake=$(nix "${flakeFlags[@]}" flake "$cmd" --json "${extraMetadataFlags[@]}" "${extraLockFlags[@]}" -- "$flake" | jq -r .url) -fi - if [ "$action" != build ]; then if [ -n "$flake" ]; then extraBuildFlags+=("--no-link") From 53b9de4d6ca51c38299f265630b811fed6d4fd05 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 12:18:02 +1100 Subject: [PATCH 059/139] ci: remove tests to ensure submodules work --- .github/workflows/test.yml | 115 ------------------------------------- 1 file changed, 115 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c7ad8c0a..3dd8bcf3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -153,60 +153,6 @@ jobs: run: | . /etc/static/bashrc darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - - name: Test git submodules - run: | - . /etc/static/bashrc - - mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule} - - pushd /tmp/example-submodule - echo '"hello"' > hello.nix - git init - git add . - git commit -m "add a submodule we will import" - popd - - cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules - cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules - - pushd /tmp/test-nix-darwin-submodules - /usr/bin/sed -i.bak \ - '\#modules = \[#s#configuration#configuration ./simple.nix#' \ - ./flake.nix - /usr/bin/sed -i.bak \ - 's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \ - ./simple.nix - git init - git add flake.nix simple.nix - git \ - -c protocol.file.allow=always \ - submodule add /tmp/example-submodule submodule-test - popd - - # Should fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - # Should also fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=0#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should succeed - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ install-flake-against-unstable: runs-on: macos-12 @@ -236,64 +182,3 @@ jobs: run: | . /etc/static/bashrc darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/nixpkgs-unstable - - name: Test git submodules - run: | - . /etc/static/bashrc - - mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule} - - pushd /tmp/example-submodule - echo '"hello"' > hello.nix - git init - git add . - git commit -m "add a submodule we will import" - popd - - cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules - cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules - - pushd /tmp/test-nix-darwin-submodules - /usr/bin/sed -i.bak \ - '\#modules = \[#s#configuration#configuration ./simple.nix#' \ - ./flake.nix - /usr/bin/sed -i.bak \ - 's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \ - ./simple.nix - git init - git add flake.nix simple.nix - git \ - -c protocol.file.allow=always \ - submodule add /tmp/example-submodule submodule-test - popd - - # Should fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should also fail - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=0#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - && { - printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr - exit 1 - } - - # Should succeed - darwin-rebuild build \ - --flake /tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable - - # Should also succeed - darwin-rebuild build \ - --flake git+file:///tmp/test-nix-darwin-submodules?submodules=1#simple \ - --override-input nix-darwin . \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable From 07db4e57d3596ae6de5877409ac6ec782e69afc8 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 5 Nov 2024 03:21:37 +1100 Subject: [PATCH 060/139] ci: switch to `macos-13` The `macos-12` runner image will be removed by 3 Dec 2024. --- .github/workflows/test.yml | 12 ++++++------ .github/workflows/update-manual.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3dd8bcf3..bb247e94 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: jobs: test-stable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -23,7 +23,7 @@ jobs: - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple test-unstable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -36,7 +36,7 @@ jobs: - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple install-against-stable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -81,7 +81,7 @@ jobs: limit-access-to-actor: true install-against-unstable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -126,7 +126,7 @@ jobs: limit-access-to-actor: true install-flake-against-stable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -155,7 +155,7 @@ jobs: darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} install-flake-against-unstable: - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 30 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index 4bd5a0b2..36e2fd88 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -8,7 +8,7 @@ on: jobs: update-manual: - runs-on: macos-12 + runs-on: macos-13 steps: - name: Checkout repository uses: actions/checkout@v3 From 6ff3a49ceb1c98e96452542a6feadacc477eedff Mon Sep 17 00:00:00 2001 From: zowoq <59103226+zowoq@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:11:14 +1000 Subject: [PATCH 061/139] time: shellcheck fix https://www.shellcheck.net/wiki/SC2143 --- modules/time/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/time/default.nix b/modules/time/default.nix index 28724a55..01c4703b 100644 --- a/modules/time/default.nix +++ b/modules/time/default.nix @@ -7,7 +7,7 @@ let cfg = config.time; timeZone = optionalString (cfg.timeZone != null) '' - if [ -z $(systemsetup -listtimezones | grep "^ ${cfg.timeZone}$") ]; then + if ! systemsetup -listtimezones | grep -q "^ ${cfg.timeZone}$"; then echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2 false fi From 84d14d404325380ec180f580332e8e85df232d06 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 5 Nov 2024 02:59:00 +0000 Subject: [PATCH 062/139] prometheus-node-exporter: fix log permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The daemon won’t start as the assigned user doesn’t have permissions to create the log file. --- .../services/monitoring/prometheus-node-exporter.nix | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/services/monitoring/prometheus-node-exporter.nix b/modules/services/monitoring/prometheus-node-exporter.nix index 752dc0f2..7f580557 100644 --- a/modules/services/monitoring/prometheus-node-exporter.nix +++ b/modules/services/monitoring/prometheus-node-exporter.nix @@ -81,7 +81,8 @@ in { users.users._prometheus-node-exporter = { uid = config.ids.uids._prometheus-node-exporter; gid = config.ids.gids._prometheus-node-exporter; - home = "/var/empty"; + home = "/var/lib/prometheus-node-exporter"; + createHome = true; shell = "/usr/bin/false"; description = "System user for the Prometheus Node exporter"; }; @@ -104,11 +105,14 @@ in { ++ (map (collector: "--collector.${collector}") cfg.enabledCollectors) ++ (map (collector: "--no-collector.${collector}") cfg.disabledCollectors) ) + escapeShellArgs cfg.extraFlags; - serviceConfig = { + serviceConfig = let + logPath = config.users.users._prometheus-node-exporter.home + + "/prometheus-node-exporter.log"; + in { KeepAlive = true; RunAtLoad = true; - StandardErrorPath = "/var/log/prometheus-node-exporter.log"; - StandardOutPath = "/var/log/prometheus-node-exporter.log"; + StandardErrorPath = logPath; + StandardOutPath = logPath; GroupName = "_prometheus-node-exporter"; UserName = "_prometheus-node-exporter"; }; From 897fc37c47d2592c475f8732f3f1a4fbc9f18f9e Mon Sep 17 00:00:00 2001 From: Trevor Opiyo Date: Tue, 5 Nov 2024 08:16:35 -0600 Subject: [PATCH 063/139] Update default.nix Co-authored-by: Michael Hoang --- modules/programs/zsh/default.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index d3b2f5c6..6555bacc 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -117,8 +117,11 @@ in config = mkIf cfg.enable { - warnings = mkIf (cfg.enableFastSyntaxHighlighting && cfg.enableSyntaxHighlighting) [ - "zsh-fast-syntax-highlighting and zsh-syntax-highlighting are mutually exclusive. Disable one of them." + assertions = [ + { + assertion = !(cfg.enableSyntaxHighlighting && cfg.enableFastSyntaxHighlighting); + message = "zsh-syntax-highlighting and zsh-fast-syntax-highlighting are mutually exclusive, please disable one of them."; + } ]; environment.systemPackages = [ # Include zsh package From 48e5c8de1a4575441b46cb174afebfa02732c0ff Mon Sep 17 00:00:00 2001 From: Trevor Opiyo Date: Wed, 6 Nov 2024 01:10:24 -0600 Subject: [PATCH 064/139] Update modules/programs/zsh/default.nix Changes added by Enzime Co-authored-by: Michael Hoang --- modules/programs/zsh/default.nix | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index 6555bacc..652ba583 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -108,11 +108,7 @@ in description = "Enable zsh-syntax-highlighting."; }; - programs.zsh.enableFastSyntaxHighlighting = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc "Enable zsh-fast-syntax-highlighting."; - }; + programs.zsh.enableFastSyntaxHighlighting = mkEnableOption "zsh-fast-syntax-highlighting"; }; config = mkIf cfg.enable { From 1a8c6cac8c7a9537fcf928714ca3778f4c59c2fd Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 21 Oct 2024 11:16:49 +1100 Subject: [PATCH 065/139] release: fix tests not running on `aarch64-darwin` --- release.nix | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/release.nix b/release.nix index a9105912..835e251f 100644 --- a/release.nix +++ b/release.nix @@ -1,14 +1,11 @@ { nixpkgs ? -, supportedSystems ? [ "x86_64-darwin" ] +, system ? builtins.currentSystem +, supportedSystems ? [ "x86_64-darwin" "aarch64-darwin" ] , scrubJobs ? true }: let - inherit (release) mapTestOn packagePlatforms pkgs all linux darwin; - - system = "x86_64-darwin"; - - mapPlatforms = systems: pkgs.lib.mapAttrs (n: v: systems); + inherit (release) mapTestOn packagePlatforms pkgs; buildFromConfig = configuration: sel: sel (import ./. { inherit nixpkgs configuration system; }).config; From e11dd028d38bd09ec4a1119742d735512775c8a6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 21:13:53 +1100 Subject: [PATCH 066/139] release: remove `unstable` job This job is actually in Nixpkgs at https://github.com/NixOS/nixpkgs/blob/2d2a9ddbe3f2c00747398f3dc9b05f7f2ebb0f53/pkgs/top-level/release.nix#L90-L139. --- release.nix | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/release.nix b/release.nix index 835e251f..cb9e41ca 100644 --- a/release.nix +++ b/release.nix @@ -75,26 +75,6 @@ let }) (config: config.system.build.manual); jobs = { - - unstable = pkgs.releaseTools.aggregate { - name = "darwin-${pkgs.lib.nixpkgsVersion}"; - constituents = - [ jobs.stdenv.x86_64-darwin - jobs.bash.x86_64-darwin - jobs.zsh.x86_64-darwin - jobs.nix.x86_64-darwin - jobs.reattach-to-user-namespace.x86_64-darwin - jobs.tmux.x86_64-darwin - jobs.nano.x86_64-darwin - jobs.vim.x86_64-darwin - jobs.emacs.x86_64-darwin - jobs.examples.hydra.x86_64-darwin - jobs.examples.lnl.x86_64-darwin - jobs.examples.simple.x86_64-darwin - ]; - meta.description = "Release-critical builds for the darwin channel"; - }; - manualHTML = manual.manualHTML; manpages = manual.manpages; options = manual.optionsJSON; From 8a03b1850b3adf005da3f35e696e801d700740ec Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 08:32:31 +1100 Subject: [PATCH 067/139] release: remove package jobs --- release.nix | 130 ++++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 71 deletions(-) diff --git a/release.nix b/release.nix index cb9e41ca..b432a29d 100644 --- a/release.nix +++ b/release.nix @@ -5,7 +5,7 @@ }: let - inherit (release) mapTestOn packagePlatforms pkgs; + inherit (release) pkgs; buildFromConfig = configuration: sel: sel (import ./. { inherit nixpkgs configuration system; }).config; @@ -63,79 +63,67 @@ let packageSet = import nixpkgs; }; - packageSet = { - inherit (pkgs) - stdenv bash zsh nix - tmux reattach-to-user-namespace - nano emacs vim; - }; - manual = buildFromConfig ({ lib, config, ... }: { system.stateVersion = lib.mkDefault config.system.maxStateVersion; }) (config: config.system.build.manual); - jobs = { - manualHTML = manual.manualHTML; - manpages = manual.manpages; - options = manual.optionsJSON; +in { + manualHTML = manual.manualHTML; + manpages = manual.manpages; + options = manual.optionsJSON; - examples.hydra = makeSystem ./modules/examples/hydra.nix; - examples.lnl = makeSystem ./modules/examples/lnl.nix; - examples.simple = makeSystem ./modules/examples/simple.nix; + examples.hydra = makeSystem ./modules/examples/hydra.nix; + examples.lnl = makeSystem ./modules/examples/lnl.nix; + examples.simple = makeSystem ./modules/examples/simple.nix; - 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; - tests.launchd-daemons = makeTest ./tests/launchd-daemons.nix; - 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.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix; - tests.programs-ssh = makeTest ./tests/programs-ssh.nix; - tests.programs-tmux = makeTest ./tests/programs-tmux.nix; - tests.programs-zsh = makeTest ./tests/programs-zsh.nix; - tests.programs-ssh-empty-known-hosts = makeTest ./tests/programs-ssh-empty-known-hosts.nix; - tests.security-pki = makeTest ./tests/security-pki.nix; - tests.services-activate-system = makeTest ./tests/services-activate-system.nix; - tests.services-activate-system-changed-label-prefix = makeTest ./tests/services-activate-system-changed-label-prefix.nix; - tests.services-buildkite-agent = makeTest ./tests/services-buildkite-agent.nix; - tests.services-github-runners = makeTest ./tests/services-github-runners.nix; - tests.services-lorri = makeTest ./tests/services-lorri.nix; - tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix; - tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix; - tests.services-aerospace = makeTest ./tests/services-aerospace.nix; - tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix; - tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix; - tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix; - tests.services-nix-optimise = makeTest ./tests/services-nix-optimise.nix; - tests.services-nextdns = makeTest ./tests/services-nextdns.nix; - tests.services-netdata = makeTest ./tests/services-netdata.nix; - tests.services-ofborg = makeTest ./tests/services-ofborg.nix; - tests.services-offlineimap = makeTest ./tests/services-offlineimap.nix; - tests.services-privoxy = makeTest ./tests/services-privoxy.nix; - tests.services-redis = makeTest ./tests/services-redis.nix; - tests.services-skhd = makeTest ./tests/services-skhd.nix; - tests.services-spacebar = makeTest ./tests/services-spacebar.nix; - tests.services-spotifyd = makeTest ./tests/services-spotifyd.nix; - tests.services-synapse-bt = makeTest ./tests/services-synapse-bt.nix; - tests.services-synergy = makeTest ./tests/services-synergy.nix; - tests.services-yabai = makeTest ./tests/services-yabai.nix; - tests.services-jankyborders = makeTest ./tests/services-jankyborders.nix; - tests.system-defaults-write = makeTest ./tests/system-defaults-write.nix; - tests.system-environment = makeTest ./tests/system-environment.nix; - tests.system-keyboard-mapping = makeTest ./tests/system-keyboard-mapping.nix; - tests.system-packages = makeTest ./tests/system-packages.nix; - tests.system-path = makeTest ./tests/system-path.nix; - tests.system-shells = makeTest ./tests/system-shells.nix; - tests.users-groups = makeTest ./tests/users-groups.nix; - tests.users-packages = makeTest ./tests/users-packages.nix; - tests.fonts = makeTest ./tests/fonts.nix; - - } - // (mapTestOn (packagePlatforms packageSet)); - -in - jobs + 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; + tests.launchd-daemons = makeTest ./tests/launchd-daemons.nix; + 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.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix; + tests.programs-ssh = makeTest ./tests/programs-ssh.nix; + tests.programs-tmux = makeTest ./tests/programs-tmux.nix; + tests.programs-zsh = makeTest ./tests/programs-zsh.nix; + tests.programs-ssh-empty-known-hosts = makeTest ./tests/programs-ssh-empty-known-hosts.nix; + tests.security-pki = makeTest ./tests/security-pki.nix; + tests.services-activate-system = makeTest ./tests/services-activate-system.nix; + tests.services-activate-system-changed-label-prefix = makeTest ./tests/services-activate-system-changed-label-prefix.nix; + tests.services-buildkite-agent = makeTest ./tests/services-buildkite-agent.nix; + tests.services-github-runners = makeTest ./tests/services-github-runners.nix; + tests.services-lorri = makeTest ./tests/services-lorri.nix; + tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix; + tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix; + tests.services-aerospace = makeTest ./tests/services-aerospace.nix; + tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix; + tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix; + tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix; + tests.services-nix-optimise = makeTest ./tests/services-nix-optimise.nix; + tests.services-nextdns = makeTest ./tests/services-nextdns.nix; + tests.services-netdata = makeTest ./tests/services-netdata.nix; + tests.services-ofborg = makeTest ./tests/services-ofborg.nix; + tests.services-offlineimap = makeTest ./tests/services-offlineimap.nix; + tests.services-privoxy = makeTest ./tests/services-privoxy.nix; + tests.services-redis = makeTest ./tests/services-redis.nix; + tests.services-skhd = makeTest ./tests/services-skhd.nix; + tests.services-spacebar = makeTest ./tests/services-spacebar.nix; + tests.services-spotifyd = makeTest ./tests/services-spotifyd.nix; + tests.services-synapse-bt = makeTest ./tests/services-synapse-bt.nix; + tests.services-synergy = makeTest ./tests/services-synergy.nix; + tests.services-yabai = makeTest ./tests/services-yabai.nix; + tests.services-jankyborders = makeTest ./tests/services-jankyborders.nix; + tests.system-defaults-write = makeTest ./tests/system-defaults-write.nix; + tests.system-environment = makeTest ./tests/system-environment.nix; + tests.system-keyboard-mapping = makeTest ./tests/system-keyboard-mapping.nix; + tests.system-packages = makeTest ./tests/system-packages.nix; + tests.system-path = makeTest ./tests/system-path.nix; + tests.system-shells = makeTest ./tests/system-shells.nix; + tests.users-groups = makeTest ./tests/users-groups.nix; + tests.users-packages = makeTest ./tests/users-packages.nix; + tests.fonts = makeTest ./tests/fonts.nix; +} From c904f6cdcb02c85181cf478496b0b9a78308133a Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 21:43:36 +1100 Subject: [PATCH 068/139] release: rename `release` to `release-lib` to match NixOS https://github.com/NixOS/nixpkgs/blob/2d2a9ddbe3f2c00747398f3dc9b05f7f2ebb0f53/pkgs/top-level/release.nix#L56-L58 --- release.nix | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/release.nix b/release.nix index b432a29d..c4d4c583 100644 --- a/release.nix +++ b/release.nix @@ -5,7 +5,12 @@ }: let - inherit (release) pkgs; + release-lib = import (nixpkgs + "/pkgs/top-level/release-lib.nix") { + inherit supportedSystems scrubJobs system; + packageSet = import nixpkgs; + }; + + inherit (release-lib) pkgs; buildFromConfig = configuration: sel: sel (import ./. { inherit nixpkgs configuration system; }).config; @@ -58,11 +63,6 @@ let in buildFromConfig configuration (config: config.system.build.run-test); - release = import (nixpkgs + "/pkgs/top-level/release-lib.nix") { - inherit supportedSystems scrubJobs; - packageSet = import nixpkgs; - }; - manual = buildFromConfig ({ lib, config, ... }: { system.stateVersion = lib.mkDefault config.system.maxStateVersion; }) (config: config.system.build.manual); From 56ac6182d3fcb449db620fac0658eedd56aa1597 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 13:38:11 +1100 Subject: [PATCH 069/139] release: remove unnecessary use of `release-lib` --- release.nix | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/release.nix b/release.nix index c4d4c583..cba42101 100644 --- a/release.nix +++ b/release.nix @@ -5,19 +5,10 @@ }: let - release-lib = import (nixpkgs + "/pkgs/top-level/release-lib.nix") { - inherit supportedSystems scrubJobs system; - packageSet = import nixpkgs; - }; - - inherit (release-lib) pkgs; - buildFromConfig = configuration: sel: sel (import ./. { inherit nixpkgs configuration system; }).config; - makeSystem = configuration: pkgs.lib.genAttrs [ system ] (system: - buildFromConfig configuration (config: config.system.build.toplevel) - ); + makeSystem = configuration: buildFromConfig configuration (config: config.system.build.toplevel); makeTest = test: let From dd48cbd7766baba246f0b2e2bd42baf67e0005d6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 13:40:00 +1100 Subject: [PATCH 070/139] examples: fix evaluation --- modules/examples/hydra.nix | 2 ++ modules/examples/lnl.nix | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/examples/hydra.nix b/modules/examples/hydra.nix index 31604985..edbb0299 100644 --- a/modules/examples/hydra.nix +++ b/modules/examples/hydra.nix @@ -53,4 +53,6 @@ in chown hydra:hydra ~hydra ~hydra/.ssh ~hydra/.ssh/authorized_keys echo "ok" ''; + + system.stateVersion = 5; } diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index d944158a..f264e1ac 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -50,13 +50,11 @@ pkgs.gnupg pkgs.htop pkgs.jq - pkgs.mosh pkgs.ripgrep pkgs.shellcheck pkgs.vault pkgs.qes - pkgs.darwin-zsh-completions ]; services.yabai.enable = true; @@ -331,4 +329,6 @@ nix.configureBuildUsers = true; nix.nrBuildUsers = 32; + + system.stateVersion = 5; } From 569153467be5f438e4f932a09bfba79adcecf856 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 14:00:05 +1100 Subject: [PATCH 071/139] ofborg: automatically add `ofborg` to `known{Users,Groups}` --- modules/examples/ofborg.nix | 5 ----- modules/services/ofborg/default.nix | 10 ++++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/modules/examples/ofborg.nix b/modules/examples/ofborg.nix index 6cef6e79..ed928b73 100644 --- a/modules/examples/ofborg.nix +++ b/modules/examples/ofborg.nix @@ -18,11 +18,6 @@ with lib; nix.gc.automatic = true; nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))"; - # Manage user for ofborg, this enables creating/deleting users - # depending on what modules are enabled. - users.knownGroups = [ "ofborg" ]; - users.knownUsers = [ "ofborg" ]; - # Used for backwards compatibility, please read the changelog before changing. # $ darwin-rebuild changelog system.stateVersion = 5; diff --git a/modules/services/ofborg/default.nix b/modules/services/ofborg/default.nix index 4c356158..8959cc84 100644 --- a/modules/services/ofborg/default.nix +++ b/modules/services/ofborg/default.nix @@ -46,12 +46,6 @@ in }; config = mkIf cfg.enable { - - assertions = [ - { assertion = elem "ofborg" config.users.knownGroups; message = "set users.knownGroups to enable ofborg group"; } - { assertion = elem "ofborg" config.users.knownUsers; message = "set users.knownUsers to enable ofborg user"; } - ]; - warnings = mkIf (isDerivation cfg.configFile) [ "services.ofborg.configFile is a derivation, credentials will be world readable" ]; @@ -87,9 +81,13 @@ in users.users.ofborg.shell = "/bin/bash"; users.users.ofborg.description = "OfBorg service user"; + users.knownUsers = [ "ofborg" ]; + users.groups.ofborg.gid = mkDefault 531; users.groups.ofborg.description = "Nix group for OfBorg service"; + users.knownGroups = [ "ofborg" ]; + # FIXME: create logfiles automatically if defined. system.activationScripts.preActivation.text = '' mkdir -p '${user.home}' From c13549d7a632fc107bc8802463806fc2002c9c54 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 13:40:00 +1100 Subject: [PATCH 072/139] examples: drop `ofborg` example We decided to drop this example as the package is not available in Nixpkgs and we won't be able to import it easily and keep this example evaluating as a useful smoke test. The code in this example is already documented under `services.ofborg.*` so any interested users can still find out how to set up `ofborg`. --- flake.nix | 1 - modules/examples/ofborg.nix | 24 ------------------------ 2 files changed, 25 deletions(-) delete mode 100644 modules/examples/ofborg.nix diff --git a/flake.nix b/flake.nix index 59db4ffb..8d50f952 100644 --- a/flake.nix +++ b/flake.nix @@ -48,7 +48,6 @@ darwinModules.hydra = ./modules/examples/hydra.nix; darwinModules.lnl = ./modules/examples/lnl.nix; - darwinModules.ofborg = ./modules/examples/ofborg.nix; darwinModules.simple = ./modules/examples/simple.nix; templates.default = { diff --git a/modules/examples/ofborg.nix b/modules/examples/ofborg.nix deleted file mode 100644 index ed928b73..00000000 --- a/modules/examples/ofborg.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -{ - # Logs are enabled by default. - # $ tail -f /var/log/ofborg.log - services.ofborg.enable = true; - # services.ofborg.configFile = "/var/lib/ofborg/config.json"; - - # $ nix-channel --add https://github.com/NixOS/ofborg/archive/released.tar.gz ofborg - # $ nix-channel --update - services.ofborg.package = (import {}).ofborg.rs; - - # Keep nix-daemon updated. - services.nix-daemon.enable = true; - - nix.gc.automatic = true; - nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))"; - - # Used for backwards compatibility, please read the changelog before changing. - # $ darwin-rebuild changelog - system.stateVersion = 5; -} From 68637ee7dbdb194755697930c36272ad115af4a6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 21:52:58 +1100 Subject: [PATCH 073/139] flake: expose `jobs` from `release.nix` as a flattened attrset --- .github/workflows/test.yml | 8 ++++---- .github/workflows/update-manual.yml | 2 +- flake.nix | 23 +++++++---------------- release.nix | 6 +++--- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bb247e94..709edd35 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,8 +19,8 @@ jobs: with: install_url: https://releases.nixos.org/nix/nix-2.18.8/install - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A manpages - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple + - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A docs + - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples test-unstable: runs-on: macos-13 @@ -32,8 +32,8 @@ jobs: with: install_url: https://releases.nixos.org/nix/nix-2.24.9/install - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A manpages - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple + - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A docs + - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples install-against-stable: runs-on: macos-13 diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index 36e2fd88..19638a21 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -21,7 +21,7 @@ jobs: - name: Build manual run: | - nix-build ./release.nix -I nixpkgs=channel:nixpkgs-24.05-darwin -I darwin=. -A manualHTML + nix build .#manualHTML --override-input nixpkgs nixpkgs/nixpkgs-24.05-darwin - name: Push update to manual run: | diff --git a/flake.nix b/flake.nix index 8d50f952..48dc3121 100644 --- a/flake.nix +++ b/flake.nix @@ -1,9 +1,12 @@ { - # WARNING this is very much still experimental. description = "A collection of darwin modules"; outputs = { self, nixpkgs }: let forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ]; + + jobs = forAllSystems (system: import ./release.nix { + inherit nixpkgs system; + }); in { lib = { evalConfig = import ./eval-config.nix; @@ -55,21 +58,7 @@ description = "nix flake init -t nix-darwin"; }; - checks = forAllSystems (system: let - simple = self.lib.darwinSystem { - modules = [ - self.darwinModules.simple - { nixpkgs.hostPlatform = system; } - ]; - }; - in { - simple = simple.system; - - inherit (simple.config.system.build.manual) - optionsJSON - manualHTML - manpages; - }); + checks = forAllSystems (system: jobs.${system}.tests // jobs.${system}.examples); packages = forAllSystems (system: let pkgs = import nixpkgs { @@ -80,6 +69,8 @@ default = self.packages.${system}.darwin-rebuild; inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller; + + inherit (jobs.${system}.docs) manualHTML manpages optionsJSON; }); }; } diff --git a/release.nix b/release.nix index cba42101..18fb239d 100644 --- a/release.nix +++ b/release.nix @@ -59,9 +59,9 @@ let }) (config: config.system.build.manual); in { - manualHTML = manual.manualHTML; - manpages = manual.manpages; - options = manual.optionsJSON; + docs = { + inherit (manual) manualHTML manpages optionsJSON; + }; examples.hydra = makeSystem ./modules/examples/hydra.nix; examples.lnl = makeSystem ./modules/examples/lnl.nix; From e0f243d17e5c6281b2541c79b52be0270be9a360 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 08:42:12 +1100 Subject: [PATCH 074/139] ci: run nix flake check --- .github/workflows/test.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 709edd35..176d56fd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,9 +18,7 @@ jobs: uses: cachix/install-nix-action@v30 with: install_url: https://releases.nixos.org/nix/nix-2.18.8/install - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A docs - - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples + - run: nix flake check --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} test-unstable: runs-on: macos-13 @@ -31,9 +29,7 @@ jobs: uses: cachix/install-nix-action@v30 with: install_url: https://releases.nixos.org/nix/nix-2.24.9/install - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A docs - - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples + - run: nix flake check --override-input nixpkgs nixpkgs/nixpkgs-unstable install-against-stable: runs-on: macos-13 From 37b591bd8b3ca9641a8aff165f30927755b5dc20 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 11:53:47 +1100 Subject: [PATCH 075/139] ci: remove unused workflows --- .github/workflows/build.yml | 18 ------------------ .github/workflows/debug.yml | 23 ----------------------- 2 files changed, 41 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/debug.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 1cb24265..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: "Build" -on: - # curl -fsSL -XPOST \ - # -H "Accept: application/vnd.github.everest-preview+json" \ - # -H "Authorization: token $GITHUB_TOKEN" \ - # --data '{"event_type": "build", "client_payload": {"args": "-f channel:nixpkgs-unstable hello"}}' \ - # https://api.github.com/repos/LnL7/nix-darwin/dispatches - repository_dispatch: - types: - - build -jobs: - build: - runs-on: macos-12 - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v22 - - run: | - nix build ${{ github.event.client_payload.args }} -vL diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml deleted file mode 100644 index 7535f713..00000000 --- a/.github/workflows/debug.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: "Debug" -on: - # curl -fsSL -XPOST \ - # -H "Accept: application/vnd.github.everest-preview+json" \ - # -H "Authorization: token $GITHUB_TOKEN" \ - # --data '{"event_type": "debug"}' \ - # https://api.github.com/repos/LnL7/nix-darwin/dispatches - repository_dispatch: - types: - - debug -jobs: - debug: - runs-on: macos-12 - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v22 - - run: | - nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs - nix-channel --update - - run: | - nix-shell -A installer - nix-shell -A installer.check - - uses: mxschmitt/action-tmate@v3 From 223a920ab457160a245a588f4191f2b6782b3957 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 14:37:59 +1100 Subject: [PATCH 076/139] ci: upgrade `actions/checkout` --- .github/workflows/test.yml | 12 ++++++------ .github/workflows/update-manual.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 176d56fd..ce176ebe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix corresponding to latest stable channel uses: cachix/install-nix-action@v30 with: @@ -24,7 +24,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix from current unstable channel uses: cachix/install-nix-action@v30 with: @@ -35,7 +35,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix corresponding to latest stable channel uses: cachix/install-nix-action@v30 with: @@ -80,7 +80,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix from current unstable channel uses: cachix/install-nix-action@v30 with: @@ -125,7 +125,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix version corresponding to latest stable channel uses: cachix/install-nix-action@v30 with: @@ -154,7 +154,7 @@ jobs: runs-on: macos-13 timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install nix from current unstable channel uses: cachix/install-nix-action@v30 with: diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index 19638a21..a2f93822 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -11,7 +11,7 @@ jobs: runs-on: macos-13 steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # So that we fetch all branches, since we need to checkout the `gh-pages` branch later. fetch-depth: 0 From 2af06b086283be3ab3824a86f35f6301c95b372b Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 22:02:31 +1100 Subject: [PATCH 077/139] examples: clean up --- modules/examples/hydra.nix | 15 +++------------ modules/examples/lnl.nix | 9 +-------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/modules/examples/hydra.nix b/modules/examples/hydra.nix index edbb0299..eb1c5d9b 100644 --- a/modules/examples/hydra.nix +++ b/modules/examples/hydra.nix @@ -1,25 +1,16 @@ { config, lib, pkgs, ... }: -with lib; - let - environment = concatStringsSep " " + environment = lib.concatStringsSep " " [ "NIX_REMOTE=daemon" "NIX_SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; in { - # Create /etc/bashrc that loads the nix-darwin environment. - programs.bash.enable = true; - programs.bash.completion.enable = false; - - # Recreate /run/current-system symlink after boot. - services.activate-system.enable = true; - services.nix-daemon.enable = true; - nix.settings.substituters = [ http://cache1 ]; + nix.settings.substituters = [ "http://cache1" ]; nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; nix.settings.trusted-users = [ "@admin" "@hydra" ]; @@ -31,7 +22,7 @@ in nix.gc.automatic = true; nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))"; - environment.etc."per-user/hydra/ssh/authorized_keys".text = concatStringsSep "\n" + environment.etc."per-user/hydra/ssh/authorized_keys".text = lib.concatStringsSep "\n" [ "command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCVsc0pHGsskoayziMhA2e59bHPWe0bbKgusmqhuJFBGQ1BAk9UmPzKCWE3nCiV6CLD1+SygVkBjb06DYtc+94BnzviCa9qZtL0G4+2vhp6x8OvXh8xlf/eWw3k5MWlvu+kjJFpbW8wHWTiUqzH+uEeHklAosT0lFNjiIYd/Vs3JAezhUR62a6c7ZjWOd5F7ALGEKzOiwC4i37kSgGsIWNCbe0Ku7gyr718zhMGeyxax6saHhnkSpIB+7d6oHhKeiJSFMWctNmz1/qxXUPbxNaJvqgdKlVHhN+B7x/TIbkVr5pTC59Okx9LTcpflFIv79VT+Gf1K7VypZpSvJjG0xFRt8iDs1+ssWFBfvpo94vUbZ+ZwMDcBGR5iJeO41Gj5fYn5aaDl32RXfJ9Fkwael1L6pcXtkIc66jk+KQQpgoeNj8Y3Emntpqva/2AM41wDDvr5tKp5KhEKFLM95CoiWq+g88pZLcpqLK7wooDVqNkVUEbMaj9lBN0AzU9mcsIRGvTa6CmWAdBvwqS2fRZD97Oarqct9AWgb0X6mOUq9BJNi4i4xvjgnVkylLwtLUnibR/PeXMtkb9bv6BEZXNf5ACqxSjKXJyaIHI65I5TILCr5eEgaujgvmkREn6U3T1NZAUIeVe9aVYLqehYh79OHUBzggoHqidRrXBB/6zdg9UgQ==" "command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnubA1pRqlpoAXkZ1q5nwhqi1RY2z840wFLFDj7vAMSups9E2U8PNIVtuVYApZpkBWIpzD4GGbQTF5Itnu5uBpJswc2Yat9yGWO/guuVyXIaRoBIM0Pg1WBWcWsz+k4rNludu9UQ74FHqEiqZIuIuOcgV+RIZn8xQlGt2kUqN9TWboHhZz8Zhx7EtGSJH6MJRLn3mA/pPjOF6k1jiiFG1pVDuqBTZPANkelWYCWAJ46jCyhxXltWE/jkBYGc/XbB8yT7DFE1XC6TVsSEp68R9PhVG3yqxqY06sniEyduSoGt/TDr6ycERd93bvLElXFATes85YiFszeaUgayYSKwQPe0q7YeHMhIXL0UYJYaKVVgT9saFDiHDzde7kKe+NA+J4+TbIk7Y/Ywn0jepsYV13M7TyEqgqbu9fvVGF3JI9+4g0m1gAzHTa7n6iiAedtz+Pi79uCEpRD2hWSSoLWroyPlep8j1p2tygtFsrieePEukesoToCTwqg1Ejnjh+yKdtUbc6xpyRvl3hKeO8QbCpfaaVd27e4vE4lP2JMW6nOo8b0wlVXQIFe5K2zh52q1MSwhLAq6Kg8oPmgj0lru4IivmPc+/NVwd3Qj3E9ZB8LRfTesfbcxHrC8lF5dL/QpLMeLwebrwCxL19gI0kxmDIaUQuHSyP3B2z+EmBKcN/Xw==" ]; diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index f264e1ac..dccae077 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -1,10 +1,6 @@ { config, lib, inputs, pkgs, ... }: { - # imports = [ ~/.config/nixpkgs/darwin/local-configuration.nix ]; - - # system.patches = [ ./pam.patch ]; - system.defaults.NSGlobalDomain.AppleKeyboardUIMode = 3; system.defaults.NSGlobalDomain.ApplePressAndHoldEnabled = false; system.defaults.NSGlobalDomain.InitialKeyRepeat = 10; @@ -52,7 +48,6 @@ pkgs.jq pkgs.ripgrep pkgs.shellcheck - pkgs.vault pkgs.qes ]; @@ -94,7 +89,7 @@ ''; nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; - nix.settings.trusted-substituters = [ https://d3i7ezr9vxxsfy.cloudfront.net ]; + nix.settings.trusted-substituters = [ "https://d3i7ezr9vxxsfy.cloudfront.net" ]; nix.settings.sandbox = true; nix.settings.extra-sandbox-paths = [ "/private/tmp" "/private/var/tmp" "/usr/bin/env" ]; @@ -300,8 +295,6 @@ fi ''; - # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; - nixpkgs.config.allowUnfree = true; nixpkgs.overlays = [ From 3ea11449387edeac72fbd7791d106af7553be6e2 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 11:11:56 +1100 Subject: [PATCH 078/139] system: run `shellcheck` on `activate` and `activate-user` scripts --- modules/system/default.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/system/default.nix b/modules/system/default.nix index 285936c5..a1862fae 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -92,6 +92,8 @@ in name = "darwin-system-${cfg.darwinLabel}"; preferLocalBuild = true; + nativeBuildInputs = [ pkgs.shellcheck ]; + activationScript = cfg.activationScripts.script.text; activationUserScript = cfg.activationScripts.userScript.text; inherit (cfg) darwinLabel; @@ -133,6 +135,8 @@ in chmod u+x $out/activate-user unset activationUserScript + shellcheck $out/activate $out/activate-user + echo -n "$systemConfig" > $out/systemConfig echo -n "$darwinLabel" > $out/darwin-version From 9afef9950f28780ff24908496c36f27826a601cf Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 29 Oct 2024 00:09:37 +1100 Subject: [PATCH 079/139] checks: move manual `/run` instructions to activation --- modules/system/base.nix | 54 ++++++++++++++++++++++++++++----------- modules/system/checks.nix | 24 +++-------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/modules/system/base.nix b/modules/system/base.nix index 44a8d912..43c9d7ff 100644 --- a/modules/system/base.nix +++ b/modules/system/base.nix @@ -2,22 +2,46 @@ { system.activationScripts.createRun.text = '' - if ! test -L /run; then - if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then + if [[ ! -L /run ]]; then + # This file doesn't exist by default on macOS and is only supported after 10.15 + # however every system with Nix installed should have this file otherwise `/nix` + # wouldn't exist. + if [[ -e /etc/synthetic.conf ]]; then + if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then echo "setting up /run via /etc/synthetic.conf..." - echo -e "run\tprivate/var/run" | sudo tee -a /etc/synthetic.conf >/dev/null - sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true - sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true - if ! test -L /run; then - echo "warning: apfs.util failed to symlink /run" - fi - fi - if ! test -L /run; then - echo "setting up /run..." - sudo ln -sfn private/var/run /run - fi - if ! test -L /run; then - echo "warning: failed to symlink /run" + printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null + fi + + # for Catalina (10.15) + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true + # for Big Sur (11.0) + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true + + if [[ ! -L /run ]]; then + printf >&2 'error: apfs.util failed to symlink /run, aborting activation\n' + printf >&2 'To create a symlink from /run to /var/run, please run:\n' + printf >&2 '\n' + printf >&2 "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" + printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B # For Catalina\n' + printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later\n' >&2 + printf >&2 '\n' + printf >&2 'The current contents of /etc/synthetic.conf is:\n' + printf >&2 '\n' + sudo sed 's/^/ /' /etc/synthetic.conf >&2 + printf >&2 '\n' + exit 1 + fi + else + echo "setting up /run..." + sudo ln -sfn private/var/run /run + + if [[ ! -L /run ]]; then + printf >&2 'error: failed to symlink /run, aborting activation\n' + printf >&2 'To create a symlink from /run to /var/run, please run:\n' + printf >&2 '\n' + printf >&2 '$ sudo ln -sfn private/var/link /run\n' + exit 1 + fi fi fi ''; diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 497cd9a9..6d7ccc00 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -22,25 +22,9 @@ let ''; runLink = '' - if ! test -e /run; then - echo "error: Directory /run does not exist, aborting activation" >&2 - echo "Create a symlink to /var/run with:" >&2 - if test -e /etc/synthetic.conf; then - echo >&2 - echo "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" >&2 - echo "$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B # For Catalina" >&2 - echo "$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later" >&2 - echo >&2 - echo "The current contents of /etc/synthetic.conf is:" >&2 - echo >&2 - sed 's/^/ /' /etc/synthetic.conf >&2 - echo >&2 - else - echo >&2 - echo "$ sudo ln -s private/var/run /run" >&2 - echo >&2 - fi - exit 2 + if [[ ! -e /run ]]; then + printf >&2 'error: directory /run does not exist, aborting activation\n' + exit 1 fi ''; @@ -59,7 +43,7 @@ let exit 2 fi ''; - + preSequoiaBuildUsers = '' ${lib.optionalString config.nix.configureBuildUsers '' # Don’t complain when we’re about to migrate old‐style build users… From 041996803af5497fb000e3f79621fa5bb6995057 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 29 Oct 2024 00:09:37 +1100 Subject: [PATCH 080/139] treewide: fix shellcheck warnings and errors --- modules/networking/default.nix | 1 + modules/system/checks.nix | 8 +++++--- modules/users/default.nix | 7 ++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/networking/default.nix b/modules/networking/default.nix index b53a9e4a..7a81ca1c 100644 --- a/modules/networking/default.nix +++ b/modules/networking/default.nix @@ -118,6 +118,7 @@ in echo "configuring networking..." >&2 ${optionalString (cfg.computerName != null) '' + # shellcheck disable=SC1112 scutil --set ComputerName ${escapeShellArg cfg.computerName} ''} ${optionalString (cfg.hostName != null) '' diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 6d7ccc00..ec6e3b5d 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -88,7 +88,7 @@ let buildUsers = '' buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true - if [ -z $buildUser ]; then + 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 @@ -104,7 +104,7 @@ let buildGroupID = '' buildGroupID=$(dscl . -read /Groups/nixbld PrimaryGroupID | awk '{print $2}') expectedBuildGroupID=${toString config.ids.gids.nixbld} - if [[ $buildGroupID != $expectedBuildGroupID ]]; then + if [[ $buildGroupID != "$expectedBuildGroupID" ]]; then printf >&2 '\e[1;31merror: Build user group has mismatching GID, aborting activation\e[0m\n' printf >&2 'The default Nix build user group ID was changed from 30000 to 350.\n' printf >&2 'You are currently managing Nix build users with nix-darwin, but your\n' @@ -114,6 +114,7 @@ let printf >&2 'Possible causes include setting up a new Nix installation with an\n' printf >&2 'existing nix-darwin configuration, setting up a new nix-darwin\n' printf >&2 'installation with an existing Nix installation, or manually increasing\n' + # shellcheck disable=SC2016 printf >&2 'your `system.stateVersion` setting.\n' printf >&2 '\n' printf >&2 'You can set the configured group ID to match the actual value:\n' @@ -266,6 +267,7 @@ let if [[ -d /etc/ssh/authorized_keys.d ]]; then printf >&2 '\e[1;31merror: /etc/ssh/authorized_keys.d exists, aborting activation\e[0m\n' printf >&2 'SECURITY NOTICE: The previous implementation of the\n' + # shellcheck disable=SC2016 printf >&2 '`users.users..openssh.authorizedKeys.*` options would not delete\n' printf >&2 'authorized keys files when the setting for a given user was removed.\n' printf >&2 '\n' @@ -334,7 +336,7 @@ in system.activationScripts.checks.text = '' ${cfg.text} - if test ''${checkActivation:-0} -eq 1; then + if [[ "''${checkActivation:-0}" -eq 1 ]]; then echo "ok" >&2 exit 0 fi diff --git a/modules/users/default.nix b/modules/users/default.nix index 6a1cd2e6..d15deac6 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -115,6 +115,7 @@ in if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then if [[ -n "$SSH_CONNECTION" ]]; then printf >&2 '\e[1;31merror: users cannot be %s over SSH without Full Disk Access, aborting activation\e[0m\n' "$2" + # shellcheck disable=SC2016 printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access over SSH.\n' "$1" "$2" printf >&2 'You can either:\n' printf >&2 '\n' @@ -122,6 +123,7 @@ in printf >&2 '\n' printf >&2 'or\n' printf >&2 '\n' + # shellcheck disable=SC2016 printf >&2 ' run `darwin-rebuild` in a graphical session.\n' printf >&2 '\n' printf >&2 'The option "Allow full disk access for remote users" can be found by\n' @@ -135,9 +137,11 @@ in if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then printf >&2 '\e[1;31merror: permission denied when trying to %s user %s, aborting activation\e[0m\n' "$2" "$1" - printf >&2 '`darwin-rebuild` requires permissions to administrate your computer,\n' "$1" "$2" + # shellcheck disable=SC2016 + printf >&2 '`darwin-rebuild` requires permissions to administrate your computer,\n' printf >&2 'please accept the dialog that pops up.\n' printf >&2 '\n' + # shellcheck disable=SC2016 printf >&2 'If you do not wish to be prompted every time `darwin-rebuild updates your users,\n' printf >&2 'you can grant Full Disk Access to your terminal emulator in System Settings.\n' printf >&2 '\n' @@ -187,6 +191,7 @@ in if [ "$u" -gt 501 ]; then # TODO: add `darwin.primaryUser` as well if [[ ${name} == "$USER" ]]; then + # shellcheck disable=SC2016 printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', ${name} exit 1 elif [[ ${name} == "root" ]]; then From fd510a7122d49cc1cbd72b9e70b1ae6b3c76c990 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 19:26:56 +1100 Subject: [PATCH 081/139] system: replace `for f in $(ls ...)` with `for f in .../*` Fixes SC2045 but has one quirk which is if the bash glob doesn't match anything it'll treat it as a string and run the loop once with `f=.../*` so we need to check that `$f` actually exists. --- modules/system/launchd.nix | 41 ++++++++++++++++++++++++++------------ modules/system/patches.nix | 15 ++++++++------ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/modules/system/launchd.nix b/modules/system/launchd.nix index cdb6549f..c578dec3 100644 --- a/modules/system/launchd.nix +++ b/modules/system/launchd.nix @@ -105,19 +105,29 @@ in ${concatMapStringsSep "\n" (attr: launchdActivation "LaunchAgents" attr.target) launchAgents} ${concatMapStringsSep "\n" (attr: launchdActivation "LaunchDaemons" attr.target) launchDaemons} - for f in $(ls /run/current-system/Library/LaunchAgents 2> /dev/null); do - if test ! -e "${cfg.build.launchd}/Library/LaunchAgents/$f"; then - echo "removing service $(basename $f .plist)" >&2 + for f in /run/current-system/Library/LaunchAgents/*; do + [[ -e "$f" ]] || break # handle when directory is empty + f=''${f#/run/current-system/Library/LaunchAgents/} + + if [[ ! -e "${cfg.build.launchd}/Library/LaunchAgents/$f" ]]; then + echo "removing service $(basename "$f" .plist)" >&2 launchctl unload "/Library/LaunchAgents/$f" || true - if test -e "/Library/LaunchAgents/$f"; then rm -f "/Library/LaunchAgents/$f"; fi + if [[ -e "/Library/LaunchAgents/$f" ]]; then + rm -f "/Library/LaunchAgents/$f" + fi fi done - for f in $(ls /run/current-system/Library/LaunchDaemons 2> /dev/null); do - if test ! -e "${cfg.build.launchd}/Library/LaunchDaemons/$f"; then - echo "removing service $(basename $f .plist)" >&2 + for f in /run/current-system/Library/LaunchDaemons/*; do + [[ -e "$f" ]] || break # handle when directory is empty + f=''${f#/run/current-system/Library/LaunchDaemons/} + + if [[ ! -e "${cfg.build.launchd}/Library/LaunchDaemons/$f" ]]; then + echo "removing service $(basename "$f" .plist)" >&2 launchctl unload "/Library/LaunchDaemons/$f" || true - if test -e "/Library/LaunchDaemons/$f"; then rm -f "/Library/LaunchDaemons/$f"; fi + if [[ -e "/Library/LaunchDaemons/$f" ]]; then + rm -f "/Library/LaunchDaemons/$f" + fi fi done ''; @@ -133,11 +143,16 @@ in ''} ${concatMapStringsSep "\n" (attr: userLaunchdActivation attr.target) userLaunchAgents} - for f in $(ls /run/current-system/user/Library/LaunchAgents 2> /dev/null); do - if test ! -e "${cfg.build.launchd}/user/Library/LaunchAgents/$f"; then - echo "removing user service $(basename $f .plist)" >&2 - launchctl unload ~/Library/LaunchAgents/$f || true - if test -e ~/Library/LaunchAgents/$f; then rm -f ~/Library/LaunchAgents/$f; fi + for f in /run/current-system/user/Library/LaunchAgents/*; do + [[ -e "$f" ]] || break # handle when directory is empty + f=''${f#/run/current-system/user/Library/LaunchAgents/} + + if [[ ! -e "${cfg.build.launchd}/user/Library/LaunchAgents/$f" ]]; then + echo "removing user service $(basename "$f" .plist)" >&2 + launchctl unload ~/Library/LaunchAgents/"$f" || true + if [[ -e ~/Library/LaunchAgents/"$f" ]]; then + rm -f ~/Library/LaunchAgents/"$f" + fi fi done ''; diff --git a/modules/system/patches.nix b/modules/system/patches.nix index 4f965014..7b192556 100644 --- a/modules/system/patches.nix +++ b/modules/system/patches.nix @@ -30,9 +30,9 @@ in Set of patches to apply to {file}`/`. ::: {.warning} - + This can modify everything so use with caution. - + ::: Useful for safely changing system files. Unlike the etc module this @@ -56,10 +56,13 @@ in # Applying patches to /. echo "applying patches..." >&2 - for f in $(ls /run/current-system/patches 2> /dev/null); do - if test ! -e "${config.system.build.patches}/patches/$f"; then - patch --force --reverse --backup -d / -p1 < "/run/current-system/patches/$f" || true - fi + for f in /run/current-system/patches/*; do + [[ -e "$f" ]] || break # handle when directory is empty + f=''${f#/run/current-system/patches/} + + if [[ ! -e "${config.system.build.patches}/patches/$f" ]]; then + patch --force --reverse --backup -d / -p1 < "/run/current-system/patches/$f" || true + fi done ${concatMapStringsSep "\n" (f: '' From 32814a6eb1de3b564ff43e5b6453637b1eb25721 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 1 Nov 2024 00:38:47 +1100 Subject: [PATCH 082/139] users: replace runtime check to prevent deleting `root` with assertion This fixes SC2050 as `${name} == "root"` will be generated as a constant expression. --- modules/users/default.nix | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index d15deac6..4044732c 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -99,6 +99,10 @@ in assertion = cfg.users ? root -> (cfg.users.root.home == null || cfg.users.root.home == "/var/root"); message = "`users.users.root.home` must be set to either `null` or `/var/root`."; } + { + assertion = !builtins.elem "root" deletedUsers; + message = "Remove `root` from `users.knownUsers` if you no longer want nix-darwin to manage it."; + } ]; users.gids = mkMerge gids; @@ -194,9 +198,6 @@ in # shellcheck disable=SC2016 printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', ${name} exit 1 - elif [[ ${name} == "root" ]]; then - printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' - exit 1 fi ensurePerms ${name} delete From cf130aa9579fc1708ff4a265d2108eefa535e9b2 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 19:53:20 +1100 Subject: [PATCH 083/139] users: don't generate `ensurePerms` when no users to manage --- modules/users/default.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 4044732c..434b1daa 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -111,7 +111,7 @@ in # NOTE: We put this in `system.checks` as we want this to run first to avoid partial activations # however currently that runs at user level activation as that runs before system level activation # TODO: replace `$USER` with `$SUDO_USER` when system.checks runs from system level - system.checks.text = lib.mkAfter '' + system.checks.text = lib.mkIf (builtins.length (createdUsers ++ deletedUsers) > 0) (lib.mkAfter '' ensurePerms() { homeDirectory=$(dscl . -read /Users/nobody NFSHomeDirectory) homeDirectory=''${homeDirectory#NFSHomeDirectory: } @@ -157,7 +157,6 @@ in fi } - ${concatMapStringsSep "\n" (v: let name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; @@ -204,7 +203,7 @@ in fi fi '') deletedUsers} - ''; + ''); system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) '' echo "setting up groups..." >&2 From 3b738c765de1bb4ecc4993fa092b27dd46d495ed Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 20:30:48 +1100 Subject: [PATCH 084/139] github-runner: replace `mkdir -p -m` with `umask` `mkdir -p -m` only applies the mode on the deepest directory which could be a security issue so we use umask to be more careful. --- modules/services/github-runner/service.nix | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/services/github-runner/service.nix b/modules/services/github-runner/service.nix index 175b22d1..c273f433 100644 --- a/modules/services/github-runner/service.nix +++ b/modules/services/github-runner/service.nix @@ -48,14 +48,20 @@ in text = mkBefore ('' echo >&2 "setting up GitHub Runner '${cfg.name}'..." - ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkStateDir cfg)} - ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)} + ( + umask -S u=rwx,g=rx,o= - ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkLogDir cfg)} - ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)} - '' + optionalString (cfg.workDir == null) '' - ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkWorkDir cfg)} - ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)} + ${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkStateDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)} + + ${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkLogDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)} + + ${optionalString (cfg.workDir == null) '' + ${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkWorkDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)} + ''} + ) ''); }; })); From 79608947e27163a2e74b1bec0812ce7a942cbdb8 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 3 Nov 2024 20:30:48 +1100 Subject: [PATCH 085/139] buildkit-agents: don't use `mkdir -p -m` As `cfg.dataDir` will be the `home` of the Buildkite Agent user, it is guaranted to exist so we don't need to use the `-p` flag. --- modules/services/buildkite-agents.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/buildkite-agents.nix b/modules/services/buildkite-agents.nix index 4888247e..69bc1f65 100644 --- a/modules/services/buildkite-agents.nix +++ b/modules/services/buildkite-agents.nix @@ -237,7 +237,7 @@ in tagStr = lib.concatStringsSep "," (lib.mapAttrsToList (name: value: "${name}=${value}") cfg.tags); in optionalString (cfg.privateSshKeyPath != null) '' - mkdir -m 0700 -p "${sshDir}" + mkdir -m 0700 "${sshDir}" install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa" '' + '' cat > "${cfg.dataDir}/buildkite-agent.cfg" < Date: Tue, 5 Nov 2024 00:54:34 +1100 Subject: [PATCH 086/139] uninstaller: remove `/run` symlink --- pkgs/darwin-uninstaller/default.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index 3eb2c244..a82974e7 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -63,10 +63,21 @@ stdenv.mkDerivation { ${uninstallSystem.system}/sw/bin/darwin-rebuild activate - if test -L /run/current-system; then + if [[ -L /run/current-system ]]; then sudo rm /run/current-system fi + if [[ -L /run ]]; then + if [[ -e /etc/synthetic.conf ]]; then + sudo sed -i -E '/^run[[:space:]]/d' /etc/synthetic.conf + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true + echo >&2 "NOTE: the /run symlink will be removed on reboot" + else + sudo rm /run + fi + fi + echo >&2 echo >&2 "NOTE: The /nix/var/nix/profiles/system* profiles still exist and won't be garbage collected." echo >&2 From 1b5fa6be405425ae5040d68c4a3bfff14fdf2100 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 5 Nov 2024 01:14:16 +1100 Subject: [PATCH 087/139] uninstaller: remove unnecessary attempt to delete `nix-daemon` Fixes https://github.com/LnL7/nix-darwin/issues/910 --- pkgs/darwin-uninstaller/configuration.nix | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index 6487774b..0bdccb98 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -7,31 +7,29 @@ with lib; assertions = mkForce []; system.activationScripts.checks.text = mkForce ""; - # Disable etc, launchd, ... environment.etc = mkForce {}; launchd.agents = mkForce {}; launchd.daemons = mkForce {}; launchd.user.agents = mkForce {}; system.activationScripts.postUserActivation.text = mkAfter '' - if test -L ~/.nix-defexpr/channels/darwin; then + if [[ -L ~/.nix-defexpr/channels/darwin ]]; then nix-channel --remove darwin || true fi ''; system.activationScripts.postActivation.text = mkAfter '' - if test -L /Applications/Nix\ Apps; then + if [[ -L /Applications/Nix\ Apps ]]; then rm /Applications/Nix\ Apps fi - if test -L /etc/static; then + if [[ -L /etc/static ]]; then rm /etc/static fi - if test -O /nix/store; then - if ! test -e /Library/LaunchDaemons/org.nixos.nix-daemon.plist; then - sudo rm /Library/LaunchDaemons/org.nixos.nix-daemon.plist || true - sudo launchctl remove org.nixos.nix-daemon 2> /dev/null || true + # 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 From 9cd45289c9200b5adf29ed4faaf8e00a8c06da9c Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 5 Nov 2024 01:52:34 +1100 Subject: [PATCH 088/139] uninstaller: reset any shells pointing to `/run/current-system/sw/bin` --- pkgs/darwin-uninstaller/configuration.nix | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index 0bdccb98..a2283d89 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -46,5 +46,15 @@ with lib; echo >&2 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) + if [[ "$shell" != */bin/zsh ]]; then + echo >&2 "warning: changing $user's shell from $shell to /bin/zsh" + fi + + dscl . -create /Users/"$user" UserShell /bin/zsh + done ''; } From c3b406bd1c6e60a69996dbbd529328e40d298bd7 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 5 Nov 2024 02:31:26 +1100 Subject: [PATCH 089/139] uninstaller: restore `*.before-nix-darwin` files Fixes https://github.com/LnL7/nix-darwin/issues/911 Fixes https://github.com/LnL7/nix-darwin/issues/912 --- pkgs/darwin-uninstaller/configuration.nix | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index a2283d89..75d1cacf 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -1,4 +1,4 @@ -{ lib, ... }: +{ lib, pkgs, ... }: with lib; @@ -33,18 +33,6 @@ with lib; 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 - - if ! grep -q etc/profile.d/nix-daemon.sh /etc/bashrc; then - echo >&2 "Found no nix-daemon.sh reference in /etc/bashrc" - echo >&2 "add this snippet back to /etc/bashrc:" - echo >&2 - echo >&2 " # Nix" - echo >&2 " if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then" - echo >&2 " . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'" - echo >&2 " fi" - echo >&2 " # End Nix" - echo >&2 - fi fi # grep will return 1 when no lines matched which makes this line fail with `set -eo pipefail` @@ -56,5 +44,9 @@ with lib; dscl . -create /Users/"$user" UserShell /bin/zsh done + + while IFS= read -r -d "" file; do + mv "$file" "''${file%.*}" + done < <(find /etc -name '*.before-nix-darwin' -follow -print0) ''; } From ebca0c23c95cc2d2c75b3c3a290fa99a886b9738 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 5 Nov 2024 02:48:25 +1100 Subject: [PATCH 090/139] uninstaller: switch to `writeShellApplication` By not defining a `shellHook`, `nix-shell -A uninstaller` and `nix-shell -A uninstaller.check` no longer work. --- .github/workflows/test.yml | 18 ++++-- pkgs/darwin-uninstaller/default.nix | 95 ++++++++++++----------------- 2 files changed, 50 insertions(+), 63 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ce176ebe..e786b4a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -66,9 +66,12 @@ jobs: darwin-rebuild switch -I darwin=. - name: Test uninstallation of nix-darwin run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - nix-shell -A uninstaller - nix-shell -A uninstaller.check + nix run .#darwin-uninstaller \ + --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ + --extra-experimental-features "nix-command flakes" + nix run .#darwin-uninstaller.tests.uninstaller \ + --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ + --extra-experimental-features "nix-command flakes" - name: Debugging tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 @@ -111,9 +114,12 @@ jobs: darwin-rebuild switch -I darwin=. - name: Test uninstallation of nix-darwin run: | - export NIX_PATH=$HOME/.nix-defexpr/channels - nix-shell -A uninstaller - nix-shell -A uninstaller.check + nix run .#darwin-uninstaller \ + --override-input nixpkgs nixpkgs/nixpkgs-unstable \ + --extra-experimental-features "nix-command flakes" + nix run .#darwin-uninstaller.tests.uninstaller \ + --override-input nixpkgs nixpkgs/nixpkgs-unstable \ + --extra-experimental-features "nix-command flakes" - name: Debugging tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index a82974e7..5159c2c8 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -1,4 +1,4 @@ -{ stdenv, lib, pkgs }: +{ lib, path, stdenv, writeShellApplication }: let uninstallSystem = import ../../eval-config.nix { @@ -6,39 +6,23 @@ let modules = [ ./configuration.nix { - nixpkgs.source = pkgs.path; - nixpkgs.hostPlatform = pkgs.stdenv.hostPlatform.system; + nixpkgs.source = path; + nixpkgs.hostPlatform = stdenv.hostPlatform.system; system.includeUninstaller = false; } ]; }; -in - -stdenv.mkDerivation { +in writeShellApplication { name = "darwin-uninstaller"; - preferLocalBuild = true; - - unpackPhase = ":"; - - installPhase = '' - mkdir -p $out/bin - echo "$shellHook" > $out/bin/darwin-uninstaller - chmod +x $out/bin/darwin-uninstaller - ''; - - shellHook = '' - #!${stdenv.shell} - set -e - - action=switch + text = '' while [ "$#" -gt 0 ]; do - i="$1"; shift 1 - case "$i" in - --help) - echo "darwin-uninstaller: [--help]" - exit - ;; - esac + i="$1"; shift 1 + case "$i" in + --help) + echo "darwin-uninstaller: [--help]" + exit + ;; + esac done echo >&2 @@ -50,15 +34,15 @@ stdenv.mkDerivation { echo >&2 " - restore daemon service from nix installer (only when this is a multi-user install)" echo >&2 - if test -t 0; then - read -p "Proceed? [y/n] " i - case "$i" in - y|Y) - ;; - *) - exit 3 - ;; - esac + if [[ -t 0 ]]; then + read -r -p "Proceed? [y/n] " i + case "$i" in + y|Y) + ;; + *) + exit 3 + ;; + esac fi ${uninstallSystem.system}/sw/bin/darwin-rebuild activate @@ -83,29 +67,26 @@ stdenv.mkDerivation { echo >&2 echo >&2 "Done!" echo >&2 - exit ''; - passthru.check = stdenv.mkDerivation { - name = "run-darwin-test"; - shellHook = '' - set -e - echo >&2 "running uninstaller tests..." - echo >&2 + derivationArgs.passthru.tests.uninstaller = writeShellApplication { + name = "post-uninstall-test"; + text = '' + echo >&2 "running uninstaller tests..." + echo >&2 - echo >&2 "checking darwin channel" - ! test -e ~/.nix-defexpr/channels/darwin - echo >&2 "checking /etc" - ! test -e /etc/static - echo >&2 "checking /run/current-system" - ! test -e /run/current-system - echo >&2 "checking nix-daemon service (assuming a multi-user install)" - sudo launchctl list | grep org.nixos.nix-daemon || echo "FIXME? sudo launchctl list | grep org.nixos.nix-daemon" - pgrep -l nix-daemon || echo "FIXME? pgrep -l nix-daemon" - readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist" - grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist" - echo >&2 ok - exit + echo >&2 "checking darwin channel" + test -e ~/.nix-defexpr/channels/darwin && exit 1 + echo >&2 "checking /etc" + test -e /etc/static && exit 1 + echo >&2 "checking /run/current-system" + test -e /run/current-system && exit 1 + echo >&2 "checking nix-daemon service (assuming a multi-user install)" + sudo launchctl list | grep org.nixos.nix-daemon || echo "FIXME? sudo launchctl list | grep org.nixos.nix-daemon" + pgrep -l nix-daemon || echo "FIXME? pgrep -l nix-daemon" + readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist" + grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist" + echo >&2 ok ''; }; } From 7bbc7c5db686f4e57a29c82a185596f53d110647 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 4 Nov 2024 11:55:15 +1100 Subject: [PATCH 091/139] ci: test uninstallation of nix-darwin using flakes --- .github/workflows/test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e786b4a6..095cd3a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -155,6 +155,10 @@ jobs: run: | . /etc/static/bashrc darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} + - name: Test uninstallation of nix-darwin + run: | + nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} + nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} install-flake-against-unstable: runs-on: macos-13 @@ -184,3 +188,7 @@ jobs: run: | . /etc/static/bashrc darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/nixpkgs-unstable + - name: Test uninstallation of nix-darwin + run: | + nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable + nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable From 3a89b614321ab8dad3962d79fc3a29bace9a8486 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 7 Nov 2024 14:19:19 +1100 Subject: [PATCH 092/139] uninstaller: check `nix-daemon` was correctly reinstalled --- pkgs/darwin-uninstaller/default.nix | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index 5159c2c8..17c0a460 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -81,12 +81,14 @@ in writeShellApplication { test -e /etc/static && exit 1 echo >&2 "checking /run/current-system" test -e /run/current-system && exit 1 - echo >&2 "checking nix-daemon service (assuming a multi-user install)" - sudo launchctl list | grep org.nixos.nix-daemon || echo "FIXME? sudo launchctl list | grep org.nixos.nix-daemon" - pgrep -l nix-daemon || echo "FIXME? pgrep -l nix-daemon" - readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist" - grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist" - echo >&2 ok + if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then + echo >&2 "checking nix-daemon service" + 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}')" ]] + echo >&2 ok + fi ''; }; } From 222c3cb558f4e56e3f9e84bb65fe23034f7f9c79 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 7 Nov 2024 16:47:15 +1100 Subject: [PATCH 093/139] ci: fix uninstaller failing to run in `install-against-unstable` --- .github/workflows/test.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 095cd3a6..623cb698 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -114,12 +114,13 @@ jobs: darwin-rebuild switch -I darwin=. - name: Test uninstallation of nix-darwin run: | + # A regression in Nix 2.19 means we need to put `--extra-experimental-features` before `--override-input` nix run .#darwin-uninstaller \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - --extra-experimental-features "nix-command flakes" + --extra-experimental-features "nix-command flakes" \ + --override-input nixpkgs nixpkgs/nixpkgs-unstable nix run .#darwin-uninstaller.tests.uninstaller \ - --override-input nixpkgs nixpkgs/nixpkgs-unstable \ - --extra-experimental-features "nix-command flakes" + --extra-experimental-features "nix-command flakes" \ + --override-input nixpkgs nixpkgs/nixpkgs-unstable - name: Debugging tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 From 110d49af637c3da025b6b42a0caa81c1d63b2aed Mon Sep 17 00:00:00 2001 From: Yuriy Taraday Date: Mon, 4 Nov 2024 18:31:38 +0100 Subject: [PATCH 094/139] github-runner: Fix labels for different nixpkgs versions Changes to escapeShellArg introduced in https://github.com/NixOS/nixpkgs/pull/333744 made different versions of nixpkgs behave differently. If current nix-darwin is used with nixpkgs before that change, labels end up having labels quoted twice (see https://github.com/LnL7/nix-darwin/issues/1085), but without changes from https://github.com/LnL7/nix-darwin/pull/1055, with new nixpkgs, labels end up not quoted at all, and ShellCheck ends up complaining that commas might have been used as array item separator (see https://www.shellcheck.net/wiki/SC2054). Use the old version of escapeShellArg to always escape the list of labels and make nix-darwin work with both old and new versions of nixpkgs. Fixes https://github.com/LnL7/nix-darwin/issues/1085 --- modules/services/github-runner/service.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/services/github-runner/service.nix b/modules/services/github-runner/service.nix index c273f433..5d73633b 100644 --- a/modules/services/github-runner/service.nix +++ b/modules/services/github-runner/service.nix @@ -94,6 +94,10 @@ in script = let + # https://github.com/NixOS/nixpkgs/pull/333744 introduced an inconsistency with different + # versions of nixpkgs. Use the old version of escapeShellArg to make sure that labels + # are always escaped to avoid https://www.shellcheck.net/wiki/SC2054 + escapeShellArgAlways = string: "'${replaceStrings ["'"] ["'\\''"] (toString string)}'"; configure = pkgs.writeShellApplication { name = "configure-github-runner-${name}"; text = /*bash*/'' @@ -104,7 +108,7 @@ in --disableupdate --work ${escapeShellArg workDir} --url ${escapeShellArg cfg.url} - --labels "${escapeShellArg (concatStringsSep "," cfg.extraLabels)}" + --labels ${escapeShellArgAlways (concatStringsSep "," cfg.extraLabels)} ${optionalString (cfg.name != null ) "--name ${escapeShellArg cfg.name}"} ${optionalString cfg.replace "--replace"} ${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"} From f0a1269297c8ca7f5aa287166c2a9cfb6e13917c Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 8 Nov 2024 12:02:34 +1100 Subject: [PATCH 095/139] nix: don't allow using `auto-optimise-store` as it can corrupt the store --- modules/nix/default.nix | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 6bce1e35..d99aae83 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -404,7 +404,7 @@ in { darwin-config = "${config.environment.darwinConfig}"; } "/nix/var/nix/profiles/per-user/root/channels" ]; - + defaultText = lib.literalExpression '' lib.optionals cfg.channel.enable [ # Include default path . @@ -527,8 +527,10 @@ in description = '' If set to true, Nix automatically detects files in the store that have identical contents, and replaces them with hard links to a single copy. - This saves disk space. If set to false (the default), you can still run - nix-store --optimise to get rid of duplicate files. + This saves disk space. If set to false (the default), you can enable + {option}`nix.optimise.automatic` to run {command}`nix-store --optimise` + periodically to get rid of duplicate files. You can also run + {command}`nix-store --optimise` manually. ''; }; @@ -761,6 +763,13 @@ in { 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 = config.users.groups ? "nixbld" -> config.users.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; } + + { + # Should be fixed in Lix by https://gerrit.lix.systems/c/lix/+/2100 + # As `isNixAtLeast "2.92.0" "2.92.0-devpre20241107" == false`, we need to explicitly check if the user is running Lix 2.92.0 + assertion = cfg.settings.auto-optimise-store -> (cfg.package.pname == "lix" && (isNixAtLeast "2.92.0-devpre20241107" || cfg.package.version == "2.92.0")); + message = "`nix.settings.auto-optimise-store` is known to corrupt the Nix Store, please use `nix.optimise.automatic` instead."; + } ]; # Not in NixOS module From 5fbb7b7637307c89e52d7e73ed6c848353bda6a0 Mon Sep 17 00:00:00 2001 From: Sam <30577766+Samasaur1@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:29:35 -0800 Subject: [PATCH 096/139] zsh: only run shell initialization in /etc/zshenv when RCs are enabled --- modules/programs/zsh/default.nix | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index a9ffbd80..c6ec9175 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -136,17 +136,19 @@ in if [ -n "''${__ETC_ZSHENV_SOURCED-}" ]; then return; fi __ETC_ZSHENV_SOURCED=1 - if [ -z "''${__NIX_DARWIN_SET_ENVIRONMENT_DONE-}" ]; then - . ${config.system.build.setEnvironment} + if [[ -o rcs ]]; then + if [ -z "''${__NIX_DARWIN_SET_ENVIRONMENT_DONE-}" ]; then + . ${config.system.build.setEnvironment} + fi + + # Tell zsh how to find installed completions + for p in ''${(z)NIX_PROFILES}; do + fpath=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions $p/share/zsh/vendor-completions $fpath) + done + + ${cfg.shellInit} fi - # Tell zsh how to find installed completions - for p in ''${(z)NIX_PROFILES}; do - fpath=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions $p/share/zsh/vendor-completions $fpath) - done - - ${cfg.shellInit} - # Read system-wide modifications. if test -f /etc/zshenv.local; then source /etc/zshenv.local From a82d72d25f67dff02afbd6fb72cd16e2ec040a68 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 7 Nov 2024 23:23:46 +1100 Subject: [PATCH 097/139] flake: expose docs on Linux as well --- flake.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/flake.nix b/flake.nix index 48dc3121..fb5545b1 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,8 @@ description = "A collection of darwin modules"; outputs = { self, nixpkgs }: let - forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ]; + forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ]; + forDarwinSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ]; jobs = forAllSystems (system: import ./release.nix { inherit nixpkgs system; @@ -58,9 +59,11 @@ description = "nix flake init -t nix-darwin"; }; - checks = forAllSystems (system: jobs.${system}.tests // jobs.${system}.examples); + checks = forDarwinSystems (system: jobs.${system}.tests // jobs.${system}.examples); - packages = forAllSystems (system: let + packages = forAllSystems (system: { + inherit (jobs.${system}.docs) manualHTML manpages optionsJSON; + } // (nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasSuffix "darwin" system) (let pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; @@ -69,8 +72,6 @@ default = self.packages.${system}.darwin-rebuild; inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller; - - inherit (jobs.${system}.docs) manualHTML manpages optionsJSON; - }); + }))); }; } From 2ff55ab1c5c238181c3b6f1bd78156e7d77812bb Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 8 Nov 2024 16:38:31 +1100 Subject: [PATCH 098/139] manual: get revision information when called from flake --- flake.nix | 2 ++ release.nix | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/flake.nix b/flake.nix index fb5545b1..2c1ae1b2 100644 --- a/flake.nix +++ b/flake.nix @@ -7,6 +7,8 @@ jobs = forAllSystems (system: import ./release.nix { inherit nixpkgs system; + + nix-darwin = self; }); in { lib = { diff --git a/release.nix b/release.nix index 18fb239d..b3e2df7e 100644 --- a/release.nix +++ b/release.nix @@ -1,4 +1,6 @@ { nixpkgs ? +# Adapted from https://github.com/NixOS/nixpkgs/blob/e818264fe227ad8861e0598166cf1417297fdf54/pkgs/top-level/release.nix#L11 +, nix-darwin ? { } , system ? builtins.currentSystem , supportedSystems ? [ "x86_64-darwin" "aarch64-darwin" ] , scrubJobs ? true @@ -56,6 +58,15 @@ let manual = buildFromConfig ({ lib, config, ... }: { system.stateVersion = lib.mkDefault config.system.maxStateVersion; + + system.darwinVersionSuffix = let + shortRev = nix-darwin.shortRev or nix-darwin.dirtyShortRev or null; + in + lib.mkIf (shortRev != null) ".${shortRev}"; + system.darwinRevision = let + rev = nix-darwin.rev or nix-darwin.dirtyRev or null; + in + lib.mkIf (rev != null) rev; }) (config: config.system.build.manual); in { From a89c85192354229d9fc0adfe11f3f89620eb9487 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 20:37:07 +1100 Subject: [PATCH 099/139] ci: don't override nixpkgs when building the manual This causes `nix-darwin` to not have `rev` or `dirtyRev` --- .github/workflows/update-manual.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index a2f93822..42ee21e5 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -21,7 +21,7 @@ jobs: - name: Build manual run: | - nix build .#manualHTML --override-input nixpkgs nixpkgs/nixpkgs-24.05-darwin + nix build .#manualHTML - name: Push update to manual run: | From 293589065dd0f6bbfd6f83fcdc4f2d74543337c9 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 20:51:18 +1100 Subject: [PATCH 100/139] ci: fix manual not being regenerated when non-Nix files are updated This also fixes the README not being updated on the website as well --- .github/workflows/update-manual.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index 42ee21e5..8d2af53b 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -3,8 +3,6 @@ on: push: branches: - master - paths: - - '**.nix' jobs: update-manual: From 534ca06930039a616934b6d9dd8316e8df799622 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 20:51:18 +1100 Subject: [PATCH 101/139] docs: use `nix-darwin` instead of `Darwin` --- doc/manual/default.nix | 8 ++++---- doc/manual/manual.md | 2 +- modules/examples/flake/flake.nix | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/manual/default.nix b/doc/manual/default.nix index abe126b7..deada0a4 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -118,18 +118,18 @@ in rec { # TODO: get these parameterized in upstream nixos-render-docs sed -i -e ' - /^\.TH / s|NixOS|Darwin|g + /^\.TH / s|NixOS|nix-darwin|g /^\.SH "NAME"$/ { N - s|NixOS|Darwin|g + s|NixOS|nix-darwin|g } /^\.SH "DESCRIPTION"$/ { N; N s|/etc/nixos/configuration|configuration|g - s|NixOS|Darwin|g - s|nixos|darwin|g + s|NixOS|nix-darwin|g + s|nixos|nix-darwin|g } /\.SH "AUTHORS"$/ { diff --git a/doc/manual/manual.md b/doc/manual/manual.md index 131df7d2..bacba03f 100644 --- a/doc/manual/manual.md +++ b/doc/manual/manual.md @@ -1,4 +1,4 @@ -# Darwin Configuration Options {#book-darwin-manual} +# nix-darwin Configuration Options {#book-darwin-manual} ## Version @DARWIN_VERSION@ ```{=include=} options diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index e6eaefc7..bd733bd9 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -1,5 +1,5 @@ { - description = "Example Darwin system flake"; + description = "Example nix-darwin system flake"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; From ae09d7ba528760f9c9b4f92d905d35c46d50ddca Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 03:14:01 +1100 Subject: [PATCH 102/139] readme: remove outdated instructions for manually managing `/etc/bashrc` --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index d3aec37f..602ce089 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,6 @@ nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer ./result/bin/darwin-installer ``` -> NOTE: the system activation scripts don't overwrite existing etc files, so files like `/etc/bashrc` and `/etc/zshrc` won't be -> updated by default. If you didn't use the installer or skipped some of the options you'll have to take care of this yourself. -> Either modify the existing file to source/import the one from `/etc/static` or remove it. Some examples: - -- `mv /etc/bashrc /etc/bashrc.before-nix-darwin` -- `echo 'if test -e /etc/static/bashrc; then . /etc/static/bashrc; fi' | sudo tee -a /etc/bashrc` - ## Updating The installer will configure a channel for this repository. From 2fe3de580e02a3d867134d6632525cf93ffaf0cb Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 03:14:01 +1100 Subject: [PATCH 103/139] readme: fix badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 602ce089..82a094df 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # nix-darwin -![Test](https://github.com/LnL7/nix-darwin/workflows/Test/badge.svg) +[![Test](https://github.com/LnL7/nix-darwin/actions/workflows/test.yml/badge.svg)](https://github.com/LnL7/nix-darwin/actions/workflows/test.yml) Nix modules for darwin, `/etc/nixos/configuration.nix` for macOS. From 050b7db4451bbca9798d09661f098cb0033779b5 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 03:14:01 +1100 Subject: [PATCH 104/139] installer: don't tell users to source bashrc Fixes #380 --- pkgs/darwin-installer/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index 37a391c0..5c6d801e 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -95,7 +95,7 @@ stdenv.mkDerivation { echo >&2 " Open '$config' to get started." echo >&2 " See the README for more information: https://github.com/LnL7/nix-darwin/blob/master/README.md" echo >&2 - echo >&2 " Don't forget to start a new shell or source /etc/static/bashrc." + echo >&2 " Please log out and log in again to make sure nix-darwin is properly loaded." echo >&2 exit ''; From 5a1ae6a6e41362fb52a682fd3d5f19585131d5de Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 9 Nov 2024 03:14:01 +1100 Subject: [PATCH 105/139] readme: add prerequisites section --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 82a094df..b9e3de7e 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,16 @@ Nix modules for darwin, `/etc/nixos/configuration.nix` for macOS. This project aims to bring the convenience of a declarative system approach to macOS. nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite similar to [NixOS](https://nixos.org/). -## Installing +## Prerequisites -To install nix-darwin, a working installation of [Nix](https://github.com/NixOS/nix#installation) is required. +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 [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system) supports both flake-based and channel-based setups. + +## Installing If you wish to use nix-darwin with flakes, please refer to the [flakes](#flakes) section. From c2c88ae983c236839c24f547a0047310f8c69647 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 00:21:42 +1100 Subject: [PATCH 106/139] users: remove `lib.` --- modules/users/default.nix | 42 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 434b1daa..2adf8132 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -1,8 +1,10 @@ { config, lib, pkgs, ... }: let - inherit (lib) concatStringsSep concatMapStringsSep elem filter filterAttrs - mapAttrs' mapAttrsToList mkIf mkMerge mkOption mkOrder optionalString types; + inherit (lib) concatStringsSep concatMapStringsSep elem escapeShellArg + escapeShellArgs filter filterAttrs mapAttrs' mapAttrsToList mkAfter + mkIf mkMerge mkOption mkOrder mkRemovedOptionModule optionals + optionalString types; cfg = config.users; @@ -42,7 +44,7 @@ in { imports = [ - (lib.mkRemovedOptionModule [ "users" "forceRecreate" ] "") + (mkRemovedOptionModule [ "users" "forceRecreate" ] "") ]; options = { @@ -111,7 +113,7 @@ in # NOTE: We put this in `system.checks` as we want this to run first to avoid partial activations # however currently that runs at user level activation as that runs before system level activation # TODO: replace `$USER` with `$SUDO_USER` when system.checks runs from system level - system.checks.text = lib.mkIf (builtins.length (createdUsers ++ deletedUsers) > 0) (lib.mkAfter '' + system.checks.text = mkIf (builtins.length (createdUsers ++ deletedUsers) > 0) (mkAfter '' ensurePerms() { homeDirectory=$(dscl . -read /Users/nobody NFSHomeDirectory) homeDirectory=''${homeDirectory#NFSHomeDirectory: } @@ -158,8 +160,8 @@ in } ${concatMapStringsSep "\n" (v: let - name = lib.escapeShellArg v.name; - dsclUser = lib.escapeShellArg "/Users/${v.name}"; + name = escapeShellArg v.name; + dsclUser = escapeShellArg "/Users/${v.name}"; in '' u=$(id -u ${name} 2> /dev/null) || true if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then @@ -170,7 +172,7 @@ in else homeDirectory=$(dscl . -read ${dsclUser} NFSHomeDirectory) homeDirectory=''${homeDirectory#NFSHomeDirectory: } - if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then + if [[ ${escapeShellArg v.home} != "$homeDirectory" ]]; then printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} printf >&2 'nix-darwin does not support changing the home directory of existing users.\n' printf >&2 '\n' @@ -187,7 +189,7 @@ in '') createdUsers} ${concatMapStringsSep "\n" (v: let - name = lib.escapeShellArg v; + name = escapeShellArg v; in '' u=$(id -u ${name} 2> /dev/null) || true if [ -n "$u" ]; then @@ -209,14 +211,14 @@ in echo "setting up groups..." >&2 ${concatMapStringsSep "\n" (v: let - dsclGroup = lib.escapeShellArg "/Groups/${v.name}"; + dsclGroup = escapeShellArg "/Groups/${v.name}"; in '' g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [ -z "$g" ]; then echo "creating group ${v.name}..." >&2 dscl . -create ${dsclGroup} PrimaryGroupID ${toString v.gid} - dscl . -create ${dsclGroup} RealName ${lib.escapeShellArg v.description} + dscl . -create ${dsclGroup} RealName ${escapeShellArg v.description} g=${toString v.gid} fi @@ -224,7 +226,7 @@ in g=$(dscl . -read ${dsclGroup} GroupMembership 2> /dev/null) || true if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then echo "updating group members ${v.name}..." >&2 - dscl . -create ${dsclGroup} GroupMembership ${lib.escapeShellArgs v.members} + dscl . -create ${dsclGroup} GroupMembership ${escapeShellArgs v.members} fi else echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 @@ -232,7 +234,7 @@ in '') createdGroups} ${concatMapStringsSep "\n" (name: let - dsclGroup = lib.escapeShellArg "/Groups/${name}"; + dsclGroup = escapeShellArg "/Groups/${name}"; in '' g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } @@ -251,8 +253,8 @@ in echo "setting up users..." >&2 ${concatMapStringsSep "\n" (v: let - name = lib.escapeShellArg v.name; - dsclUser = lib.escapeShellArg "/Users/${v.name}"; + name = escapeShellArg v.name; + dsclUser = escapeShellArg "/Users/${v.name}"; in '' u=$(id -u ${name} 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then @@ -261,11 +263,11 @@ in if [ -z "$u" ]; then echo "creating user ${v.name}..." >&2 - sysadminctl -addUser ${lib.escapeShellArgs ([ + sysadminctl -addUser ${escapeShellArgs ([ v.name "-UID" v.uid "-GID" v.gid ] - ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) + ++ (optionals (v.description != null) [ "-fullName" v.description ]) ++ [ "-home" (if v.home != null then v.home else "/var/empty") ] ++ [ "-shell" (if v.shell != null then shellPath v.shell else "/usr/bin/false") ])} 2> /dev/null @@ -284,17 +286,17 @@ in # Update properties on known users to keep them inline with configuration dscl . -create ${dsclUser} PrimaryGroupID ${toString v.gid} - ${optionalString (v.description != null) "dscl . -create ${dsclUser} RealName ${lib.escapeShellArg v.description}"} - ${optionalString (v.shell != null) "dscl . -create ${dsclUser} UserShell ${lib.escapeShellArg (shellPath v.shell)}"} + ${optionalString (v.description != null) "dscl . -create ${dsclUser} RealName ${escapeShellArg v.description}"} + ${optionalString (v.shell != null) "dscl . -create ${dsclUser} UserShell ${escapeShellArg (shellPath v.shell)}"} fi '') createdUsers} ${concatMapStringsSep "\n" (name: '' - u=$(id -u ${lib.escapeShellArg name} 2> /dev/null) || true + u=$(id -u ${escapeShellArg name} 2> /dev/null) || true if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then echo "deleting user ${name}..." >&2 - dscl . -delete ${lib.escapeShellArg "/Users/${name}"} + dscl . -delete ${escapeShellArg "/Users/${name}"} else echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2 fi From 5eb88645f74396d4b80fdf736ddd63afbe8320d5 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 00:08:42 +1100 Subject: [PATCH 107/139] users: assert that `programs..enable = true;` for users' shells Backport of https://github.com/NixOS/nixpkgs/pull/211603 and https://github.com/NixOS/nixpkgs/commit/093f354a1777e462bd80398c4fc624c4d383dc68 --- modules/users/default.nix | 28 +++++++++++++++++++++++++--- modules/users/user.nix | 11 +++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 2adf8132..ade4ffbc 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -2,8 +2,8 @@ let inherit (lib) concatStringsSep concatMapStringsSep elem escapeShellArg - escapeShellArgs filter filterAttrs mapAttrs' mapAttrsToList mkAfter - mkIf mkMerge mkOption mkOrder mkRemovedOptionModule optionals + escapeShellArgs filter filterAttrs flatten flip mapAttrs' mapAttrsToList + mkAfter mkIf mkMerge mkOption mkOrder mkRemovedOptionModule optionals optionalString types; cfg = config.users; @@ -105,7 +105,29 @@ in assertion = !builtins.elem "root" deletedUsers; message = "Remove `root` from `users.knownUsers` if you no longer want nix-darwin to manage it."; } - ]; + ] ++ flatten (flip mapAttrsToList cfg.users (name: user: + map (shell: { + assertion = let + s = user.shell.pname or null; + in + !user.ignoreShellProgramCheck -> (s == shell || (shell == "bash" && s == "bash-interactive")) -> (config.programs.${shell}.enable == true); + message = '' + users.users.${user.name}.shell is set to ${shell}, but + programs.${shell}.enable is not true. This will cause the ${shell} + shell to lack the basic Nix directories in its PATH and might make + logging in as that user impossible. You can fix it with: + programs.${shell}.enable = true; + + If you know what you're doing and you are fine with the behavior, + set users.users.${user.name}.ignoreShellProgramCheck = true; + instead. + ''; + }) [ + "bash" + "fish" + "zsh" + ] + )); users.gids = mkMerge gids; users.uids = mkMerge uids; diff --git a/modules/users/user.nix b/modules/users/user.nix index 9689e052..5256ac3b 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -84,6 +84,17 @@ ''; }; + ignoreShellProgramCheck = mkOption { + type = types.bool; + default = false; + description = '' + By default, nix-darwin will check that programs.SHELL.enable is set to + true if the user has a custom shell specified. If that behavior isn't + required and there are custom overrides in place to make sure that the + shell is functional, set this to true. + ''; + }; + packages = mkOption { type = types.listOf types.package; default = []; From 8b27551e094666e6beb273c484392fa205bb0c97 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 00:08:42 +1100 Subject: [PATCH 108/139] users: warn users to use `pkgs.bashInteractive` instead of `pkgs.bash` --- modules/users/default.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/users/default.nix b/modules/users/default.nix index ade4ffbc..574f5a4e 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -129,6 +129,12 @@ in ] )); + warnings = flatten (flip mapAttrsToList cfg.users (name: user: + mkIf + (user.shell.pname or null == "bash") + "Set `users.users.${name}.shell = pkgs.bashInteractive;` instead of `pkgs.bash` as it does not include `readline`." + )); + users.gids = mkMerge gids; users.uids = mkMerge uids; From 2bacd8db310f479fab713829663d4b36913553cf Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 00:54:26 +1100 Subject: [PATCH 109/139] environment: fix `lowPrio` support in `environment.systemPackages` --- modules/environment/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/environment/default.nix b/modules/environment/default.nix index 994c77a3..fc4db2ab 100644 --- a/modules/environment/default.nix +++ b/modules/environment/default.nix @@ -197,6 +197,7 @@ in name = "system-path"; paths = cfg.systemPackages; postBuild = cfg.extraSetup; + ignoreCollisions = true; inherit (cfg) pathsToLink extraOutputsToInstall; }; From d71aa30b41bac3b2e38bd4b8f49e12811cd27ec1 Mon Sep 17 00:00:00 2001 From: Lucas Mendes Loureiro Date: Sun, 10 Nov 2024 23:12:44 +0000 Subject: [PATCH 110/139] feat(defaults): adding support to control center --- modules/module-list.nix | 1 + modules/system/defaults-write.nix | 3 + modules/system/defaults/controlcenter.nix | 100 ++++++++++++++++++ .../system-defaults-write/activate-user.txt | 35 ++++++ tests/system-defaults-write.nix | 7 ++ 5 files changed, 146 insertions(+) create mode 100644 modules/system/defaults/controlcenter.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 3725c7ee..aa190c7d 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -14,6 +14,7 @@ ./system/activation-scripts.nix ./system/applications.nix ./system/defaults-write.nix + ./system/defaults/controlcenter.nix ./system/defaults/LaunchServices.nix ./system/defaults/NSGlobalDomain.nix ./system/defaults/GlobalPreferences.nix diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index 7af972d6..4249af99 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -17,6 +17,7 @@ let SoftwareUpdate = defaultsToList "/Library/Preferences/com.apple.SoftwareUpdate" cfg.SoftwareUpdate; # userDefaults + controlcenter = defaultsToList "~/Library/Preferences/ByHost/com.apple.controlcenter" cfg.controlcenter; GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences"; LaunchServices = defaultsToList "com.apple.LaunchServices" cfg.LaunchServices; NSGlobalDomain = defaultsToList "-g" cfg.NSGlobalDomain; @@ -71,6 +72,7 @@ in system.activationScripts.userDefaults.text = mkIfAttrs [ + controlcenter GlobalPreferences LaunchServices NSGlobalDomain @@ -113,6 +115,7 @@ in ${concatStringsSep "\n" ActivityMonitor} ${concatStringsSep "\n" CustomUserPreferences} ${concatStringsSep "\n" WindowManager} + ${concatStringsSep "\n" controlcenter} ${optionalString (length dock > 0) '' # Only restart Dock if current user is logged in diff --git a/modules/system/defaults/controlcenter.nix b/modules/system/defaults/controlcenter.nix new file mode 100644 index 00000000..91532fa9 --- /dev/null +++ b/modules/system/defaults/controlcenter.nix @@ -0,0 +1,100 @@ +{ config, lib, ... }: + +{ + options = { + + system.defaults.controlcenter.BatteryShowPercentage = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Battery + + Show a battery percentage in menu bar. Default is null. + ''; + }; + + system.defaults.controlcenter.Sound = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Sound + + Show a sound control in menu bar . Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + + system.defaults.controlcenter.Bluetooth = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Bluetooth + + Show a bluetooth control in menu bar. Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + + system.defaults.controlcenter.AirDrop = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > AirDrop + + Show a AirDrop control in menu bar. Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + + system.defaults.controlcenter.Display = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Display + + Show a Screen Brightness control in menu bar. Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + + system.defaults.controlcenter.FocusModes = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Focus + + Show a Focus control in menu bar. Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + + system.defaults.controlcenter.NowPlaying = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + apply = v: if v == null then null else if v == true then 18 else 24; + default = null; + description = '' + Apple menu > System Preferences > Control Center > Now Playing + + Show a Now Playing control in menu bar. Default is null. + + 18 = Display icon in menu bar + 24 = Hide icon in menu bar + ''; + }; + }; +} diff --git a/tests/fixtures/system-defaults-write/activate-user.txt b/tests/fixtures/system-defaults-write/activate-user.txt index 51b7574a..57cfe67a 100644 --- a/tests/fixtures/system-defaults-write/activate-user.txt +++ b/tests/fixtures/system-defaults-write/activate-user.txt @@ -489,3 +489,38 @@ defaults write com.apple.WindowManager 'StandardHideWidgets' $' ' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'AirDrop' $' + + +18 +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'BatteryShowPercentage' $' + + + +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Bluetooth' $' + + +18 +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Display' $' + + +24 +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'FocusModes' $' + + +24 +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'NowPlaying' $' + + +18 +' +defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Sound' $' + + +24 +' \ No newline at end of file diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix index ab26ef11..c5c9b754 100644 --- a/tests/system-defaults-write.nix +++ b/tests/system-defaults-write.nix @@ -94,6 +94,13 @@ true; }; }; + system.defaults.controlcenter.BatteryShowPercentage = true; + system.defaults.controlcenter.Sound = false; + system.defaults.controlcenter.Bluetooth = true; + system.defaults.controlcenter.AirDrop = true; + system.defaults.controlcenter.Display = false; + system.defaults.controlcenter.FocusModes = false; + system.defaults.controlcenter.NowPlaying = true; test = lib.strings.concatMapStringsSep "\n" (x: '' echo >&2 "checking defaults write in /${x}" From 32df51bf2b82dab724b845f4ad2d45bc1a0d0b9e Mon Sep 17 00:00:00 2001 From: Lucas Mendes Loureiro Date: Tue, 12 Nov 2024 01:24:22 +0000 Subject: [PATCH 111/139] fix(defaults): fixing #1107 --- modules/system/defaults-write.nix | 5 +- modules/system/defaults/clock.nix | 8 +++ modules/system/defaults/dock.nix | 8 +++ modules/system/defaults/finder.nix | 57 +++++++++++++++++-- modules/system/defaults/screencapture.nix | 12 ++++ .../system-defaults-write/activate-user.txt | 45 +++++++++++++++ tests/system-defaults-write.nix | 9 +++ 7 files changed, 138 insertions(+), 6 deletions(-) diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index 4249af99..87b179b8 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -17,7 +17,6 @@ let SoftwareUpdate = defaultsToList "/Library/Preferences/com.apple.SoftwareUpdate" cfg.SoftwareUpdate; # userDefaults - controlcenter = defaultsToList "~/Library/Preferences/ByHost/com.apple.controlcenter" cfg.controlcenter; GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences"; LaunchServices = defaultsToList "com.apple.LaunchServices" cfg.LaunchServices; NSGlobalDomain = defaultsToList "-g" cfg.NSGlobalDomain; @@ -35,9 +34,11 @@ let universalaccess = defaultsToList "com.apple.universalaccess" cfg.universalaccess; ActivityMonitor = defaultsToList "com.apple.ActivityMonitor" cfg.ActivityMonitor; WindowManager = defaultsToList "com.apple.WindowManager" cfg.WindowManager; + controlcenter = defaultsToList "~/Library/Preferences/ByHost/com.apple.controlcenter" cfg.controlcenter; CustomUserPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomUserPreferences); CustomSystemPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomSystemPreferences); + mkIfAttrs = list: mkIf (any (attrs: attrs != { }) list); in @@ -72,7 +73,6 @@ in system.activationScripts.userDefaults.text = mkIfAttrs [ - controlcenter GlobalPreferences LaunchServices NSGlobalDomain @@ -91,6 +91,7 @@ in ActivityMonitor CustomUserPreferences WindowManager + controlcenter ] '' # Set defaults diff --git a/modules/system/defaults/clock.nix b/modules/system/defaults/clock.nix index 3fae4640..50eb5176 100644 --- a/modules/system/defaults/clock.nix +++ b/modules/system/defaults/clock.nix @@ -5,6 +5,14 @@ with lib; { options = { + system.defaults.menuExtraClock.FlashDateSeparators = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + When enabled, the clock indicator (which by default is the colon) will flash on and off each second. Default is null. + ''; + }; + system.defaults.menuExtraClock.IsAnalog = mkOption { type = types.nullOr types.bool; default = null; diff --git a/modules/system/defaults/dock.nix b/modules/system/defaults/dock.nix index 5c4a4709..2d5c1619 100644 --- a/modules/system/defaults/dock.nix +++ b/modules/system/defaults/dock.nix @@ -149,6 +149,14 @@ in { else map (folder: { tile-data = { file-data = { _CFURLString = "file://" + folder; _CFURLStringType = 15; }; }; tile-type = if strings.hasInfix "." (last (splitString "/" folder)) then "file-tile" else "directory-tile"; }) value; }; + system.defaults.dock.scroll-to-open = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Scroll up on a Dock icon to show all Space's opened windows for an app, or open stack. The default is false. + ''; + }; + system.defaults.dock.show-process-indicators = mkOption { type = types.nullOr types.bool; default = null; diff --git a/modules/system/defaults/finder.nix b/modules/system/defaults/finder.nix index 51fff74f..5004b2c4 100644 --- a/modules/system/defaults/finder.nix +++ b/modules/system/defaults/finder.nix @@ -41,6 +41,15 @@ in ''; }; + system.defaults.finder.FXRemoveOldTrashItems = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Remove items in the trash after 30 days. + The default is false. + ''; + }; + system.defaults.finder.FXPreferredViewStyle = mkOption { type = types.nullOr types.str; default = null; @@ -55,7 +64,7 @@ in type = types.nullOr types.bool; default = null; description = '' - Whether to always show file extensions. The default is false. + Whether to always show file extensions. The default is false. ''; }; @@ -71,7 +80,39 @@ in type = types.nullOr types.bool; default = null; description = '' - Whether to allow quitting of the Finder. The default is false. + Whether to allow quitting of the Finder. The default is false. + ''; + }; + + system.defaults.finder.ShowExternalHardDrivesOnDesktop = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to show external disks on desktop. The default is true. + ''; + }; + + system.defaults.finder.ShowHardDrivesOnDesktop = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to show hard disks on desktop. The default is false. + ''; + }; + + system.defaults.finder.ShowMountedServersOnDesktop = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to show connected servers on desktop. The default is false. + ''; + }; + + system.defaults.finder.ShowRemovableMediaOnDesktop = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to show removable media (CDs, DVDs and iPods) on desktop. The default is true. ''; }; @@ -79,7 +120,7 @@ in type = types.nullOr types.bool; default = null; description = '' - Whether to show the full POSIX filepath in the window title. The default is false. + Whether to show the full POSIX filepath in the window title. The default is false. ''; }; @@ -91,11 +132,19 @@ in ''; }; + system.defaults.finder._FXSortFoldersFirstOnDesktop = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Keep folders on top when sorting by name on the desktop. The default is false. + ''; + }; + system.defaults.finder.FXEnableExtensionChangeWarning = mkOption { type = types.nullOr types.bool; default = null; description = '' - Whether to show warnings when change the file extension of files. The default is true. + Whether to show warnings when change the file extension of files. The default is true. ''; }; diff --git a/modules/system/defaults/screencapture.nix b/modules/system/defaults/screencapture.nix index b5efc22f..80dcaabb 100644 --- a/modules/system/defaults/screencapture.nix +++ b/modules/system/defaults/screencapture.nix @@ -29,6 +29,18 @@ with lib; ''; }; + system.defaults.screencapture.include-date = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Include date and time in screenshot filenames. The default is true. + Screenshot 2024-01-09 at 13.27.20.png would be an example for true. + + Screenshot.png + Screenshot 1.png would be an example for false. + ''; + }; + system.defaults.screencapture.show-thumbnail = mkOption { type = types.nullOr types.bool; default = null; diff --git a/tests/fixtures/system-defaults-write/activate-user.txt b/tests/fixtures/system-defaults-write/activate-user.txt index 57cfe67a..f6e9bbaa 100644 --- a/tests/fixtures/system-defaults-write/activate-user.txt +++ b/tests/fixtures/system-defaults-write/activate-user.txt @@ -205,6 +205,11 @@ defaults write .GlobalPreferences 'com.apple.sound.beep.sound' $'/System/Library/Sounds/Funk.aiff ' +defaults write com.apple.menuextra.clock 'FlashDateSeparators' $' + + + +' defaults write com.apple.menuextra.clock 'Show24Hour' $' @@ -299,6 +304,11 @@ defaults write com.apple.dock 'persistent-others' $' ' +defaults write com.apple.dock 'scroll-to-open' $' + + + +' defaults write com.apple.finder 'AppleShowAllExtensions' $' @@ -329,6 +339,11 @@ defaults write com.apple.finder 'FXPreferredViewStyle' $' Flwv ' +defaults write com.apple.finder 'FXRemoveOldTrashItems' $' + + + +' defaults write com.apple.finder 'NewWindowTarget' $' @@ -344,11 +359,31 @@ defaults write com.apple.finder 'QuitMenuItem' $' ' +defaults write com.apple.finder 'ShowExternalHardDrivesOnDesktop' $' + + + +' +defaults write com.apple.finder 'ShowHardDrivesOnDesktop' $' + + + +' +defaults write com.apple.finder 'ShowMountedServersOnDesktop' $' + + + +' defaults write com.apple.finder 'ShowPathbar' $' ' +defaults write com.apple.finder 'ShowRemovableMediaOnDesktop' $' + + + +' defaults write com.apple.finder 'ShowStatusBar' $' @@ -364,6 +399,11 @@ defaults write com.apple.finder '_FXSortFoldersFirst' $' ' +defaults write com.apple.finder '_FXSortFoldersFirstOnDesktop' $' + + + +' defaults write com.apple.HIToolbox 'AppleFnUsageType' $' @@ -371,6 +411,11 @@ defaults write com.apple.HIToolbox 'AppleFnUsageType' $'' +defaults write com.apple.screencapture 'include-date' $' + + + +' defaults write com.apple.screencapture 'location' $' diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix index c5c9b754..078cf82f 100644 --- a/tests/system-defaults-write.nix +++ b/tests/system-defaults-write.nix @@ -42,6 +42,7 @@ system.defaults.NSGlobalDomain."com.apple.springing.delay" = 0.0; system.defaults.NSGlobalDomain."com.apple.swipescrolldirection" = true; system.defaults.".GlobalPreferences"."com.apple.sound.beep.sound" = "/System/Library/Sounds/Funk.aiff"; + system.defaults.menuExtraClock.FlashDateSeparators = false; system.defaults.menuExtraClock.Show24Hour = false; system.defaults.menuExtraClock.ShowDayOfWeek = true; system.defaults.menuExtraClock.ShowDate = 2; @@ -50,11 +51,13 @@ system.defaults.dock.orientation = "left"; system.defaults.dock.persistent-apps = ["MyApp.app" "Cool.app"]; system.defaults.dock.persistent-others = ["~/Documents" "~/Downloads/file.txt"]; + system.defaults.dock.scroll-to-open = false; system.defaults.finder.AppleShowAllFiles = true; system.defaults.finder.ShowStatusBar = true; system.defaults.finder.ShowPathbar = true; system.defaults.finder.FXDefaultSearchScope = "SCcf"; system.defaults.finder.FXPreferredViewStyle = "Flwv"; + system.defaults.finder.FXRemoveOldTrashItems = false; system.defaults.finder.AppleShowAllExtensions = true; system.defaults.finder.CreateDesktop = false; system.defaults.finder.NewWindowTarget = "Other"; @@ -62,9 +65,15 @@ system.defaults.finder.QuitMenuItem = true; system.defaults.finder._FXShowPosixPathInTitle = true; system.defaults.finder._FXSortFoldersFirst = true; + system.defaults.finder._FXSortFoldersFirstOnDesktop = false; system.defaults.finder.FXEnableExtensionChangeWarning = false; + system.defaults.finder.ShowExternalHardDrivesOnDesktop = false; + system.defaults.finder.ShowHardDrivesOnDesktop = false; + system.defaults.finder.ShowMountedServersOnDesktop = false; + system.defaults.finder.ShowRemovableMediaOnDesktop = false; system.defaults.hitoolbox.AppleFnUsageType = "Show Emoji & Symbols"; system.defaults.screencapture.location = "/tmp"; + system.defaults.screencapture.include-date = true; system.defaults.screensaver.askForPassword = true; system.defaults.screensaver.askForPasswordDelay = 5; system.defaults.smb.NetBIOSName = "IMAC-000000"; From 67fbc7aa24cf0f4b5322b6f99fb3856bb9a1ab08 Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Fri, 31 May 2024 15:52:23 +0530 Subject: [PATCH 112/139] checks: add check to ensure Homebrew is installed Co-Authored-By: Michael Hoang --- modules/system/checks.nix | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index ec6e3b5d..ab6ea19d 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -28,6 +28,7 @@ let fi ''; + oldBuildUsers = '' if dscl . -list /Users | grep -q '^nixbld'; then echo "error: Detected old style nixbld users, aborting activation" >&2 @@ -283,6 +284,19 @@ let exit 2 fi ''; + + homebrewInstalled = '' + if [[ ! -f ${escapeShellArg config.homebrew.brewPrefix}/brew ]]; then + echo "error: Using the homebrew module requires homebrew installed, aborting activation" >&2 + echo "Homebrew doesn't seem to be installed. Please install homebrew separately." >&2 + echo "You can install homebrew using the following command:" >&2 + echo >&2 + # shellcheck disable=SC2016 + echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' >&2 + echo >&2 + exit 2 + fi + ''; in { @@ -331,6 +345,7 @@ in nixInstaller (mkIf cfg.verifyNixPath nixPath) oldSshAuthorizedKeysDirectory + (mkIf config.homebrew.enable homebrewInstalled) ]; system.activationScripts.checks.text = '' From 9077d812d8d6ed57b7c805467bb1bab78575e75a Mon Sep 17 00:00:00 2001 From: Joey Territo Date: Wed, 21 Feb 2024 16:13:30 -0600 Subject: [PATCH 113/139] activate-user script: fix broken NIX_PATH if paths contain spaces --- modules/system/checks.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index ab6ea19d..ef5f6d62 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -3,6 +3,9 @@ with lib; let + # Similar to lib.escapeShellArg but escapes "s instead of 's, to allow for parameter expansion in shells + escapeDoubleQuote = arg: ''"${replaceStrings ["\""] ["\"\\\"\""] (toString arg)}"''; + cfg = config.system.checks; darwinChanges = '' @@ -180,7 +183,7 @@ let ''; nixPath = '' - nixPath=${concatStringsSep ":" config.nix.nixPath}:$HOME/.nix-defexpr/channels + nixPath=${concatMapStringsSep ":" escapeDoubleQuote config.nix.nixPath}:$HOME/.nix-defexpr/channels darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true if ! test -e "$darwinConfig"; then From dae702993d18c608f07e9d320ccba816e9bce064 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 15 Nov 2024 14:03:43 +1100 Subject: [PATCH 114/139] activate-system: remove `enable` option Disabling this is not supported as `/run` gets cleared out on every reboot so it is necessary for ensuring that the `/run/current-system` symlink exists. --- README.md | 6 +++--- modules/nix/default.nix | 1 - modules/services/activate-system/default.nix | 20 ++++--------------- ...s-activate-system-changed-label-prefix.nix | 1 - tests/services-activate-system.nix | 2 -- 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index b9e3de7e..eb6228ca 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Furthermore there's `darwin-option` to introspect the settings of a system and i > NOTE: `darwin-option` is only available to non-flake installations. ``` -$ darwin-option services.activate-system.enable +$ darwin-option nix.linux-builder.enable Value: true @@ -180,10 +180,10 @@ Default: false Example: -no example +true Description: -Whether to activate system at boot time. +Whether to enable Linux builder. ``` There's also a small wiki https://github.com/LnL7/nix-darwin/wiki about diff --git a/modules/nix/default.nix b/modules/nix/default.nix index d99aae83..3751e8c4 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -774,7 +774,6 @@ in # Not in NixOS module warnings = [ - (mkIf (!config.services.activate-system.enable && cfg.distributedBuilds) "services.activate-system is not enabled, a reboot could cause distributed builds to stop working.") (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") ]; diff --git a/modules/services/activate-system/default.nix b/modules/services/activate-system/default.nix index c41d9637..6a982fe8 100644 --- a/modules/services/activate-system/default.nix +++ b/modules/services/activate-system/default.nix @@ -1,22 +1,11 @@ { config, lib, pkgs, ... }: -with lib; - -let - cfg = config.services.activate-system; -in - { - options = { - services.activate-system.enable = mkOption { - type = types.bool; - default = true; - description = "Whether to activate system at boot time."; - }; - }; - - config = mkIf cfg.enable { + imports = [ + (lib.mkRemovedOptionModule [ "services" "activate-system" "enable" ] "The `activate-system` service is now always enabled as it is necessary for a working `nix-darwin` setup.") + ]; + config = { launchd.daemons.activate-system = { script = '' set -e @@ -41,6 +30,5 @@ in serviceConfig.RunAtLoad = true; serviceConfig.KeepAlive.SuccessfulExit = false; }; - }; } diff --git a/tests/services-activate-system-changed-label-prefix.nix b/tests/services-activate-system-changed-label-prefix.nix index 1ae2bcf5..2c2f6038 100644 --- a/tests/services-activate-system-changed-label-prefix.nix +++ b/tests/services-activate-system-changed-label-prefix.nix @@ -1,7 +1,6 @@ { config, pkgs, ... }: { - services.activate-system.enable = true; launchd.labelPrefix = "org.nix-darwin"; test = '' diff --git a/tests/services-activate-system.nix b/tests/services-activate-system.nix index c519aa89..702bb26a 100644 --- a/tests/services-activate-system.nix +++ b/tests/services-activate-system.nix @@ -1,8 +1,6 @@ { config, pkgs, ... }: { - services.activate-system.enable = true; - test = '' echo checking activation service in /Library/LaunchDaemons >&2 grep "org.nixos.activate-system" ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist From d2498644fd84360e46ad90de3029066ad441e15a Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 19:56:15 +1100 Subject: [PATCH 115/139] nix-daemon: remove `with lib;` --- modules/services/nix-daemon.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index 6718ac05..6f931315 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -1,9 +1,9 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ config, lib, ... }: let cfg = config.services.nix-daemon; + + inherit (lib) mkDefault mkIf mkMerge mkOption types; in { From 698414e4091d919cc1b3af622f29bd594d3c21c3 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 19:56:15 +1100 Subject: [PATCH 116/139] nix-daemon: enable by default Single user installs have been unsupported by the official Nix installer since 2.4. --- modules/services/nix-daemon.nix | 2 +- pkgs/darwin-installer/default.nix | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index 6f931315..ffc7e651 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 = false; + default = true; description = "Whether to enable the nix-daemon service."; }; diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index 5c6d801e..78ca3c88 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -53,11 +53,6 @@ stdenv.mkDerivation { mkdir -p "$HOME/.nixpkgs" cp "${../../modules/examples/simple.nix}" "$config" chmod u+w "$config" - - # Enable nix-daemon service for multi-user installs. - if [ ! -w /nix/var/nix/db ]; then - sed -i 's/# services.nix-daemon.enable/services.nix-daemon.enable/' "$config" - fi fi # Skip when stdin is not a tty, eg. From 5d1b7ac696c2c9cf4206d7fbd3ebe3daa3b9bbd2 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 22:48:25 +1100 Subject: [PATCH 117/139] treewide: remove mentions of `services.nix-daemon.enable = true;` --- README.md | 1 - modules/examples/flake/flake.nix | 1 - modules/examples/hydra.nix | 2 -- modules/examples/lnl.nix | 1 - modules/examples/simple.nix | 1 - 5 files changed, 6 deletions(-) diff --git a/README.md b/README.md index eb6228ca..97dc7960 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,6 @@ Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out ]; # Auto upgrade nix package and the daemon service. - services.nix-daemon.enable = true; nix.package = pkgs.nix; } ``` diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index bd733bd9..d3967ef1 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -17,7 +17,6 @@ ]; # Auto upgrade nix package and the daemon service. - services.nix-daemon.enable = true; # nix.package = pkgs.nix; # Necessary for using flakes on this system. diff --git a/modules/examples/hydra.nix b/modules/examples/hydra.nix index eb1c5d9b..f87ed5d0 100644 --- a/modules/examples/hydra.nix +++ b/modules/examples/hydra.nix @@ -8,8 +8,6 @@ let in { - services.nix-daemon.enable = true; - nix.settings.substituters = [ "http://cache1" ]; nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index dccae077..2204c2fa 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -77,7 +77,6 @@ # serviceConfig.ProcessType = "Background"; # }; - services.nix-daemon.enable = true; # services.nix-daemon.enableSocketListener = true; nix.extraOptions = '' diff --git a/modules/examples/simple.nix b/modules/examples/simple.nix index 5baf009f..c76ecda8 100644 --- a/modules/examples/simple.nix +++ b/modules/examples/simple.nix @@ -12,7 +12,6 @@ # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; # Auto upgrade nix package and the daemon service. - # services.nix-daemon.enable = true; # nix.package = pkgs.nix; # Enable alternative shell support in nix-darwin. From 6d794390fa48afbe5d8b0020392f55bc1d800cb6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 20:23:06 +1100 Subject: [PATCH 118/139] checks: check single user installs don't have the `nix-daemon` enabled Remove suggestion to set `nix.useDaemon` as it came without an explanation of how the `nix-daemon` would be unmanaged and would most likely lead to most users running an old version of Nix as the daemon. --- modules/system/checks.nix | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index ab6ea19d..949a28ea 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -129,18 +129,26 @@ let fi ''; - singleUser = '' - if grep -q 'build-users-group =' /etc/nix/nix.conf; then - echo "error: The daemon is not enabled but this is a multi-user install, aborting activation" >&2 - echo "Enable the nix-daemon service:" >&2 - echo >&2 - echo " services.nix-daemon.enable = true;" >&2 - echo >&2 - echo "or set" >&2 - echo >&2 - echo " nix.useDaemon = true;" >&2 - echo >&2 - exit 2 + 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' + printf >&2 '\n' + printf >&2 ' services.nix-daemon.enable = false;\n' + printf >&2 '\n' + # shellcheck disable=SC2016 + 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 '\n' + exit 2 fi ''; @@ -337,7 +345,7 @@ in (mkIf cfg.verifyBuildUsers buildUsers) (mkIf cfg.verifyBuildUsers preSequoiaBuildUsers) (mkIf config.nix.configureBuildUsers buildGroupID) - (mkIf (!config.nix.useDaemon) singleUser) + nixDaemon nixStore (mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector) (mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser) From 7918e24e5b999e36c923573e9d6ac183b0c00f38 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 22:30:42 +1100 Subject: [PATCH 119/139] treewide: remove `nix.package` example --- .github/workflows/test.yml | 8 ++++---- README.md | 3 --- modules/examples/flake/flake.nix | 3 --- modules/examples/simple.nix | 3 --- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 623cb698..92d06d4d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,7 @@ jobs: nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ + "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ ~/.nixpkgs/darwin-configuration.nix nix-shell -A installer @@ -103,7 +103,7 @@ jobs: nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ + "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ ~/.nixpkgs/darwin-configuration.nix nix-shell -A installer @@ -145,7 +145,7 @@ jobs: nix flake init -t $darwin nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ + "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ flake.nix popd nix run .#darwin-rebuild -- \ @@ -178,7 +178,7 @@ jobs: nix flake init -t $darwin nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ - "s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ + "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ flake.nix popd nix run .#darwin-rebuild -- \ diff --git a/README.md b/README.md index 97dc7960..58bde794 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,6 @@ Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out environment.systemPackages = [ pkgs.vim ]; - - # Auto upgrade nix package and the daemon service. - nix.package = pkgs.nix; } ``` diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index d3967ef1..dbcc420a 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -16,9 +16,6 @@ [ pkgs.vim ]; - # Auto upgrade nix package and the daemon service. - # nix.package = pkgs.nix; - # Necessary for using flakes on this system. nix.settings.experimental-features = "nix-command flakes"; diff --git a/modules/examples/simple.nix b/modules/examples/simple.nix index c76ecda8..8d769a2c 100644 --- a/modules/examples/simple.nix +++ b/modules/examples/simple.nix @@ -11,9 +11,6 @@ # $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; - # Auto upgrade nix package and the daemon service. - # nix.package = pkgs.nix; - # Enable alternative shell support in nix-darwin. # programs.fish.enable = true; From 6d20de4ed606846230f766cc059bf01b47b8e2d4 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 22:32:55 +1100 Subject: [PATCH 120/139] nix: remove outdated note requiring managed daemon for distributedBuilds For Nix 1, some environment variables were set when using distributed builds requiring the Nix daemon to be managed by nix-darwin. However, support for Nix 1 has been removed and no other environment variables for Nix are set by default. --- modules/nix/default.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 3751e8c4..09e6e50d 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -191,9 +191,6 @@ in description = '' Whether to distribute builds to the machines listed in {option}`nix.buildMachines`. - - NOTE: This requires services.nix-daemon.enable for a - multi-user install. ''; }; From e07f08c0dcbf2f10a51f76ac2910c25e25ff4d84 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 23:05:03 +1100 Subject: [PATCH 121/139] uninstaller: fix restoring nix-daemon launchd daemon --- pkgs/darwin-uninstaller/configuration.nix | 3 +++ pkgs/darwin-uninstaller/default.nix | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index 75d1cacf..295477a6 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -12,6 +12,9 @@ with lib; launchd.daemons = mkForce {}; launchd.user.agents = mkForce {}; + # Don't try to reload `nix-daemon` + nix.useDaemon = mkForce false; + system.activationScripts.postUserActivation.text = mkAfter '' if [[ -L ~/.nix-defexpr/channels/darwin ]]; then nix-channel --remove darwin || true diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index 17c0a460..f6e04504 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -31,7 +31,9 @@ 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" - echo >&2 " - restore daemon service from nix installer (only when this is a multi-user install)" + if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then + echo >&2 " - restore nix-daemon service from nix installer as this is a multi-user install" + fi echo >&2 if [[ -t 0 ]]; then From ec5fce6061c26095f6de3a9cb9398171aa3b8c86 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 11 Nov 2024 23:45:00 +1100 Subject: [PATCH 122/139] uninstaller: check `nix-daemon` works after restoring --- pkgs/darwin-uninstaller/default.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index f6e04504..da58682e 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -89,8 +89,9 @@ in writeShellApplication { 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}')" ]] - echo >&2 ok + nix-store --store daemon -q --hash ${stdenv.shell} fi + echo >&2 ok ''; }; } From 4720d452f8095703d1978700a1ea4f94eb3c1520 Mon Sep 17 00:00:00 2001 From: Terrance Kennedy Date: Sun, 17 Nov 2024 13:21:26 -0700 Subject: [PATCH 123/139] manualHTML: support --redirects option in nixos-render-docs --- doc/manual/default.nix | 6 ++++++ doc/manual/redirects.json | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 doc/manual/redirects.json diff --git a/doc/manual/default.nix b/doc/manual/default.nix index deada0a4..d8e12f29 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -79,11 +79,17 @@ in rec { '@DARWIN_OPTIONS_JSON@' \ ${optionsJSON}/share/doc/darwin/options.json + # Pass --redirects option if nixos-render-docs supports it + if nixos-render-docs manual html --help | grep --silent -E '^\s+--redirects\s'; then + redirects_opt="--redirects ${./redirects.json}" + fi + # TODO: --manpage-urls? nixos-render-docs -j $NIX_BUILD_CORES manual html \ --manpage-urls ${pkgs.writeText "manpage-urls.json" "{}"} \ --revision ${lib.escapeShellArg revision} \ --generator "nixos-render-docs ${lib.version}" \ + $redirects_opt \ --stylesheet style.css \ --stylesheet highlightjs/mono-blue.css \ --script ./highlightjs/highlight.pack.js \ diff --git a/doc/manual/redirects.json b/doc/manual/redirects.json new file mode 100644 index 00000000..46e6796c --- /dev/null +++ b/doc/manual/redirects.json @@ -0,0 +1,5 @@ +{ + "book-darwin-manual": [ + "index.html#book-darwin-manual" + ] +} From 23f312e48a252e348fc8884f2abc7975f976aac0 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sat, 16 Nov 2024 21:53:32 +1100 Subject: [PATCH 124/139] nix-tools: set `meta.mainProgram` --- pkgs/nix-tools/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/nix-tools/default.nix b/pkgs/nix-tools/default.nix index 4e4336a8..5fdc3821 100644 --- a/pkgs/nix-tools/default.nix +++ b/pkgs/nix-tools/default.nix @@ -17,6 +17,7 @@ let inherit name src; dir = "bin"; isExecutable = true; + meta.mainProgram = name; } // env); path = "${extraPath}:${systemPath}"; From fece297d640dcbf9aa9f1829caa5f50d47996f2c Mon Sep 17 00:00:00 2001 From: isabel Date: Sun, 17 Nov 2024 14:20:32 +0000 Subject: [PATCH 125/139] fix: allow users to disable the homebrew check --- modules/system/checks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/checks.nix b/modules/system/checks.nix index f3f1e6d4..796e7e4e 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -297,7 +297,7 @@ let ''; homebrewInstalled = '' - if [[ ! -f ${escapeShellArg config.homebrew.brewPrefix}/brew ]]; then + if [[ ! -f ${escapeShellArg config.homebrew.brewPrefix}/brew && -z "''${INSTALLING_HOMEBREW:-}" ]]; then echo "error: Using the homebrew module requires homebrew installed, aborting activation" >&2 echo "Homebrew doesn't seem to be installed. Please install homebrew separately." >&2 echo "You can install homebrew using the following command:" >&2 From 57c144515a59efde1dd59078e280a82b32626311 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 03:12:30 +1100 Subject: [PATCH 126/139] system: always add /run to /etc/synthetic.conf on macOS 10.15 onwards Currently if nix-darwin is uninstalled then reinstalled without rebooting, then the `/run` symlink will still remain and nix-darwin won't readd `run` to `/etc/synthetic.conf` meaning the system will be broken on next reboot. --- modules/system/base.nix | 73 +++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/modules/system/base.nix b/modules/system/base.nix index 43c9d7ff..f20e2b64 100644 --- a/modules/system/base.nix +++ b/modules/system/base.nix @@ -2,46 +2,49 @@ { system.activationScripts.createRun.text = '' - if [[ ! -L /run ]]; then - # This file doesn't exist by default on macOS and is only supported after 10.15 - # however every system with Nix installed should have this file otherwise `/nix` - # wouldn't exist. - if [[ -e /etc/synthetic.conf ]]; then - if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then - echo "setting up /run via /etc/synthetic.conf..." - printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null - fi + IFS="." read -r -a macOSVersion <<< "$(sw_vers -productVersion)" - # for Catalina (10.15) - sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true - # for Big Sur (11.0) - sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true + if [[ ''${macOSVersion[0]} -gt 10 || ( ''${macOSVersion[0]} -eq 10 && ''${macOSVersion[1]} -ge 15 ) ]]; then + if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then + echo "setting up /run via /etc/synthetic.conf..." + printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null + fi - if [[ ! -L /run ]]; then - printf >&2 'error: apfs.util failed to symlink /run, aborting activation\n' - printf >&2 'To create a symlink from /run to /var/run, please run:\n' - printf >&2 '\n' - printf >&2 "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" - printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B # For Catalina\n' - printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later\n' >&2 - printf >&2 '\n' - printf >&2 'The current contents of /etc/synthetic.conf is:\n' - printf >&2 '\n' - sudo sed 's/^/ /' /etc/synthetic.conf >&2 - printf >&2 '\n' - exit 1 - fi + if [[ ''${macOSVersion[0]} -gt 10 ]]; then + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true else - echo "setting up /run..." - sudo ln -sfn private/var/run /run + sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B || true + fi - if [[ ! -L /run ]]; then - printf >&2 'error: failed to symlink /run, aborting activation\n' - printf >&2 'To create a symlink from /run to /var/run, please run:\n' - printf >&2 '\n' - printf >&2 '$ sudo ln -sfn private/var/link /run\n' - exit 1 + if [[ ! -L /run ]]; then + printf >&2 'error: apfs.util failed to symlink /run, aborting activation\n' + printf >&2 'To create a symlink from /run to /var/run, please run:\n' + printf >&2 '\n' + printf >&2 "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" + + if [[ ''${macOSVersion[0]} -gt 10 ]]; then + printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t\n' + else + printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B\n' fi + + printf >&2 '\n' + printf >&2 'The current contents of /etc/synthetic.conf is:\n' + printf >&2 '\n' + sudo sed 's/^/ /' /etc/synthetic.conf >&2 + printf >&2 '\n' + exit 1 + fi + else + echo "setting up /run..." + sudo ln -sfn private/var/run /run + + if [[ ! -L /run ]]; then + printf >&2 'error: failed to symlink /run, aborting activation\n' + printf >&2 'To create a symlink from /run to /var/run, please run:\n' + printf >&2 '\n' + printf >&2 '$ sudo ln -sfn private/var/link /run\n' + exit 1 fi fi ''; From 5cc3c00f9b689fa98c524674ddf5a569005e4bd9 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 02:16:56 +1100 Subject: [PATCH 127/139] readme: move sections under new Channels section --- README.md | 109 +++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 58bde794..3bbaf5cb 100644 --- a/README.md +++ b/README.md @@ -18,60 +18,14 @@ As the official Nix installer does not include an automated uninstaller, and man - 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 [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system) supports both flake-based and channel-based setups. -## Installing -If you wish to use nix-darwin with flakes, please refer to the [flakes](#flakes) section. -```bash -nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer -./result/bin/darwin-installer -``` +## Getting started -## Updating +Despite being an experimental feature in Nix currently, nix-darwin recommends that beginners use flakes to manage their nix-darwin configurations. -The installer will configure a channel for this repository. - -```bash -nix-channel --update darwin -darwin-rebuild changelog -``` - -> NOTE: If you are using Nix as a daemon service the channel for that will be owned by root. -> Use `sudo -i nix-channel --update darwin` instead. - -## Uninstalling - -To run the latest version of the uninstaller, you can run the following command: - -``` -nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller -``` - -If that command doesn't work for you, you can try the locally installed uninstaller: - -``` -darwin-uninstaller -``` - -## Example configuration - -Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out -[modules/examples](https://github.com/LnL7/nix-darwin/tree/master/modules/examples) for some example configurations. - -```nix -{ pkgs, ... }: -{ - # List packages installed in system profile. To search by name, run: - # $ nix-env -qaP | grep wget - environment.systemPackages = - [ pkgs.vim - ]; -} -``` - -## Flakes - -nix-darwin aims for both non-flake and flake configurations to be well supported despite flakes being an experimental feature in Nix. +
+Flakes (Recommended for beginners) ### Step 1. Creating `flake.nix` @@ -156,6 +110,47 @@ nix-darwin.lib.darwinSystem { { pkgs, lib, inputs }: # inputs.self, inputs.nix-darwin, and inputs.nixpkgs can be accessed here ``` +
+ +
+Channels + +### Installing + +```bash +nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer +./result/bin/darwin-installer +``` + +### Updating + +The installer will configure a channel for this repository. + +```bash +nix-channel --update darwin +darwin-rebuild changelog +``` + +> NOTE: If you are using Nix as a daemon service the channel for that will be owned by root. +> Use `sudo -i nix-channel --update darwin` instead. + +### Example configuration + +Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out +[modules/examples](https://github.com/LnL7/nix-darwin/tree/master/modules/examples) for some example configurations. + +```nix +{ pkgs, ... }: +{ + # List packages installed in system profile. To search by name, run: + # $ nix-env -qaP | grep wget + environment.systemPackages = + [ pkgs.vim + ]; +} +``` + +
## Documentation @@ -185,6 +180,20 @@ Whether to enable Linux builder. There's also a small wiki https://github.com/LnL7/nix-darwin/wiki about specific topics, like macOS upgrades. +## Uninstalling + +To run the latest version of the uninstaller, you can run the following command: + +``` +nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller +``` + +If that command doesn't work for you, you can try the locally installed uninstaller: + +``` +darwin-uninstaller +``` + ## Tests There are basic tests that run sanity checks for some of the modules, From 9a1bea70d5728a19ee0a090dc0bcdeb73f09b7a4 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 02:33:37 +1100 Subject: [PATCH 128/139] installer: move creating default configuration to README --- .github/workflows/test.yml | 20 ++++++++------------ README.md | 25 ++++++------------------- modules/examples/simple.nix | 5 ++--- pkgs/darwin-installer/default.nix | 25 +++---------------------- 4 files changed, 19 insertions(+), 56 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 92d06d4d..90bd6fdd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -49,17 +49,15 @@ jobs: run: | export NIX_PATH=$HOME/.nix-defexpr/channels - # We run nix-darwin twice to test that it can create darwin-configuration correctly for us - # but we expect it to fail setting up /etc/nix/nix.conf - nix-shell -A installer || true + mkdir -p ~/.config/nix-darwin + cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - ~/.nixpkgs/darwin-configuration.nix + ~/.config/nix-darwin/configuration.nix - nix-shell -A installer - nix-shell -A installer.check + nix-shell -A installer -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Build and activate default derivation run: | . /etc/static/bashrc @@ -97,17 +95,15 @@ jobs: run: | export NIX_PATH=$HOME/.nix-defexpr/channels - # We run nix-darwin twice to test that it can create darwin-configuration correctly for us - # but we expect it to fail setting up /etc/nix/nix.conf - nix-shell -A installer || true + mkdir -p ~/.config/nix-darwin + cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1) /usr/bin/sed -i.bak \ "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ - ~/.nixpkgs/darwin-configuration.nix + ~/.config/nix-darwin/configuration.nix - nix-shell -A installer - nix-shell -A installer.check + nix-shell -A installer -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Build and activate default derivation run: | . /etc/static/bashrc diff --git a/README.md b/README.md index 3bbaf5cb..bfc825e9 100644 --- a/README.md +++ b/README.md @@ -115,14 +115,18 @@ nix-darwin.lib.darwinSystem {
Channels -### Installing +### Step 1. Creating `configuration.nix` + +Copy the [simple](./modules/examples/simple.nix) example to `~/.config/nix-darwin/configuration.nix`. + +### Step 2. Installing `nix-darwin` ```bash nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer ./result/bin/darwin-installer ``` -### Updating +### Step 3. Updating `nix-darwin` The installer will configure a channel for this repository. @@ -133,23 +137,6 @@ darwin-rebuild changelog > NOTE: If you are using Nix as a daemon service the channel for that will be owned by root. > Use `sudo -i nix-channel --update darwin` instead. - -### Example configuration - -Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out -[modules/examples](https://github.com/LnL7/nix-darwin/tree/master/modules/examples) for some example configurations. - -```nix -{ pkgs, ... }: -{ - # List packages installed in system profile. To search by name, run: - # $ nix-env -qaP | grep wget - environment.systemPackages = - [ pkgs.vim - ]; -} -``` -
## Documentation diff --git a/modules/examples/simple.nix b/modules/examples/simple.nix index 8d769a2c..5771ec60 100644 --- a/modules/examples/simple.nix +++ b/modules/examples/simple.nix @@ -7,9 +7,8 @@ [ pkgs.vim ]; - # Use a custom configuration.nix location. - # $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix - # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; + # Use custom location for configuration.nix. + environment.darwinConfig = "$HOME/.config/nix-darwin/configuration.nix"; # Enable alternative shell support in nix-darwin. # programs.fish.enable = true; diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index 78ca3c88..0eed5187 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -47,25 +47,6 @@ stdenv.mkDerivation { echo >&2 "Installing nix-darwin..." echo >&2 - config="$HOME/.nixpkgs/darwin-configuration.nix" - if ! test -f "$config"; then - echo "copying example configuration.nix" >&2 - mkdir -p "$HOME/.nixpkgs" - cp "${../../modules/examples/simple.nix}" "$config" - chmod u+w "$config" - fi - - # Skip when stdin is not a tty, eg. - # $ yes | darwin-installer - if test -t 0; then - read -p "Would you like to edit the default configuration.nix before starting? [y/N] " i - case "$i" in - y|Y) - PATH=$_PATH ''${EDITOR:-nano} "$config" - ;; - esac - fi - i=y darwinPath=$(NIX_PATH=$HOME/.nix-defexpr/channels nix-instantiate --eval -E '' 2> /dev/null) || true if ! test -e "$darwinPath"; then @@ -81,13 +62,13 @@ stdenv.mkDerivation { fi export NIX_PATH=${nixPath} - system=$(nix-build '' -I "darwin-config=$config" -A system --no-out-link --show-trace) + system=$(nix-build '' -A system --no-out-link --show-trace) export PATH=$system/sw/bin:$PATH - darwin-rebuild "$action" -I "darwin-config=$config" + darwin-rebuild "$action" echo >&2 - echo >&2 " Open '$config' to get started." + echo >&2 " Installation complete." echo >&2 " See the README for more information: https://github.com/LnL7/nix-darwin/blob/master/README.md" echo >&2 echo >&2 " Please log out and log in again to make sure nix-darwin is properly loaded." From 65ea368ebbed4fa52a1a59fcb06848c49b310c9c Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 02:51:42 +1100 Subject: [PATCH 129/139] installer: move channel creation to README --- .github/workflows/test.yml | 6 ++++-- README.md | 16 +++++++++------- pkgs/darwin-installer/default.nix | 14 -------------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90bd6fdd..73a3fb71 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,8 +41,9 @@ jobs: with: install_url: https://releases.nixos.org/nix/nix-2.18.8/install nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} - - name: Install ${{ env.CURRENT_STABLE_CHANNEL }} channel + - name: Install channels run: | + nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs nix-channel --update - name: Install nix-darwin and test @@ -87,8 +88,9 @@ jobs: with: install_url: https://releases.nixos.org/nix/nix-2.24.9/install nix_path: nixpkgs=channel:nixpkgs-unstable - - name: Install nixpkgs-unstable channel + - name: Install channels run: | + nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs nix-channel --update - name: Install nix-darwin and test diff --git a/README.md b/README.md index bfc825e9..f029c9a5 100644 --- a/README.md +++ b/README.md @@ -119,24 +119,26 @@ nix-darwin.lib.darwinSystem { Copy the [simple](./modules/examples/simple.nix) example to `~/.config/nix-darwin/configuration.nix`. -### Step 2. Installing `nix-darwin` +### Step 2. Adding `nix-darwin` channel + +```bash +nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin +nix-channel --update +``` + +### Step 3. Installing `nix-darwin` ```bash nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer ./result/bin/darwin-installer ``` -### Step 3. Updating `nix-darwin` - -The installer will configure a channel for this repository. +### Step 4. Updating `nix-darwin` ```bash nix-channel --update darwin darwin-rebuild changelog ``` - -> NOTE: If you are using Nix as a daemon service the channel for that will be owned by root. -> Use `sudo -i nix-channel --update darwin` instead. ## Documentation diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index 0eed5187..630c5bfe 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -47,20 +47,6 @@ stdenv.mkDerivation { echo >&2 "Installing nix-darwin..." echo >&2 - i=y - darwinPath=$(NIX_PATH=$HOME/.nix-defexpr/channels nix-instantiate --eval -E '' 2> /dev/null) || true - if ! test -e "$darwinPath"; then - if test -t 0; then - read -p "Would you like to manage with nix-channel? [y/N] " i - fi - case "$i" in - y|Y) - nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin - nix-channel --update - ;; - esac - fi - export NIX_PATH=${nixPath} system=$(nix-build '' -A system --no-out-link --show-trace) From 62f9402af0a5412045385b8ba4cb79bd8880a2c3 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 12:33:06 +1100 Subject: [PATCH 130/139] readme: add using `nix-darwin` section for non-flakes --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f029c9a5..a4ce5986 100644 --- a/README.md +++ b/README.md @@ -133,11 +133,20 @@ nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer ./result/bin/darwin-installer ``` -### Step 4. Updating `nix-darwin` +### Step 4. Using `nix-darwin` + +After installing, you can run `darwin-rebuild` to apply changes to your system: + +```bash +darwin-rebuild switch +``` + +### Step 5. Updating `nix-darwin` + +You can update `nix-darwin` using the following command: ```bash nix-channel --update darwin -darwin-rebuild changelog ``` From 60ed03d0b10fa88054a73a0d34338f03f8d73f53 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 02:14:06 +1100 Subject: [PATCH 131/139] installer: remove --- .github/workflows/test.yml | 12 ++-- README.md | 7 +- default.nix | 17 +---- pkgs/darwin-installer/default.nix | 109 ------------------------------ 4 files changed, 14 insertions(+), 131 deletions(-) delete mode 100644 pkgs/darwin-installer/default.nix diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73a3fb71..43aed103 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs nix-channel --update - - name: Install nix-darwin and test + - name: Install nix-darwin run: | export NIX_PATH=$HOME/.nix-defexpr/channels @@ -58,7 +58,9 @@ jobs: "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ ~/.config/nix-darwin/configuration.nix - nix-shell -A installer -I darwin-config=$HOME/.config/nix-darwin/configuration.nix + nix run .#darwin-rebuild \ + -- switch \ + -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Build and activate default derivation run: | . /etc/static/bashrc @@ -93,7 +95,7 @@ jobs: nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs nix-channel --update - - name: Install nix-darwin and test + - name: Install nix-darwin run: | export NIX_PATH=$HOME/.nix-defexpr/channels @@ -105,7 +107,9 @@ jobs: "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ ~/.config/nix-darwin/configuration.nix - nix-shell -A installer -I darwin-config=$HOME/.config/nix-darwin/configuration.nix + nix run .#darwin-rebuild \ + -- switch \ + -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Build and activate default derivation run: | . /etc/static/bashrc diff --git a/README.md b/README.md index a4ce5986..c7fb408f 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x ### Step 2. Installing `nix-darwin` -Instead of using `darwin-installer`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command: +Unlike NixOS, `nix-darwin` does not have an installer, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command: ```bash nix run nix-darwin -- switch --flake ~/.config/nix-darwin @@ -128,9 +128,10 @@ nix-channel --update ### Step 3. Installing `nix-darwin` +To install `nix-darwin`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command: + ```bash -nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer -./result/bin/darwin-installer +nix --extra-experimental-features "nix-command flakes" run nix-darwin -- switch -I darwin-config=$HOME/.config/nix-darwin/configuration.nix ``` ### Step 4. Using `nix-darwin` diff --git a/default.nix b/default.nix index c93b4783..075ae6d2 100644 --- a/default.nix +++ b/default.nix @@ -1,8 +1,8 @@ { nixpkgs ? , configuration ? -, lib ? pkgs.lib -, pkgs ? import nixpkgs { inherit system; } , system ? builtins.currentSystem +, pkgs ? import nixpkgs { inherit system; } +, lib ? pkgs.lib }: let @@ -15,20 +15,7 @@ let nixpkgs.system = lib.mkDefault system; }; }; - - # The source code of this repo needed by the installer. - nix-darwin = lib.cleanSource ( - lib.cleanSourceWith { - # We explicitly specify a name here otherwise `cleanSource` will use the - # basename of ./. which might be different for different clones of this - # repo leading to non-reproducible outputs. - name = "nix-darwin"; - src = ./.; - } - ); in - eval // { - installer = pkgs.callPackage ./pkgs/darwin-installer { inherit nix-darwin; }; uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { }; } diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix deleted file mode 100644 index 630c5bfe..00000000 --- a/pkgs/darwin-installer/default.nix +++ /dev/null @@ -1,109 +0,0 @@ -{ stdenv, nix, pkgs, nix-darwin }: - -let - nixPath = pkgs.lib.concatStringsSep ":" [ - "darwin=${nix-darwin}" - "nixpkgs=${pkgs.path}" - "$HOME/.nix-defexpr/channels" - "/nix/var/nix/profiles/per-user/root/channels" - "$NIX_PATH" - ]; -in - -stdenv.mkDerivation { - name = "darwin-installer"; - preferLocalBuild = true; - - unpackPhase = ":"; - - installPhase = '' - mkdir -p $out/bin - echo "$shellHook" > $out/bin/darwin-installer - chmod +x $out/bin/darwin-installer - ''; - - shellHook = '' - #!${stdenv.shell} - set -e - - _PATH=$PATH - export PATH=/nix/var/nix/profiles/default/bin:${nix}/bin:${pkgs.gnused}/bin:${pkgs.openssh}/bin:/usr/bin:/bin:/usr/sbin:/sbin - - action=switch - while [ "$#" -gt 0 ]; do - i="$1"; shift 1 - case "$i" in - --help) - echo "darwin-installer: [--help] [--check]" - exit - ;; - --check) - action=check - ;; - esac - done - - echo >&2 - echo >&2 "Installing nix-darwin..." - echo >&2 - - export NIX_PATH=${nixPath} - system=$(nix-build '' -A system --no-out-link --show-trace) - - export PATH=$system/sw/bin:$PATH - darwin-rebuild "$action" - - echo >&2 - echo >&2 " Installation complete." - echo >&2 " See the README for more information: https://github.com/LnL7/nix-darwin/blob/master/README.md" - echo >&2 - echo >&2 " Please log out and log in again to make sure nix-darwin is properly loaded." - echo >&2 - exit - ''; - - passthru.check = stdenv.mkDerivation { - name = "run-darwin-test"; - shellHook = '' - set -e - echo >&2 "running installer tests..." - echo >&2 - - echo >&2 "checking configuration.nix" - test -f ~/.nixpkgs/darwin-configuration.nix - test -w ~/.nixpkgs/darwin-configuration.nix - echo >&2 "checking darwin channel" - readlink ~/.nix-defexpr/channels/darwin - test -e ~/.nix-defexpr/channels/darwin - echo >&2 "checking /etc" - readlink /etc/static - test -e /etc/static - echo >&2 "checking profile" - cat /etc/profile - (! grep nix-daemon.sh /etc/profile) - echo >&2 "checking /run/current-system" - readlink /run - test -e /run - readlink /run/current-system - test -e /run/current-system - echo >&2 "checking system profile" - readlink /nix/var/nix/profiles/system - test -e /nix/var/nix/profiles/system - - echo >&2 "checking bash environment" - env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH' - env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin - env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' - env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels - - echo >&2 "checking zsh environment" - env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH' - env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin - env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' - env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels - - echo >&2 ok - exit - ''; - }; -} From 3c27b0874017b325b0ed7269705c0d2df5df42dc Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 12:46:35 +1100 Subject: [PATCH 132/139] readme: update `Documentation` section --- README.md | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c7fb408f..2623b9fa 100644 --- a/README.md +++ b/README.md @@ -153,31 +153,9 @@ nix-channel --update darwin ## Documentation -Reference documentation of all the options is available [here](https://daiderd.com/nix-darwin/manual/index.html). -This can also be accessed locally using `man 5 configuration.nix`. +`darwin-help` will open up a local copy of the reference documentation, it can also be found online [here](https://daiderd.com/nix-darwin/manual/index.html). -`darwin-help` will open a HTML version of the manpage in the default browser. - -Furthermore there's `darwin-option` to introspect the settings of a system and its available options. -> NOTE: `darwin-option` is only available to non-flake installations. - -``` -$ darwin-option nix.linux-builder.enable -Value: -true - -Default: -false - -Example: -true - -Description: -Whether to enable Linux builder. -``` - -There's also a small wiki https://github.com/LnL7/nix-darwin/wiki about -specific topics, like macOS upgrades. +The documentation is also available as manpages by running `man 5 configuration.nix`. ## Uninstalling From a4d4d12e3885f9fea3100c73d024664ea9572f94 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 13:11:30 +1100 Subject: [PATCH 133/139] examples: change default architecture to `aarch64-darwin` --- .github/workflows/test.yml | 14 ++++++++++++-- modules/examples/flake/flake.nix | 5 +---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 43aed103..b9eb32f5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -149,6 +149,9 @@ jobs: /usr/bin/sed -i.bak \ "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ flake.nix + /usr/bin/sed -i.bak \ + 's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \ + flake.nix popd nix run .#darwin-rebuild -- \ switch --flake ~/.config/nix-darwin#simple \ @@ -157,7 +160,9 @@ jobs: - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface run: | . /etc/static/bashrc - darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} + darwin-rebuild switch --flake ~/.config/nix-darwin#simple \ + --override-input nix-darwin . \ + --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - name: Test uninstallation of nix-darwin run: | nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} @@ -182,6 +187,9 @@ jobs: /usr/bin/sed -i.bak \ "s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \ flake.nix + /usr/bin/sed -i.bak \ + 's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \ + flake.nix popd nix run .#darwin-rebuild -- \ switch --flake ~/.config/nix-darwin#simple \ @@ -190,7 +198,9 @@ jobs: - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface run: | . /etc/static/bashrc - darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/nixpkgs-unstable + darwin-rebuild switch --flake ~/.config/nix-darwin#simple \ + --override-input nix-darwin . \ + --override-input nixpkgs nixpkgs/nixpkgs-unstable - name: Test uninstallation of nix-darwin run: | nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable diff --git a/modules/examples/flake/flake.nix b/modules/examples/flake/flake.nix index dbcc420a..4520b8ff 100644 --- a/modules/examples/flake/flake.nix +++ b/modules/examples/flake/flake.nix @@ -30,7 +30,7 @@ system.stateVersion = 5; # The platform the configuration will be used on. - nixpkgs.hostPlatform = "x86_64-darwin"; + nixpkgs.hostPlatform = "aarch64-darwin"; }; in { @@ -39,8 +39,5 @@ darwinConfigurations."simple" = nix-darwin.lib.darwinSystem { modules = [ configuration ]; }; - - # Expose the package set, including overlays, for convenience. - darwinPackages = self.darwinConfigurations."simple".pkgs; }; } From 9fe8a0a7387d24a4e5113587256e37d5f1294486 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 17 Nov 2024 16:16:32 +1100 Subject: [PATCH 134/139] ci: check that switching to new configurations works after installation --- .github/workflows/test.yml | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b9eb32f5..d26e0519 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -61,10 +61,17 @@ jobs: nix run .#darwin-rebuild \ -- switch \ -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - - name: Build and activate default derivation + - name: Switch to new configuration run: | . /etc/static/bashrc + + /usr/bin/sed -i.bak \ + "s/pkgs.vim/pkgs.hello/" \ + ~/.config/nix-darwin/configuration.nix + darwin-rebuild switch -I darwin=. + + hello - name: Test uninstallation of nix-darwin run: | nix run .#darwin-uninstaller \ @@ -110,10 +117,17 @@ jobs: nix run .#darwin-rebuild \ -- switch \ -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - - name: Build and activate default derivation + - name: Switch to new configuration run: | . /etc/static/bashrc + + /usr/bin/sed -i.bak \ + "s/pkgs.vim/pkgs.hello/" \ + ~/.config/nix-darwin/configuration.nix + darwin-rebuild switch -I darwin=. + + hello - name: Test uninstallation of nix-darwin run: | # A regression in Nix 2.19 means we need to put `--extra-experimental-features` before `--override-input` @@ -157,12 +171,19 @@ jobs: switch --flake ~/.config/nix-darwin#simple \ --override-input nix-darwin . \ --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface + - name: Switch to new configuration run: | . /etc/static/bashrc + + /usr/bin/sed -i.bak \ + "s/pkgs.vim/pkgs.hello/" \ + ~/.config/nix-darwin/flake.nix + darwin-rebuild switch --flake ~/.config/nix-darwin#simple \ --override-input nix-darwin . \ --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} + + hello - name: Test uninstallation of nix-darwin run: | nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} @@ -195,12 +216,19 @@ jobs: switch --flake ~/.config/nix-darwin#simple \ --override-input nix-darwin . \ --override-input nixpkgs nixpkgs/nixpkgs-unstable - - name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface + - name: Switch to new configuration run: | . /etc/static/bashrc + + /usr/bin/sed -i.bak \ + "s/pkgs.vim/pkgs.hello/" \ + ~/.config/nix-darwin/flake.nix + darwin-rebuild switch --flake ~/.config/nix-darwin#simple \ --override-input nix-darwin . \ --override-input nixpkgs nixpkgs/nixpkgs-unstable + + hello - name: Test uninstallation of nix-darwin run: | nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable From 2ca27ba780bb072e9fb80565684ad81c2664f9d0 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 19 Nov 2024 12:50:32 +1100 Subject: [PATCH 135/139] ci: source `/etc/bashrc` instead of `/etc/static/bashrc` This should no longer be necessary after #687, as we can be sure that if activation succeeded, that `/etc/bashrc` points to `/etc/static/bashrc`. --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d26e0519..6e06117b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,7 +63,7 @@ jobs: -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Switch to new configuration run: | - . /etc/static/bashrc + . /etc/bashrc /usr/bin/sed -i.bak \ "s/pkgs.vim/pkgs.hello/" \ @@ -119,7 +119,7 @@ jobs: -I darwin-config=$HOME/.config/nix-darwin/configuration.nix - name: Switch to new configuration run: | - . /etc/static/bashrc + . /etc/bashrc /usr/bin/sed -i.bak \ "s/pkgs.vim/pkgs.hello/" \ @@ -173,7 +173,7 @@ jobs: --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - name: Switch to new configuration run: | - . /etc/static/bashrc + . /etc/bashrc /usr/bin/sed -i.bak \ "s/pkgs.vim/pkgs.hello/" \ @@ -218,7 +218,7 @@ jobs: --override-input nixpkgs nixpkgs/nixpkgs-unstable - name: Switch to new configuration run: | - . /etc/static/bashrc + . /etc/bashrc /usr/bin/sed -i.bak \ "s/pkgs.vim/pkgs.hello/" \ From d57e74864bccd31e081443733bfaee1eda85a242 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 19 Nov 2024 12:54:51 +1100 Subject: [PATCH 136/139] uninstaller: always specify `--extra-experimental-features` first See https://github.com/NixOS/nix/issues/11891 --- .github/workflows/test.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e06117b..c531aa5f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,12 +74,14 @@ jobs: hello - name: Test uninstallation of nix-darwin run: | + # We need to specify `--extra-experimental-features` because `experimental-features` is set by + # `cachix/install-nix-action` but not by our default config above nix run .#darwin-uninstaller \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - --extra-experimental-features "nix-command flakes" + --extra-experimental-features "nix-command flakes" \ + --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} nix run .#darwin-uninstaller.tests.uninstaller \ - --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \ - --extra-experimental-features "nix-command flakes" + --extra-experimental-features "nix-command flakes" \ + --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - name: Debugging tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 @@ -130,7 +132,8 @@ jobs: hello - name: Test uninstallation of nix-darwin run: | - # A regression in Nix 2.19 means we need to put `--extra-experimental-features` before `--override-input` + # We need to specify `--extra-experimental-features` because `experimental-features` is set by + # `cachix/install-nix-action` but not by our default config above nix run .#darwin-uninstaller \ --extra-experimental-features "nix-command flakes" \ --override-input nixpkgs nixpkgs/nixpkgs-unstable From 095ba5502c83c5fd8173a1b0dbc99a0e1be7e42d Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Thu, 21 Nov 2024 10:52:11 +1100 Subject: [PATCH 137/139] default: expose all the `darwin-*` commands Change `uninstaller` to `darwin-uninstaller` to match flake attribute --- README.md | 3 ++- default.nix | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2623b9fa..d5373273 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,8 @@ nix-channel --update To install `nix-darwin`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command: ```bash -nix --extra-experimental-features "nix-command flakes" run nix-darwin -- switch -I darwin-config=$HOME/.config/nix-darwin/configuration.nix +nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A darwin-rebuild +./result/bin/darwin-rebuild switch -I darwin-config=$HOME/.config/nix-darwin/configuration.nix ``` ### Step 4. Using `nix-darwin` diff --git a/default.nix b/default.nix index 075ae6d2..8bae7e1e 100644 --- a/default.nix +++ b/default.nix @@ -17,5 +17,7 @@ let }; in eval // { - uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { }; + darwin-uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { }; + + inherit (pkgs.callPackage ./pkgs/nix-tools { }) darwin-option darwin-rebuild darwin-version; } From caa23e878f7f6fecb978bb91c1d208bf94a62c43 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 22 Nov 2024 11:18:17 +1100 Subject: [PATCH 138/139] github-runner: make `umask` quiet --- modules/services/github-runner/service.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/github-runner/service.nix b/modules/services/github-runner/service.nix index 5d73633b..21d908e0 100644 --- a/modules/services/github-runner/service.nix +++ b/modules/services/github-runner/service.nix @@ -49,7 +49,7 @@ in echo >&2 "setting up GitHub Runner '${cfg.name}'..." ( - umask -S u=rwx,g=rx,o= + umask -S u=rwx,g=rx,o= > /dev/null ${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkStateDir cfg)} ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)} From 82ed8010ffb17b637cbbd916398ee3a4027cfb10 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Fri, 22 Nov 2024 12:58:40 +1100 Subject: [PATCH 139/139] ci: extend timeout and remove `tmate` --- .github/workflows/test.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c531aa5f..25211d30 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,6 @@ env: jobs: test-stable: runs-on: macos-13 - timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Install nix corresponding to latest stable channel @@ -22,7 +21,6 @@ jobs: test-unstable: runs-on: macos-13 - timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Install nix from current unstable channel @@ -33,7 +31,6 @@ jobs: install-against-stable: runs-on: macos-13 - timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Install nix corresponding to latest stable channel @@ -82,12 +79,6 @@ jobs: nix run .#darwin-uninstaller.tests.uninstaller \ --extra-experimental-features "nix-command flakes" \ --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} - - name: Debugging tmate session - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 15 - with: - limit-access-to-actor: true install-against-unstable: runs-on: macos-13 @@ -140,16 +131,9 @@ jobs: nix run .#darwin-uninstaller.tests.uninstaller \ --extra-experimental-features "nix-command flakes" \ --override-input nixpkgs nixpkgs/nixpkgs-unstable - - name: Debugging tmate session - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 15 - with: - limit-access-to-actor: true install-flake-against-stable: runs-on: macos-13 - timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Install nix version corresponding to latest stable channel