1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-03-31 04:04:45 +00:00
This commit is contained in:
Emily 2025-03-24 23:41:35 -06:00 committed by GitHub
commit 1fc8e765e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
68 changed files with 724 additions and 339 deletions

View file

@ -39,8 +39,8 @@ jobs:
nix_path: nixpkgs=channel:${{ env.NIXPKGS_BRANCH }}
- name: Install channels
run: |
nix-channel --add https://nixos.org/channels/${{ env.NIXPKGS_BRANCH }} nixpkgs
nix-channel --update
sudo nix-channel --add https://nixos.org/channels/${{ env.NIXPKGS_BRANCH }} nixpkgs
sudo nix-channel --update
- name: Install nix-darwin
run: |
sudo mkdir -p /etc/nix-darwin
@ -61,7 +61,7 @@ jobs:
/" \
/etc/nix-darwin/configuration.nix
nix run .#darwin-rebuild -- switch \
sudo nix run .#darwin-rebuild -- switch \
-I darwin=. \
-I darwin-config=/etc/nix-darwin/configuration.nix
- name: Switch to new configuration
@ -72,17 +72,17 @@ jobs:
"s/pkgs.vim/pkgs.hello/" \
/etc/nix-darwin/configuration.nix
darwin-rebuild switch
sudo darwin-rebuild switch
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 \
sudo nix run .#darwin-uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
nix run .#darwin-uninstaller.tests.uninstaller \
sudo nix run .#darwin-uninstaller.tests.uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
@ -112,7 +112,7 @@ jobs:
's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \
flake.nix
popd
nix run .#darwin-rebuild -- switch \
sudo nix run .#darwin-rebuild -- switch \
--override-input nix-darwin . \
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
- name: Switch to new configuration
@ -123,12 +123,12 @@ jobs:
"s/pkgs.vim/pkgs.hello/" \
/etc/nix-darwin/flake.nix
darwin-rebuild switch \
sudo darwin-rebuild switch \
--override-input nix-darwin . \
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
hello
- name: Test uninstallation of nix-darwin
run: |
nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
sudo nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
sudo nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}

View file

@ -1,3 +1,30 @@
2025-01-30
- Previously, some nix-darwin options applied to the user running
`darwin-rebuild`. As part of a longterm migration to make
nix-darwin focus on systemwide activation and support firstclass
multiuser setups, all system activation now runs as `root`, and
these options instead apply to the `system.primaryUser` user.
You will get an evaluation error if you are using any options to
which this applies.
To continue using these options, set `system.primaryUser` to the name
of the user you have been using to run `darwin-rebuild`. In the long
run, this setting will be deprecated and removed after all the
functionality it is relevant for has been adjusted to allow
specifying the relevant user separately, moved under the
`users.users.*` namespace, or migrated to Home Manager.
Accordingly, `darwin-rebuild` must now be run as root, the
`system.activationScripts.{extraUserActivation,preUserActivation,
postUserActivation}` settings have been removed, and all activation
scripts are now executed as `root` be careful if you override any
of them.
If you run into any unexpected issues with the migration, please
open an issue at <https://github.com/LnL7/nix-darwin/issues/new>
and include as much information as possible.
2025-01-29
- There is now a `nix.enable` toggle to disable management of the Nix
installation. Nix installation management has been made more

View file

@ -98,9 +98,9 @@ Unlike NixOS, `nix-darwin` does not have an installer, you can just run `darwin-
```bash
# To use Nixpkgs unstable:
nix run nix-darwin/master#darwin-rebuild -- switch
sudo nix run nix-darwin/master#darwin-rebuild -- switch
# To use Nixpkgs 24.11:
nix run nix-darwin/nix-darwin-24.11#darwin-rebuild -- switch
sudo nix run nix-darwin/nix-darwin-24.11#darwin-rebuild -- switch
```
### Step 3. Using `nix-darwin`
@ -108,7 +108,7 @@ nix run nix-darwin/nix-darwin-24.11#darwin-rebuild -- switch
After installing, you can run `darwin-rebuild` to apply changes to your system:
```bash
darwin-rebuild switch
sudo darwin-rebuild switch
```
#### Using flake inputs
@ -155,7 +155,7 @@ To install `nix-darwin`, you can just run `darwin-rebuild switch` to install nix
```bash
nix-build '<darwin>' -A darwin-rebuild
./result/bin/darwin-rebuild switch -I darwin-config=/etc/nix-darwin/configuration.nix
sudo ./result/bin/darwin-rebuild switch -I darwin-config=/etc/nix-darwin/configuration.nix
```
### Step 4. Using `nix-darwin`
@ -163,7 +163,7 @@ nix-build '<darwin>' -A darwin-rebuild
After installing, you can run `darwin-rebuild` to apply changes to your system:
```bash
darwin-rebuild switch
sudo darwin-rebuild switch
```
### Step 5. Updating `nix-darwin`
@ -186,13 +186,13 @@ The documentation is also available as manpages by running `man 5 configuration.
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
sudo 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
sudo darwin-uninstaller
```
## Tests
@ -218,7 +218,7 @@ flag can also be used to override darwin-config or nixpkgs, for more
information on the `-I` flag look at the nix-build [manpage](https://nixos.org/manual/nix/stable/command-ref/nix-build.html).
```bash
darwin-rebuild switch -I darwin=.
sudo darwin-rebuild switch -I darwin=.
```
If you're adding a module, please add yourself to `meta.maintainers`, for example

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ options, config, lib, pkgs, ... }:
with lib;
@ -75,7 +75,7 @@ in
else if config.system.stateVersion >= 6 then
"/etc/nix-darwin/configuration.nix"
else
"$HOME/.nixpkgs/darwin-configuration.nix";
"${config.system.primaryUserHome}/.nixpkgs/darwin-configuration.nix";
defaultText = literalExpression ''
if config.nixpkgs.flake.setNixPath then
# Dont set this for flakebased systems.
@ -83,7 +83,7 @@ in
else if config.system.stateVersion >= 6 then
"/etc/nix-darwin/configuration.nix"
else
"$HOME/.nixpkgs/darwin-configuration.nix"
"''${config.system.primaryUserHome}/.nixpkgs/darwin-configuration.nix"
'';
description = ''
The path of the darwin configuration.nix used to configure the system,
@ -175,6 +175,16 @@ in
config = {
# This is horrible, sorry.
system.requiresPrimaryUser = mkIf (
config.nix.enable
&& !config.nixpkgs.flake.setNixPath
&& config.system.stateVersion < 6
&& options.environment.darwinConfig.highestPrio == (mkOptionDefault {}).priority
) [
"environment.darwinConfig"
];
environment.systemPath = mkMerge [
[ (makeBinPath cfg.profiles) ]
(mkOrder 1200 [ "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" ])

View file

@ -1,6 +1,8 @@
{ config, lib, inputs, pkgs, ... }:
{
system.primaryUser = "lnl";
system.defaults.NSGlobalDomain.AppleKeyboardUIMode = 3;
system.defaults.NSGlobalDomain.ApplePressAndHoldEnabled = false;
system.defaults.NSGlobalDomain.InitialKeyRepeat = 10;

View file

@ -559,6 +559,17 @@ in
This module also provides a few options for modifying how Homebrew commands behave when
you manually invoke them, under [](#opt-homebrew.global)'';
user = mkOption {
type = types.str;
default = config.system.primaryUser;
defaultText = literalExpression "config.system.primaryUser";
description = ''
The user that owns the Homebrew installation. In most cases
this should be the normal user account that you installed
Homebrew as.
'';
};
brewPrefix = mkOption {
type = types.str;
default = if pkgs.stdenv.hostPlatform.isAarch64 then "/opt/homebrew/bin" else "/usr/local/bin";
@ -764,6 +775,10 @@ in
(mkIf (options.homebrew.autoUpdate.isDefined || options.homebrew.cleanup.isDefined) "The `homebrew' module no longer upgrades outdated formulae and apps by default during `nix-darwin' system activation. To enable upgrading, set `homebrew.onActivation.upgrade = true'.")
];
system.requiresPrimaryUser = mkIf (cfg.enable && options.homebrew.user.highestPrio == (mkOptionDefault {}).priority) [
"homebrew.enable"
];
homebrew.brews =
optional (cfg.whalebrews != [ ]) "whalebrew";
@ -786,6 +801,9 @@ in
echo >&2 "Homebrew bundle..."
if [ -f "${cfg.brewPrefix}/brew" ]; then
PATH="${cfg.brewPrefix}:${lib.makeBinPath [ pkgs.mas ]}:$PATH" \
sudo \
--user=${escapeShellArg cfg.user} \
--set-home \
${cfg.onActivation.brewBundleCmd}
else
echo -e "\e[1;31merror: Homebrew is not installed, skipping...\e[0m" >&2

View file

@ -170,7 +170,16 @@ in
launchd.user.agents = mkOption {
default = {};
type = types.attrsOf (types.submodule serviceOptions);
type = types.attrsOf (types.submodule [
serviceOptions
({ name, ... }: {
options.managedBy = lib.mkOption {
type = lib.types.str;
internal = true;
default = lib.showOption [ "launchd" "user" "agents" name ];
};
})
]);
description = ''
Definition of per-user launchd agents.
@ -187,6 +196,18 @@ in
config = {
system.requiresPrimaryUser =
lib.map (
name:
lib.showOption [
"launchd"
"user"
"envVariables"
name
]
) (attrNames cfg.user.envVariables)
++ lib.map ({ managedBy, ... }: managedBy) (attrValues cfg.user.agents);
environment.launchAgents = mapAttrs' toEnvironmentText cfg.agents;
environment.launchDaemons = mapAttrs' toEnvironmentText cfg.daemons;

View file

@ -10,6 +10,7 @@
./security/sudo.nix
./system
./system/base.nix
./system/primary-user.nix
./system/checks.nix
./system/activation-scripts.nix
./system/applications.nix

View file

@ -825,11 +825,18 @@ in
# Not in NixOS module
nix.nixPath = mkIf (config.system.stateVersion < 2) (mkDefault [
"darwin=$HOME/.nix-defexpr/darwin"
"darwin-config=$HOME/.nixpkgs/darwin-configuration.nix"
"darwin=${config.system.primaryUserHome}/.nix-defexpr/darwin"
"darwin-config=${config.system.primaryUserHome}/.nixpkgs/darwin-configuration.nix"
"/nix/var/nix/profiles/per-user/root/channels"
]);
system.requiresPrimaryUser = mkIf (
config.system.stateVersion < 2
&& options.nix.nixPath.highestPrio == (mkDefault {}).priotity
) [
"nix.nixPath"
];
# Set up the environment variables for running Nix.
environment.variables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
@ -869,7 +876,7 @@ in
#
# TODO: Maybe this could use a more general file placement mechanism
# to express that we want it deleted and know only one hash?
system.activationScripts.etcChecks.text = mkAfter ''
system.activationScripts.checks.text = mkAfter ''
nixCustomConfKnownSha256Hashes=(
# v0.33.0
6787fade1cf934f82db554e78e1fc788705c2c5257fddf9b59bdd963ca6fec63

View file

@ -5,6 +5,7 @@ let
inherit (config.system) profile;
inherit (config.environment) systemPath;
nixPath = lib.optionalString config.nix.enable (lib.concatStringsSep ":" config.nix.nixPath);
nixPackage = if config.nix.enable then config.nix.package else null;
};
darwin-uninstaller = pkgs.callPackage ../../pkgs/darwin-uninstaller { };

View file

@ -1,5 +1,35 @@
{ config, lib, pkgs, ... }:
let
activationPath =
lib.makeBinPath (
[
pkgs.gnugrep
pkgs.coreutils
] ++ lib.optionals config.nix.enable [ config.nix.package ]
)
+ lib.optionalString (!config.nix.enable) ''
$(
# If `nix.enable` is off, there might be an unmanaged Nix
# installation (say in `/nix/var/nix/profiles/default`) that
# activation scripts (such as Home Manager) want to find on the
# `$PATH`. Search for it directly to avoid polluting the
# activation script environment with everything on the
# `environment.systemPath`.
if nixEnvPath=$(
PATH="${config.environment.systemPath}" command -v nix-env
); then
printf ':'
${lib.getExe' pkgs.coreutils "dirname"} -- "$(
${lib.getExe' pkgs.coreutils "readlink"} \
--canonicalize-missing \
-- "$nixEnvPath"
)"
fi
)''
+ ":/usr/bin:/bin:/usr/sbin:/sbin";
in
{
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.")
@ -10,7 +40,17 @@
script = ''
set -e
set -o pipefail
export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin"
PATH="${activationPath}"
export PATH
export USER=root
export LOGNAME=root
export HOME=~root
export MAIL=/var/mail/root
export SHELL=$BASH
export LANG=C
export LC_CTYPE=UTF-8
systemConfig=$(cat ${config.system.profile}/systemConfig)
@ -25,7 +65,7 @@
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
fi
${config.system.activationScripts.etcChecks.text}
${config.system.activationScripts.checks.text}
${config.system.activationScripts.etc.text}
${config.system.activationScripts.keyboard.text}
'';

View file

@ -253,6 +253,7 @@ in
KeepAlive = true;
RunAtLoad = true;
};
managedBy = "services.aerospace.enable";
};
}
);

View file

@ -126,6 +126,7 @@ in
serviceConfig.RunAtLoad = true;
serviceConfig.KeepAlive = true;
serviceConfig.ProcessType = "Interactive";
managedBy = "services.chunkwm.enable";
};
};

View file

@ -49,6 +49,7 @@ in {
RunAtLoad = true;
KeepAlive = true;
};
managedBy = "services.emacs.enable";
};
};

View file

@ -64,6 +64,7 @@ in
StandardErrorPath = cfg.logFile;
EnvironmentVariables = {} // (optionalAttrs (cfg.ipfsPath != null) { IPFS_PATH = cfg.ipfsPath; });
};
managedBy = "services.ipfs.enable";
};
};
}

View file

@ -162,6 +162,7 @@ in {
++ (optionalArg "order" cfg.order);
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = true;
managedBy = "services.jankyborders.enable";
};
};
}

View file

@ -84,6 +84,7 @@ in
"${parentAppDir}/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager" "activate"
];
serviceConfig.RunAtLoad = true;
managedBy = "services.karabiner-elements.enable";
};
# We need this to run every reboot as /run gets nuked so we can't put this
@ -105,6 +106,7 @@ in
];
serviceConfig.Label = "org.pqrs.karabiner.karabiner_session_monitor";
serviceConfig.KeepAlive = true;
managedBy = "services.karabiner-elements.enable";
};
environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_grabber.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_grabber.plist";

View file

@ -57,6 +57,8 @@ in
SockType = "dgram";
SockFamily = "IPv4";
};
managedBy = "services.khd.enable";
};
};

View file

@ -47,6 +47,7 @@ in
SockType = "dgram";
SockFamily = "IPv4";
};
managedBy = "services.kwm.enable";
};
};

View file

@ -38,6 +38,7 @@ in
];
environment.systemPackages = [ pkgs.lorri ];
launchd.user.agents.lorri = {
command = with pkgs; "${lorri}/bin/lorri daemon";
path = with pkgs; [ config.nix.package git gnutar gzip ];
@ -49,6 +50,7 @@ in
StandardErrorPath = cfg.logFile;
EnvironmentVariables = { NIX_PATH = "nixpkgs=" + toString pkgs.path; };
};
managedBy = "services.lorri.enable";
};
};
}

View file

@ -56,6 +56,7 @@ in {
serviceConfig.StartInterval = cfg.startInterval;
serviceConfig.StandardErrorPath = "/var/log/offlineimap.log";
serviceConfig.StandardOutPath = "/var/log/offlineimap.log";
managedBy = "services.offlineimap.enable";
};
};
}

View file

@ -41,6 +41,7 @@ in
serviceConfig.Program = "${cfg.package}/bin/mopidy";
serviceConfig.RunAtLoad = true;
serviceConfig.KeepAlive = true;
managedBy = "services.mopidy.enable";
};
})
(mkIf cfg.mediakeys.enable {
@ -48,6 +49,7 @@ in
serviceConfig.Program = "${cfg.package}/bin/mpdkeys";
serviceConfig.RunAtLoad = true;
serviceConfig.KeepAlive = true;
managedBy = "services.mopidy.mediakeys.enable";
};
})
];

View file

@ -363,6 +363,7 @@ in
serviceConfig.EnvironmentVariables = {
PGDATA = cfg.dataDir;
};
managedBy = "services.postgresql.enable";
};
};

View file

@ -61,6 +61,7 @@ in
${cfg.package}/bin/privoxy /etc/privoxy-config
'';
serviceConfig.KeepAlive = true;
managedBy = "services.privoxy.enable";
};
};
}

View file

@ -67,6 +67,7 @@ in
launchd.user.agents.redis = {
command = "${cfg.package}/bin/redis-server /etc/redis.conf";
serviceConfig.KeepAlive = true;
managedBy = "services.redis.enable";
};
environment.etc."redis.conf".text = ''

View file

@ -54,6 +54,7 @@ in
++ optionals (cfg.config != "") [ "--config" "${configFile}" ];
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = true;
managedBy = "services.sketchybar.enable";
};
};
}

View file

@ -40,6 +40,8 @@ in
++ optionals (cfg.skhdConfig != "") [ "-c" "/etc/skhdrc" ];
serviceConfig.KeepAlive = true;
serviceConfig.ProcessType = "Interactive";
managedBy = "services.skhd.enable";
};
};

View file

@ -69,6 +69,8 @@ in
serviceConfig.EnvironmentVariables = {
PATH = "${cfg.package}/bin:${config.environment.systemPath}";
};
managedBy = "services.spacebar.enable";
};
};
}

View file

@ -58,6 +58,7 @@ in
RunAtLoad = true;
ThrottleInterval = 30;
};
managedBy = "services.spotifyd.enable";
};
};
}

View file

@ -66,6 +66,7 @@ in
command = "${cfg.package}/bin/synapse --config ${configFile}";
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = true;
managedBy = "services.synapse-bt.enable";
};
};

View file

@ -130,6 +130,7 @@ in
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = cfg.client.autoStart;
serviceConfig.ProcessType = "Interactive";
managedBy = "services.synergy.client.enable";
};
})
@ -145,6 +146,7 @@ in
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = cfg.server.autoStart;
serviceConfig.ProcessType = "Interactive";
managedBy = "services.synergy.server.enable";
};
})
];

View file

@ -42,6 +42,7 @@ in {
KeepAlive = true;
RunAtLoad = true;
};
managedBy = "services.trezord.enable";
};
};
}

View file

@ -85,6 +85,8 @@ in
serviceConfig.EnvironmentVariables = {
PATH = "${cfg.package}/bin:${config.environment.systemPath}";
};
managedBy = "services.yabai.enable";
};
})

View file

@ -14,10 +14,12 @@ let
};
activationPath =
lib.makeBinPath [
pkgs.gnugrep
pkgs.coreutils
]
lib.makeBinPath (
[
pkgs.gnugrep
pkgs.coreutils
] ++ lib.optionals config.nix.enable [ config.nix.package ]
)
+ lib.optionalString (!config.nix.enable) ''
$(
# If `nix.enable` is off, there might be an unmanaged Nix
@ -37,8 +39,7 @@ let
)"
fi
)''
+ ":@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin";
+ ":/usr/bin:/bin:/usr/sbin:/sbin";
in
{
@ -62,24 +63,58 @@ in
config = {
assertions =
map
(userActivationOption: {
assertion = !config.system.activationScripts ? ${userActivationOption};
message = ''
The `system.activationScripts.${userActivationOption}` option has
been removed, as all activation now takes place as `root`. Please
restructure your custom activation scripts appropriately,
potentially using `sudo` if you need to run commands as a user.
'';
})
[
"extraUserActivation"
"preUserActivation"
"postUserActivation"
];
system.activationScripts.script.text = ''
#! ${stdenv.shell}
#!/usr/bin/env -i ${stdenv.shell}
# shellcheck shell=bash
# shellcheck disable=SC2096
set -e
set -o pipefail
PATH="${activationPath}"
export PATH
export USER=root
export LOGNAME=root
export HOME=~root
export MAIL=/var/mail/root
export SHELL=$BASH
export LANG=C
export LC_CTYPE=UTF-8
systemConfig=@out@
# Ensure a consistent umask.
umask 0022
cd /
if [[ $(id -u) -ne 0 ]]; then
printf >&2 '\e[1;31merror: `activate` must be run as root\e[0m\n'
exit 2
fi
${cfg.activationScripts.preActivation.text}
# We run `etcChecks` again just in case someone runs `activate`
# directly without `activate-user`.
${cfg.activationScripts.etcChecks.text}
${cfg.activationScripts.checks.text}
${cfg.activationScripts.createRun.text}
${cfg.activationScripts.extraActivation.text}
${cfg.activationScripts.groups.text}
${cfg.activationScripts.users.text}
@ -88,7 +123,9 @@ in
${cfg.activationScripts.patches.text}
${cfg.activationScripts.etc.text}
${cfg.activationScripts.defaults.text}
${cfg.activationScripts.userDefaults.text}
${cfg.activationScripts.launchd.text}
${cfg.activationScripts.userLaunchd.text}
${cfg.activationScripts.nix-daemon.text}
${cfg.activationScripts.time.text}
${cfg.activationScripts.networking.text}
@ -96,6 +133,7 @@ in
${cfg.activationScripts.keyboard.text}
${cfg.activationScripts.fonts.text}
${cfg.activationScripts.nvram.text}
${cfg.activationScripts.homebrew.text}
${cfg.activationScripts.postActivation.text}
@ -111,48 +149,11 @@ in
fi
'';
# FIXME: activationScripts.checks should be system level
system.activationScripts.userScript.text = ''
#! ${stdenv.shell}
set -e
set -o pipefail
PATH="${activationPath}"
export PATH
systemConfig=@out@
_status=0
trap "_status=1" ERR
# Ensure a consistent umask.
umask 0022
${cfg.activationScripts.preUserActivation.text}
# This should be running at the system level, but as user activation runs first
# we run it here with sudo
${cfg.activationScripts.createRun.text}
${cfg.activationScripts.checks.text}
${cfg.activationScripts.etcChecks.text}
${cfg.activationScripts.extraUserActivation.text}
${cfg.activationScripts.userDefaults.text}
${cfg.activationScripts.userLaunchd.text}
${cfg.activationScripts.homebrew.text}
${cfg.activationScripts.postUserActivation.text}
exit $_status
'';
# Extra activation scripts, that can be customized by users
# don't use this unless you know what you are doing.
system.activationScripts.extraActivation.text = mkDefault "";
system.activationScripts.preActivation.text = mkDefault "";
system.activationScripts.postActivation.text = mkDefault "";
system.activationScripts.extraUserActivation.text = mkDefault "";
system.activationScripts.preUserActivation.text = mkDefault "";
system.activationScripts.postUserActivation.text = mkDefault "";
};
}

View file

@ -30,12 +30,15 @@ in
[ -L "$1" ] && [ "''${link#*-}" = 'system-applications/Applications' ]
}
# Clean up for links created at the old location in HOME
if ourLink ~/Applications; then
rm ~/Applications
elif ourLink ~/Applications/'Nix Apps'; then
rm ~/Applications/'Nix Apps'
fi
${lib.optionalString (config.system.primaryUser != null) ''
# Clean up for links created at the old location in HOME
# TODO: Remove this in 25.11.
if ourLink ~${config.system.primaryUser}/Applications; then
rm ~${config.system.primaryUser}/Applications
elif ourLink ~${config.system.primaryUser}/Applications/'Nix Apps'; then
rm ~${config.system.primaryUser}/Applications/'Nix Apps'
fi
''}
if [ ! -e '/Applications/Nix Apps' ] \
|| ourLink '/Applications/Nix Apps'; then

View file

@ -4,26 +4,26 @@
system.activationScripts.createRun.text = ''
if [[ $(stat -c '%a' /etc/synthetic.conf) != "644" ]]; then
echo "fixing permissions on /etc/synthetic.conf..."
sudo chmod 644 /etc/synthetic.conf
chmod 644 /etc/synthetic.conf
fi
if [[ $(grep -c '^run\b' /etc/synthetic.conf) -gt 1 ]]; then
echo "found duplicate run entries in /etc/synthetic.conf, removing..."
sudo sed -i "" -e '/^run\tprivate\/var\/run$/d' /etc/synthetic.conf
sed -i "" -e '/^run\tprivate\/var\/run$/d' /etc/synthetic.conf
fi
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
printf 'run\tprivate/var/run\n' | tee -a /etc/synthetic.conf >/dev/null
fi
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true
/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || 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\n"
printf >&2 "$ printf 'run\tprivate/var/run\n' | tee -a /etc/synthetic.conf\n"
printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t\n'
printf >&2 '\n'
printf >&2 'The current contents of /etc/synthetic.conf is:\n'

View file

@ -31,6 +31,18 @@ let
fi
'';
primaryUser = ''
primaryUser=${escapeShellArg config.system.primaryUser}
if ! id -- "$primaryUser" >/dev/null 2>&1; then
printf >&2 '\e[1;31merror: primary user `%s` does not exist, aborting activation\e[0m\n' \
"$primaryUser"
printf >&2 'Please ensure that `system.primaryUser` is set to the name of an\n'
printf >&2 'existing user. Usually this should be the user you have been using to\n'
printf >&2 'run `darwin-rebuild`.\n'
exit 2
fi
'';
determinate = ''
if [[ -e /usr/local/bin/determinate-nixd ]]; then
printf >&2 '\e[1;31merror: Determinate detected, aborting activation\e[0m\n'
@ -150,49 +162,70 @@ let
'';
nixPath = ''
nixPath=${concatMapStringsSep ":" escapeDoubleQuote config.nix.nixPath}:$HOME/.nix-defexpr/channels
findPathEntry() {
NIX_PATH=${concatMapStringsSep ":" escapeDoubleQuote config.nix.nixPath} \
nix-instantiate --find-file "$@" >/dev/null
}
darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true
if ! test -e "$darwinConfig"; then
echo "error: Changed <darwin-config> but target does not exist, aborting activation" >&2
echo "Create ''${darwinConfig:-/etc/nix-darwin/configuration.nix} or set environment.darwinConfig:" >&2
echo >&2
echo " environment.darwinConfig = \"$(nix-instantiate --find-file darwin-config 2> /dev/null || echo '***')\";" >&2
echo >&2
echo "And rebuild using (only required once)" >&2
echo "$ darwin-rebuild switch -I \"darwin-config=$(nix-instantiate --find-file darwin-config 2> /dev/null || echo '***')\"" >&2
echo >&2
echo >&2
exit 2
if ! findPathEntry darwin-config; then
printf >&2 '\e[1;31merror: cant find `<darwin-config>`, aborting activation\e[0m\n'
printf >&2 'Make sure that %s exists,\n' \
${escapeDoubleQuote (
if config.environment.darwinConfig == null then
"the \\`<darwin-config>\\` entry in `nix.nixPath`"
else
"\\`${config.environment.darwinConfig}\\`"
)}
printf >&2 'or else set `environment.darwinConfig` to the correct path to your\n'
printf >&2 '`configuration.nix` file.\n'
printf >&2 '\n'
printf >&2 'The setting should not reference `$HOME`, as `root` now needs to be\n'
printf >&2 'able to find your configuration. If you previously used `$HOME` in\n'
printf >&2 'your `environment.darwinConfig` path, please replace it with the\n'
printf >&2 'full path to your home directory.\n'
exit 2
fi
darwinPath=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin) || true
if ! test -e "$darwinPath"; then
echo "error: Changed <darwin> but target does not exist, aborting activation" >&2
echo "Add the darwin repo as a channel or set nix.nixPath:" >&2
echo "$ sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin" >&2
echo "$ sudo nix-channel --update" >&2
echo >&2
echo "or set" >&2
echo >&2
echo " nix.nixPath = [ \"darwin=$(nix-instantiate --find-file darwin 2> /dev/null || echo '***')\" ];" >&2
echo >&2
exit 2
fi
checkChannel() {
if findPathEntry "$1"; then
return
fi
nixpkgsPath=$(NIX_PATH=$nixPath nix-instantiate --find-file nixpkgs) || true
if ! test -e "$nixpkgsPath"; then
echo "error: Changed <nixpkgs> but target does not exist, aborting activation" >&2
echo "Add a nixpkgs channel or set nix.nixPath:" >&2
echo "$ sudo nix-channel --add http://nixos.org/channels/nixpkgs-unstable nixpkgs" >&2
echo "$ sudo nix-channel --update" >&2
echo >&2
echo "or set" >&2
echo >&2
echo " nix.nixPath = [ \"nixpkgs=$(nix-instantiate --find-file nixpkgs 2> /dev/null || echo '***')\" ];" >&2
echo >&2
exit 2
fi
printf >&2 '\e[1;31merror: cant find `<%s>`, aborting activation\e[0m\n' \
"$1"
printf >&2 'The most likely reason for this is that the channel is owned\n'
printf >&2 'by your user. This no longer works now that nix-darwin has moved over\n'
printf >&2 'to `root`based activation.\n'
printf >&2 '\n'
printf >&2 'You can check your current channels with:\n'
printf >&2 '\n'
printf >&2 ' $ sudo nix-channel --list\n'
printf >&2 ' nixpkgs https://nixos.org/channels/NIXPKGS-BRANCH\n'
printf >&2 ' darwin https://github.com/LnL7/nix-darwin/archive/NIX-DARWIN-BRANCH.tar.gz\n'
printf >&2 ' \n'
printf >&2 ' $ nix-channel --list\n'
printf >&2 ' \n'
printf >&2 '\n'
printf >&2 'You should see `darwin` and `nixpkgs` in `sudo nix-channel --list`.\n'
printf >&2 'If `darwin` or `nixpkgs` are present in `nix-channel --list` (without\n'
printf >&2 '`sudo`), you should delete them with `nix-channel --remove NAME`.\n'
printf >&2 '\n'
printf >&2 'You can then fix your channels like this:\n'
printf >&2 '\n'
printf >&2 ' $ sudo nix-channel --add https://nixos.org/channels/NIXPKGS-BRANCH nixpkgs\n'
printf >&2 ' $ sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/NIX-DARWIN-BRANCH.tar.gz darwin\n'
printf >&2 ' $ sudo nix-channel --update\n'
printf >&2 '\n'
printf >&2 'After that, activating your system again should work correctly. If it\n'
printf >&2 'doesnt, please open an issue at\n'
printf >&2 '<https://github.com/LnL7/nix-darwin/issues/new> and include as much\n'
printf >&2 'information as possible.\n'
exit 2
}
checkChannel nixpkgs
checkChannel darwin
'';
# TODO: Remove this a couple years down the line when we can assume
@ -275,6 +308,7 @@ in
system.checks.text = mkMerge [
(mkIf cfg.verifyMacOSVersion macOSVersion)
(mkIf (config.system.primaryUser != null) primaryUser)
(mkIf config.nix.enable determinate)
(mkIf cfg.verifyBuildUsers preSequoiaBuildUsers)
(mkIf cfg.verifyBuildUsers buildGroupID)

View file

@ -95,7 +95,51 @@ in
nativeBuildInputs = [ pkgs.shellcheck ];
activationScript = cfg.activationScripts.script.text;
activationUserScript = cfg.activationScripts.userScript.text;
# This is for compatibility with older `darwin-rebuild`s and
# thirdparty deployment tools.
#
# TODO: Remove this in 25.11.
activationUserScript = ''
#! ${pkgs.stdenv.shell}
# nix-darwin: deprecated
# Hack to handle upgrades.
if
[[ -e /run/current-system/activate-user ]] \
&& ! grep -q '^# nix-darwin: deprecated$' \
/run/current-system/activate-user
then
exit
fi
printf >&2 '\e[1;31mwarning: `activate-user` is deprecated and will be removed in 25.11\e[0m\n'
printf >&2 'This is usually due to the use of a nonstandard activation/deployment\n'
printf >&2 'tool. If you maintain one of these tools, our advice is:\n'
printf >&2 '\n'
printf >&2 ' You can identify a postuseractivation configuration by the absence\n'
printf >&2 ' of `activate-user` or the second line of the script being\n'
printf >&2 ' `# nix-darwin: deprecated`.\n'
printf >&2 '\n'
printf >&2 ' We recommend running `$systemConfig/sw/bin/darwin-rebuild activate`\n'
printf >&2 ' to activate built configurations; for a preuseractivation\n'
printf >&2 ' configuration this should be run as a normal user, and for a\n'
printf >&2 ' postuseractivation configuration it should be run as `root`.\n'
printf >&2 '\n'
printf >&2 ' If you cant or dont want to use `darwin-rebuild activate`, then you\n'
printf >&2 ' should skip running `activate-user` for postuseractivation\n'
printf >&2 ' configurations and continue running `activate` as `root`.\n'
printf >&2 '\n'
printf >&2 ' In 25.11, `darwin-rebuild` will stop running `activate-user` and this\n'
printf >&2 ' transition script will be deleted; you should be able to safely\n'
printf >&2 ' remove all related logic by then.\n'
printf >&2 '\n'
printf >&2 'Otherwise, you should report this to the deployment tool developers. If\n'
printf >&2 'you dont use a thirdparty deployment tool, please open a bug report\n'
printf >&2 'at <https://github.com/LnL7/nix-darwin/issues/new> and include as much\n'
printf >&2 'detail about your setup as possible.\n'
'';
inherit (cfg) darwinLabel;
darwinVersionJson = (pkgs.formats.json {}).generate "darwin-version.json" (
@ -131,7 +175,6 @@ in
unset activationScript
echo "$activationUserScript" > $out/activate-user
substituteInPlace $out/activate-user --subst-var out
chmod u+x $out/activate-user
unset activationUserScript

View file

@ -1,4 +1,4 @@
{ config, lib, ... }:
{ options, config, lib, ... }:
with lib;
@ -9,6 +9,10 @@ let
"defaults write ${domain} '${key}' $'${strings.escape [ "'" ] (generators.toPlist { } value)}'";
defaultsToList = domain: attrs: mapAttrsToList (writeDefault domain) (filterAttrs (n: v: v != null) attrs);
userDefaultsToList = domain: attrs: map
(cmd: "sudo --user=${escapeShellArg config.system.primaryUser} -- ${cmd}")
(defaultsToList domain attrs);
# Filter out options to not pass through
# dock has alias options that we need to ignore
dockFiltered = (builtins.removeAttrs cfg.dock ["expose-group-by-app"]);
@ -18,28 +22,28 @@ let
loginwindow = defaultsToList "/Library/Preferences/com.apple.loginwindow" cfg.loginwindow;
smb = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.smb.server" cfg.smb;
SoftwareUpdate = defaultsToList "/Library/Preferences/com.apple.SoftwareUpdate" cfg.SoftwareUpdate;
CustomSystemPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomSystemPreferences);
# userDefaults
GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences";
LaunchServices = defaultsToList "com.apple.LaunchServices" cfg.LaunchServices;
NSGlobalDomain = defaultsToList "-g" cfg.NSGlobalDomain;
menuExtraClock = defaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock;
dock = defaultsToList "com.apple.dock" dockFiltered;
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;
screensaver = defaultsToList "com.apple.screensaver" cfg.screensaver;
spaces = defaultsToList "com.apple.spaces" cfg.spaces;
trackpad = defaultsToList "com.apple.AppleMultitouchTrackpad" cfg.trackpad;
trackpadBluetooth = defaultsToList "com.apple.driver.AppleBluetoothMultitouch.trackpad" cfg.trackpad;
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);
GlobalPreferences = userDefaultsToList ".GlobalPreferences" cfg.".GlobalPreferences";
LaunchServices = userDefaultsToList "com.apple.LaunchServices" cfg.LaunchServices;
NSGlobalDomain = userDefaultsToList "-g" cfg.NSGlobalDomain;
menuExtraClock = userDefaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock;
dock = userDefaultsToList "com.apple.dock" dockFiltered;
finder = userDefaultsToList "com.apple.finder" cfg.finder;
hitoolbox = userDefaultsToList "com.apple.HIToolbox" cfg.hitoolbox;
magicmouse = userDefaultsToList "com.apple.AppleMultitouchMouse" cfg.magicmouse;
magicmouseBluetooth = userDefaultsToList "com.apple.driver.AppleMultitouchMouse.mouse" cfg.magicmouse;
screencapture = userDefaultsToList "com.apple.screencapture" cfg.screencapture;
screensaver = userDefaultsToList "com.apple.screensaver" cfg.screensaver;
spaces = userDefaultsToList "com.apple.spaces" cfg.spaces;
trackpad = userDefaultsToList "com.apple.AppleMultitouchTrackpad" cfg.trackpad;
trackpadBluetooth = userDefaultsToList "com.apple.driver.AppleBluetoothMultitouch.trackpad" cfg.trackpad;
universalaccess = userDefaultsToList "com.apple.universalaccess" cfg.universalaccess;
ActivityMonitor = userDefaultsToList "com.apple.ActivityMonitor" cfg.ActivityMonitor;
WindowManager = userDefaultsToList "com.apple.WindowManager" cfg.WindowManager;
controlcenter = userDefaultsToList "~${config.system.primaryUser}/Library/Preferences/ByHost/com.apple.controlcenter" cfg.controlcenter;
CustomUserPreferences = flatten (mapAttrsToList (name: value: userDefaultsToList name value) cfg.CustomUserPreferences);
mkIfLists = list: mkIf (any (attrs: attrs != [ ]) list);
@ -57,6 +61,30 @@ in
else types.float.check x;
};
system.requiresPrimaryUser = concatMap
(scope: mapAttrsToList
(name: value: mkIf (value != null) (showOption [ "system" "defaults" scope name ]))
(if scope == "dock" then dockFiltered else cfg.${scope}))
[
"CustomUserPreferences"
".GlobalPreferences"
"LaunchServices"
"NSGlobalDomain"
"menuExtraClock"
"dock"
"finder"
"hitoolbox"
"magicmouse"
"screencapture"
"screensaver"
"spaces"
"trackpad"
"universalaccess"
"ActivityMonitor"
"WindowManager"
"controlcenter"
];
system.activationScripts.defaults.text = mkIfLists [
alf
loginwindow
@ -122,11 +150,8 @@ in
${concatStringsSep "\n" controlcenter}
${optionalString (length dock > 0) ''
# Only restart Dock if current user is logged in
if pgrep -xu $UID Dock >/dev/null; then
echo >&2 "restarting Dock..."
killall Dock || true
fi
echo >&2 "restarting Dock..."
killall -qu ${escapeShellArg config.system.primaryUser} Dock || true
''}
'';

View file

@ -39,7 +39,7 @@ in
'') etc}
'';
system.activationScripts.etcChecks.text = ''
system.activationScripts.checks.text = mkAfter ''
declare -A etcSha256Hashes=(
${concatMapStringsSep "\n "
(attr:

View file

@ -11,8 +11,8 @@ let
mkTextDerivation = pkgs.writeText;
};
launchdVariables = mapAttrsToList (name: value: ''
launchctl setenv ${name} '${value}'
launchdVariables = prefix: mapAttrsToList (name: value: ''
${prefix} launchctl setenv ${name} '${value}'
'');
launchdActivation = basedir: target: ''
@ -31,19 +31,21 @@ let
fi
'';
userLaunchdActivation = target: ''
if ! diff ${cfg.build.launchd}/user/Library/LaunchAgents/${target} ~/Library/LaunchAgents/${target} &> /dev/null; then
if test -f ~/Library/LaunchAgents/${target}; then
userLaunchdActivation = target: let
user = lib.escapeShellArg config.system.primaryUser;
in ''
if ! diff ${cfg.build.launchd}/user/Library/LaunchAgents/${target} ~${user}/Library/LaunchAgents/${target} &> /dev/null; then
if test -f ~${user}/Library/LaunchAgents/${target}; then
echo "reloading user service $(basename ${target} .plist)" >&2
launchctl unload ~/Library/LaunchAgents/${target} || true
sudo --user=${user} -- launchctl unload ~${user}/Library/LaunchAgents/${target} || true
else
echo "creating user service $(basename ${target} .plist)" >&2
fi
if test -L ~/Library/LaunchAgents/${target}; then
rm ~/Library/LaunchAgents/${target}
if test -L ~${user}/Library/LaunchAgents/${target}; then
sudo --user=${user} -- rm ~${user}/Library/LaunchAgents/${target}
fi
cp -f '${cfg.build.launchd}/user/Library/LaunchAgents/${target}' ~/Library/LaunchAgents/${target}
launchctl load -w ~/Library/LaunchAgents/${target}
sudo --user=${user} -- cp -f '${cfg.build.launchd}/user/Library/LaunchAgents/${target}' ~${user}/Library/LaunchAgents/${target}
sudo --user=${user} -- launchctl load -w ~${user}/Library/LaunchAgents/${target}
fi
'';
@ -100,7 +102,7 @@ in
# Set up launchd services in /Library/LaunchAgents and /Library/LaunchDaemons
echo "setting up launchd services..." >&2
${concatStringsSep "\n" (launchdVariables config.launchd.envVariables)}
${concatStringsSep "\n" (launchdVariables "" config.launchd.envVariables)}
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchAgents" attr.target) launchAgents}
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchDaemons" attr.target) launchDaemons}
@ -132,14 +134,16 @@ in
done
'';
system.activationScripts.userLaunchd.text = ''
system.activationScripts.userLaunchd.text = let
user = lib.escapeShellArg config.system.primaryUser;
in mkIf (config.launchd.user.envVariables != { } || userLaunchAgents != [ ]) ''
# Set up user launchd services in ~/Library/LaunchAgents
echo "setting up user launchd services..."
${concatStringsSep "\n" (launchdVariables config.launchd.user.envVariables)}
${concatStringsSep "\n" (launchdVariables "sudo --user=${user} --" config.launchd.user.envVariables)}
${optionalString (builtins.length userLaunchAgents > 0) ''
mkdir -p ~/Library/LaunchAgents
sudo --user=${user} -- mkdir -p ~${user}/Library/LaunchAgents
''}
${concatMapStringsSep "\n" (attr: userLaunchdActivation attr.target) userLaunchAgents}
@ -149,9 +153,9 @@ in
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"
sudo --user=${user} -- launchctl unload ~${user}/Library/LaunchAgents/"$f" || true
if [[ -e ~${user}/Library/LaunchAgents/"$f" ]]; then
sudo --user=${user} -- rm -f ~${user}/Library/LaunchAgents/"$f"
fi
fi
done

View file

@ -0,0 +1,67 @@
{
lib,
options,
config,
...
}:
{
options = {
system.primaryUser = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The user used for options that previously applied to the user
running `darwin-rebuild`.
This is a transition mechanism as nix-darwin reorganizes its
options and will eventually be unnecessary and removed.
'';
};
system.primaryUserHome = lib.mkOption {
internal = true;
type = lib.types.str;
default =
config.users.users.${config.system.primaryUser}.home or "/Users/${config.system.primaryUser}";
};
system.requiresPrimaryUser = lib.mkOption {
internal = true;
type = lib.types.listOf lib.types.str;
default = [ ];
};
};
config = {
assertions = [
{
assertion = config.system.primaryUser == null -> config.system.requiresPrimaryUser == [ ];
message = ''
Previously, some nix-darwin options applied to the user running
`darwin-rebuild`. As part of a longterm migration to make
nix-darwin focus on systemwide activation and support firstclass
multiuser setups, all system activation now runs as `root`, and
these options instead apply to the `system.primaryUser` user.
You currently have the following primaryuserrequiring options set:
${lib.concatMapStringsSep "\n" (name: "* `${name}`") (
lib.sort (name1: name2: name1 < name2) config.system.requiresPrimaryUser
)}
To continue using these options, set `system.primaryUser` to the name
of the user you have been using to run `darwin-rebuild`. In the long
run, this setting will be deprecated and removed after all the
functionality it is relevant for has been adjusted to allow
specifying the relevant user separately, moved under the
`users.users.*` namespace, or migrated to Home Manager.
If you run into any unexpected issues with the migration, please
open an issue at <https://github.com/LnL7/nix-darwin/issues/new>
and include as much information as possible.
'';
}
];
};
}

View file

@ -105,6 +105,16 @@ in
assertion = !builtins.elem "root" deletedUsers;
message = "Remove `root` from `users.knownUsers` if you no longer want nix-darwin to manage it.";
}
{
assertion =
config.system.primaryUser != null
-> !builtins.elem config.system.primaryUser deletedUsers;
message = ''
Refusing to delete the primary user. Remove
`${config.system.primaryUser}` from `users.knownUsers` if
you no longer want nix-darwin to manage it.
'';
}
] ++ flatten (flip mapAttrsToList cfg.users (name: user:
map (shell: {
assertion = let
@ -140,13 +150,12 @@ 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 = mkIf (builtins.length (createdUsers ++ deletedUsers) > 0) (mkAfter ''
ensurePerms() {
homeDirectory=$(dscl . -read /Users/nobody NFSHomeDirectory)
homeDirectory=''${homeDirectory#NFSHomeDirectory: }
if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then
if ! dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then
if [[ "$(launchctl managername)" != Aqua ]]; then
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"
@ -167,7 +176,7 @@ in
# 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
if ! 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'
printf >&2 'please accept the dialog that pops up.\n'
@ -218,12 +227,6 @@ in
u=$(id -u ${name} 2> /dev/null) || true
if [ -n "$u" ]; then
if [ "$u" -gt 501 ]; then
# 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
fi
ensurePerms ${name} delete
fi
fi

View file

@ -1,4 +1,4 @@
{ lib, pkgs, ... }:
{ lib, config, pkgs, ... }:
with lib;
@ -15,13 +15,17 @@ with lib;
# Restore any unmanaged `nix-daemon`.
nix.enable = false;
system.activationScripts.postUserActivation.text = mkAfter ''
nix-channel --remove darwin || true
'';
system.activationScripts.postActivation.text = mkAfter ''
nix-channel --remove darwin || true
${lib.optionalString (config.system.primaryUser != null) ''
sudo \
--user=${lib.escapeShellArg config.system.primaryUser} \
--set-home \
-- nix-channel --remove darwin \
|| true
''}
if [[ -L /Applications/Nix\ Apps ]]; then
rm /Applications/Nix\ Apps
fi

View file

@ -53,16 +53,16 @@ in writeShellApplication {
${uninstallSystem.system}/sw/bin/darwin-rebuild activate
if [[ -L /run/current-system ]]; then
sudo rm /run/current-system
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 -t &>/dev/null || true
sed -i -E '/^run[[:space:]]/d' /etc/synthetic.conf
/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
rm /run
fi
fi

View file

@ -2,6 +2,12 @@
set -e
set -o pipefail
if [[ $(id -u) -eq 0 ]]; then
# On macOS, `sudo(8)` preserves `$HOME` by default, which causes Nix
# to output warnings.
HOME=~root
fi
export PATH=@path@
export NIX_PATH=${NIX_PATH:-@nixPath@}
@ -22,12 +28,6 @@ showSyntax() {
exit 1
}
sudo() {
# 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 --preserve-env=SSH_CONNECTION env "$@"
}
# Parse the command line.
origArgs=("$@")
extraMetadataFlags=()
@ -142,6 +142,11 @@ done
if [ -z "$action" ]; then showSyntax; fi
if [[ $action =~ ^switch|activate|rollback|check$ && $(id -u) -ne 0 ]]; then
printf >&2 '%s: system activation must now be run as root\n' "$0"
exit 1
fi
flakeFlags=(--extra-experimental-features 'nix-command flakes')
# Use /etc/nix-darwin/flake.nix if it exists. It can be a symlink to the
@ -193,11 +198,7 @@ if [ "$action" = switch ] || [ "$action" = build ] || [ "$action" = check ] || [
fi
if [ "$action" = list ] || [ "$action" = rollback ]; then
if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then
sudo nix-env -p "$profile" "${extraProfileFlags[@]}"
else
nix-env -p "$profile" "${extraProfileFlags[@]}"
fi
nix-env -p "$profile" "${extraProfileFlags[@]}"
fi
if [ "$action" = rollback ]; then
@ -210,22 +211,37 @@ fi
if [ -z "$systemConfig" ]; then exit 0; fi
if [ "$action" = switch ]; then
if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then
sudo nix-env -p "$profile" --set "$systemConfig"
# TODO: Remove this backwardscompatibility hack in 25.11.
if
[[ -x $systemConfig/activate-user ]] \
&& ! grep -q '^# nix-darwin: deprecated$' "$systemConfig/activate-user"
then
hasActivateUser=1
else
hasActivateUser=
fi
runActivateUser() {
if [[ -n $SUDO_USER ]]; then
sudo --user="$SUDO_USER" --set-home -- "$systemConfig/activate-user"
else
nix-env -p "$profile" --set "$systemConfig"
printf >&2 \
'%s: $SUDO_USER not set, cant run legacy `activate-user` script\n' \
"$0"
exit 1
fi
}
if [ "$action" = switch ]; then
nix-env -p "$profile" --set "$systemConfig"
fi
if [ "$action" = switch ] || [ "$action" = activate ] || [ "$action" = rollback ]; then
"$systemConfig/activate-user"
if [ "$USER" != root ]; then
sudo "$systemConfig/activate"
else
"$systemConfig/activate"
if [[ -n $hasActivateUser ]]; then
runActivateUser
fi
"$systemConfig/activate"
fi
if [ "$action" = changelog ]; then
@ -234,5 +250,9 @@ fi
if [ "$action" = check ]; then
export checkActivation=1
"$systemConfig/activate-user"
if [[ -n $hasActivateUser ]]; then
runActivateUser
else
"$systemConfig/activate"
fi
fi

View file

@ -21,6 +21,7 @@
"/usr/sbin"
"/sbin"
]
, nixPackage ? null
, # This should be kept in sync with the default `nix.nixPath`.
nixPath ? lib.concatStringsSep ":" [
"darwin-config=/etc/nix-darwin/configuration.nix"
@ -29,7 +30,7 @@
}:
let
extraPath = lib.makeBinPath [ coreutils jq git ];
extraPath = lib.makeBinPath [ coreutils jq git nixPackage ];
writeProgram = name: env: src:
substituteAll ({

View file

@ -1,10 +1,6 @@
{ config, pkgs, ... }:
{
system.activationScripts.preUserActivation.text = "echo hook preUserActivation";
system.activationScripts.extraUserActivation.text = "echo hook extraUserActivation";
system.activationScripts.postUserActivation.text = "echo hook postUserActivation";
system.activationScripts.preActivation.text = "echo hook preActivation";
system.activationScripts.extraActivation.text = "echo hook extraActivation";
system.activationScripts.postActivation.text = "echo hook postActivation";
@ -14,11 +10,6 @@
awk '/echo hook / {i++ ; print i " => " $0}' "$2" | grep "$1"
}
echo checking activation hooks in /activate-user >&2
countHooks "1 => echo hook preUserActivation" ${config.out}/activate-user
countHooks "2 => echo hook extraUserActivation" ${config.out}/activate-user
countHooks "3 => echo hook postUserActivation" ${config.out}/activate-user
echo checking activation hooks in /activate >&2
countHooks "1 => echo hook preActivation" ${config.out}/activate
countHooks "2 => echo hook extraActivation" ${config.out}/activate

View file

@ -1,251 +1,251 @@
defaults write -g 'AppleEnableMouseSwipeNavigateWithScrolls' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleEnableMouseSwipeNavigateWithScrolls' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'AppleEnableSwipeNavigateWithScrolls' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleEnableSwipeNavigateWithScrolls' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'AppleFontSmoothing' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleFontSmoothing' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>1</integer>
</plist>'
defaults write -g 'AppleICUForce24HourTime' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleICUForce24HourTime' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'AppleKeyboardUIMode' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleKeyboardUIMode' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>3</integer>
</plist>'
defaults write -g 'ApplePressAndHoldEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'ApplePressAndHoldEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'AppleScrollerPagingBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleScrollerPagingBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'AppleShowAllFiles' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleShowAllFiles' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'AppleShowScrollBars' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleShowScrollBars' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>Always</string>
</plist>'
defaults write -g 'AppleSpacesSwitchOnActivate' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleSpacesSwitchOnActivate' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'AppleWindowTabbingMode' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'AppleWindowTabbingMode' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>always</string>
</plist>'
defaults write -g 'InitialKeyRepeat' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'InitialKeyRepeat' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>10</integer>
</plist>'
defaults write -g 'KeyRepeat' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'KeyRepeat' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>1</integer>
</plist>'
defaults write -g 'NSAutomaticCapitalizationEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticCapitalizationEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticDashSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticDashSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticInlinePredictionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticInlinePredictionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticPeriodSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticPeriodSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticQuoteSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticQuoteSubstitutionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticSpellingCorrectionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticSpellingCorrectionEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSAutomaticWindowAnimationsEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSAutomaticWindowAnimationsEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSDisableAutomaticTermination' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSDisableAutomaticTermination' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'NSDocumentSaveNewDocumentsToCloud' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSDocumentSaveNewDocumentsToCloud' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSNavPanelExpandedStateForSaveMode' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSNavPanelExpandedStateForSaveMode' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'NSNavPanelExpandedStateForSaveMode2' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSNavPanelExpandedStateForSaveMode2' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'NSScrollAnimationEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSScrollAnimationEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'NSTableViewDefaultSizeMode' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSTableViewDefaultSizeMode' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>2</integer>
</plist>'
defaults write -g 'NSTextShowsControlCharacters' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSTextShowsControlCharacters' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'NSUseAnimatedFocusRing' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSUseAnimatedFocusRing' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write -g 'NSWindowResizeTime' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSWindowResizeTime' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<real>0.010000</real>
</plist>'
defaults write -g 'NSWindowShouldDragOnGesture' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'NSWindowShouldDragOnGesture' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'PMPrintingExpandedStateForPrint' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'PMPrintingExpandedStateForPrint' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'PMPrintingExpandedStateForPrint2' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'PMPrintingExpandedStateForPrint2' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'com.apple.keyboard.fnState' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.keyboard.fnState' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'com.apple.mouse.tapBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.mouse.tapBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>1</integer>
</plist>'
defaults write -g 'com.apple.springing.delay' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.springing.delay' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<real>0.000000</real>
</plist>'
defaults write -g 'com.apple.springing.enabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.springing.enabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'com.apple.swipescrolldirection' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.swipescrolldirection' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'com.apple.trackpad.enableSecondaryClick' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.trackpad.enableSecondaryClick' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write -g 'com.apple.trackpad.trackpadCornerClickBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write -g 'com.apple.trackpad.trackpadCornerClickBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>1</integer>
</plist>'
defaults write .GlobalPreferences 'com.apple.sound.beep.sound' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write .GlobalPreferences 'com.apple.sound.beep.sound' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>/System/Library/Sounds/Funk.aiff</string>
</plist>'
defaults write com.apple.menuextra.clock 'FlashDateSeparators' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.menuextra.clock 'FlashDateSeparators' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.menuextra.clock 'Show24Hour' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.menuextra.clock 'Show24Hour' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.menuextra.clock 'ShowDate' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.menuextra.clock 'ShowDate' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>2</integer>
</plist>'
defaults write com.apple.menuextra.clock 'ShowDayOfWeek' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.menuextra.clock 'ShowDayOfWeek' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.dock 'appswitcher-all-displays' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'appswitcher-all-displays' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.dock 'autohide-delay' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'autohide-delay' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<real>0.240000</real>
</plist>'
defaults write com.apple.dock 'expose-group-apps' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'expose-group-apps' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.dock 'orientation' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'orientation' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>left</string>
</plist>'
defaults write com.apple.dock 'persistent-apps' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'persistent-apps' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
@ -319,7 +319,7 @@ defaults write com.apple.dock 'persistent-apps' $'<?xml version="1.0" encoding="
</dict>
</array>
</plist>'
defaults write com.apple.dock 'persistent-others' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'persistent-others' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
@ -353,134 +353,134 @@ defaults write com.apple.dock 'persistent-others' $'<?xml version="1.0" encoding
</dict>
</array>
</plist>'
defaults write com.apple.dock 'scroll-to-open' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.dock 'scroll-to-open' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder 'AppleShowAllFiles' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'AppleShowAllFiles' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder 'CreateDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'CreateDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'FXDefaultSearchScope' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'FXDefaultSearchScope' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>SCcf</string>
</plist>'
defaults write com.apple.finder 'FXEnableExtensionChangeWarning' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'FXEnableExtensionChangeWarning' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'FXPreferredViewStyle' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'FXPreferredViewStyle' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>Flwv</string>
</plist>'
defaults write com.apple.finder 'FXRemoveOldTrashItems' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'FXRemoveOldTrashItems' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'NewWindowTarget' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'NewWindowTarget' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>PfLo</string>
</plist>'
defaults write com.apple.finder 'NewWindowTargetPath' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'NewWindowTargetPath' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>file:///Library/Apple</string>
</plist>'
defaults write com.apple.finder 'QuitMenuItem' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'QuitMenuItem' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder 'ShowExternalHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowExternalHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'ShowHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'ShowMountedServersOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowMountedServersOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'ShowPathbar' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowPathbar' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder 'ShowRemovableMediaOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowRemovableMediaOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.finder 'ShowStatusBar' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder 'ShowStatusBar' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder '_FXShowPosixPathInTitle' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder '_FXShowPosixPathInTitle' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder '_FXSortFoldersFirst' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder '_FXSortFoldersFirst' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.finder '_FXSortFoldersFirstOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.finder '_FXSortFoldersFirstOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.HIToolbox 'AppleFnUsageType' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.HIToolbox 'AppleFnUsageType' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>2</integer>
</plist>'
defaults write com.apple.screencapture 'include-date' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.screencapture 'include-date' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.screencapture 'location' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.screencapture 'location' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>/tmp</string>
</plist>'
defaults write com.apple.screencapture 'target' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.screencapture 'target' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>file</string>
</plist>'
defaults write com.apple.screensaver 'askForPassword' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.screensaver 'askForPassword' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.screensaver 'askForPasswordDelay' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.screensaver 'askForPasswordDelay' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>5</integer>
@ -488,62 +488,62 @@ defaults write com.apple.screensaver 'askForPasswordDelay' $'<?xml version="1.0"
defaults write com.apple.universalaccess 'closeViewScrollWheelToggle' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.universalaccess 'closeViewScrollWheelToggle' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.universalaccess 'closeViewZoomFollowsFocus' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.universalaccess 'closeViewZoomFollowsFocus' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.universalaccess 'mouseDriverCursorSize' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.universalaccess 'mouseDriverCursorSize' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<real>1.500000</real>
</plist>'
defaults write com.apple.universalaccess 'reduceMotion' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.universalaccess 'reduceMotion' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.universalaccess 'reduceTransparency' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.universalaccess 'reduceTransparency' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.ActivityMonitor 'IconType' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.ActivityMonitor 'IconType' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>3</integer>
</plist>'
defaults write com.apple.ActivityMonitor 'OpenMainWindow' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.ActivityMonitor 'OpenMainWindow' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.ActivityMonitor 'ShowCategory' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.ActivityMonitor 'ShowCategory' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>103</integer>
</plist>'
defaults write com.apple.ActivityMonitor 'SortColumn' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.ActivityMonitor 'SortColumn' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>CPUUsage</string>
</plist>'
defaults write com.apple.ActivityMonitor 'SortDirection' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.ActivityMonitor 'SortDirection' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>0</integer>
</plist>'
defaults write NSGlobalDomain 'TISRomanSwitchState' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write NSGlobalDomain 'TISRomanSwitchState' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>1</integer>
</plist>'
defaults write com.apple.Safari 'NSUserKeyEquivalents' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.Safari 'NSUserKeyEquivalents' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
@ -551,102 +551,102 @@ defaults write com.apple.Safari 'NSUserKeyEquivalents' $'<?xml version="1.0" enc
<string>@^q</string>
</dict>
</plist>'
defaults write com.apple.Safari 'com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.Safari 'com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'AppWindowGroupingBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'AppWindowGroupingBehavior' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'AutoHide' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'AutoHide' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'EnableStandardClickToShowDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'EnableStandardClickToShowDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'EnableTiledWindowMargins' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'EnableTiledWindowMargins' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'EnableTilingByEdgeDrag' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'EnableTilingByEdgeDrag' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'EnableTilingOptionAccelerator' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'EnableTilingOptionAccelerator' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'EnableTopTilingByEdgeDrag' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'EnableTopTilingByEdgeDrag' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'GloballyEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'GloballyEnabled' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'HideDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'HideDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'StageManagerHideWidgets' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'StageManagerHideWidgets' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write com.apple.WindowManager 'StandardHideDesktopIcons' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'StandardHideDesktopIcons' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'StandardHideWidgets' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write com.apple.WindowManager 'StandardHideWidgets' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'AirDrop' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'AirDrop' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>18</integer>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'BatteryShowPercentage' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'BatteryShowPercentage' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<true/>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Bluetooth' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'Bluetooth' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>18</integer>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Display' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'Display' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>24</integer>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'FocusModes' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'FocusModes' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>24</integer>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'NowPlaying' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'NowPlaying' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>18</integer>
</plist>'
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Sound' $'<?xml version="1.0" encoding="UTF-8"?>
sudo --user=test-defaults-user -- defaults write ~test-defaults-user/Library/Preferences/ByHost/com.apple.controlcenter 'Sound' $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<integer>24</integer>

View file

@ -15,6 +15,8 @@ in
{
homebrew.enable = true;
homebrew.user = "test-homebrew-user";
# Examples taken from https://github.com/Homebrew/homebrew-bundle
homebrew.taps = [
"homebrew/cask"

View file

@ -1,6 +1,8 @@
{ config, pkgs, ... }:
{
system.primaryUser = "test-launchd-user";
launchd.daemons.foo.command = "foo";
launchd.agents.bar.command = "bar";
launchd.user.agents.baz.command = "baz";
@ -9,9 +11,9 @@
echo "checking launchd load in /activate" >&2
grep "launchctl load .* '/Library/LaunchDaemons/org.nixos.foo.plist" ${config.out}/activate
grep "launchctl load .* '/Library/LaunchAgents/org.nixos.bar.plist" ${config.out}/activate
echo "checking launchd load in /activate-user" >&2
grep "launchctl load .* ~/Library/LaunchAgents/org.nixos.baz.plist" ${config.out}/activate-user
echo "checking LaunchAgents creation /activate-user" >&2
grep "mkdir -p ~/Library/LaunchAgents" ${config.out}/activate-user
echo "checking launchd user agent load in /activate" >&2
grep "sudo --user=test-launchd-user -- launchctl load .* ~test-launchd-user/Library/LaunchAgents/org.nixos.baz.plist" ${config.out}/activate
echo "checking LaunchAgents creation /activate" >&2
grep "sudo --user=test-launchd-user -- mkdir -p ~test-launchd-user/Library/LaunchAgents" ${config.out}/activate
'';
}

View file

@ -9,6 +9,5 @@
grep "scutil --set ComputerName 'EVEs MacBook Pro'" ${config.out}/activate
grep "scutil --set LocalHostName ${lib.escapeShellArg "EVE"}" ${config.out}/activate
grep "scutil --set HostName ${lib.escapeShellArg "EVE"}" ${config.out}/activate
echo checking defaults write in ${config.out}/activate-user >&2
'';
}

View file

@ -10,6 +10,5 @@
grep "scutil --set ComputerName '"\""Quotey McQuote's Macbook Pro"\""'" ${config.out}/activate
grep "scutil --set LocalHostName '"\""Quotey-McQuote's-Macbook-Pro"\""'" ${config.out}/activate
grep "scutil --set HostName "'"\""Quotey-McQuote's-Macbook-Pro"\""'" ${config.out}/activate
echo checking defaults write in ${config.out}/activate-user >&2
'';
}

View file

@ -12,5 +12,9 @@
printf >&2 'checking for latebound Nix lookup in /activate\n'
grep nixEnvPath= ${config.out}/activate
printf >&2 'checking for latebound Nix lookup in activation service\n'
script=$(cat ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist | awk -F'[< ]' '$6 ~ "^/nix/store/.*" {print $6}')
grep nixEnvPath= "$script"
'';
}

View file

@ -5,6 +5,8 @@ let
in
{
system.primaryUser = "test-aerospace-user";
services.aerospace.enable = true;
services.aerospace.package = aerospace;
services.aerospace.settings = {

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-jankyborders-user";
services.jankyborders.enable = true;
services.jankyborders.package = jankyborders;
services.jankyborders.width = 5.0;

View file

@ -16,6 +16,8 @@ let
expectedNixPath = "${"nixpkgs=" + toString pkgs.path}";
in
{
system.primaryUser = "test-lorri-user";
services.lorri.enable = true;
test = ''
PATH=${

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-offlineimap-user";
services.offlineimap.enable = true;
services.offlineimap.package = offlineimap;
services.offlineimap.runQuick = true;

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-privoxy-user";
services.privoxy.enable = true;
services.privoxy.package = privoxy;
services.privoxy.config = "forward / .";

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-redis-user";
services.redis.enable = true;
services.redis.package = redis;
services.redis.extraConfig = ''

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-skhd-user";
services.skhd.enable = true;
services.skhd.package = skhd;
services.skhd.skhdConfig = "alt + shift - r : chunkc quit";

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-spacebar-user";
services.spacebar.enable = true;
services.spacebar.package = spacebar;
services.spacebar.config = { background_color = "0xff202020"; };

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-spotify-user";
services.spotifyd.enable = true;
services.spotifyd.package = spotifyd;

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-synapse-bt-user";
services.synapse-bt.enable = true;
services.synapse-bt.package = synapse-bt;

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-synergy-user";
services.synergy.package = synergy;
services.synergy.client.enable = true;

View file

@ -7,6 +7,8 @@ let
in
{
system.primaryUser = "test-yabai-user";
services.yabai.enable = true;
services.yabai.package = yabai;
services.yabai.config = { focus_follows_mouse = "autoraise"; };

View file

@ -1,6 +1,8 @@
{ config, pkgs, lib, ... }:
{
system.primaryUser = "test-defaults-user";
imports = [
{
system.defaults.CustomUserPreferences = {
@ -137,18 +139,18 @@
system.defaults.controlcenter.NowPlaying = true;
test = lib.strings.concatMapStringsSep "\n"
(x: ''
echo >&2 "checking defaults write in /${x}"
echo >&2 "checking ${x} defaults write in /activate"
${pkgs.python3}/bin/python3 <<EOL
import sys
from pathlib import Path
fixture = '${./fixtures/system-defaults-write}/${x}.txt'
out = '${config.out}/${x}'
out = '${config.out}/activate'
if Path(fixture).read_text() not in Path(out).read_text():
print("Did not find content from %s in %s" % (fixture, out), file=sys.stderr)
sys.exit(1)
EOL
'') [
"activate"
"activate-user"
"system"
"user"
];
}