activation-scripts: get rid of user activation

🎉

Closes: #96
This commit is contained in:
Emily 2025-01-11 15:44:41 +00:00
parent 0abf012666
commit 2ca294741f
7 changed files with 104 additions and 63 deletions

View file

@ -62,6 +62,23 @@ 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}
set -e
@ -77,9 +94,9 @@ in
${cfg.activationScripts.preActivation.text}
# We run `etcChecks` again just in case someone runs `activate`
# directly without `activate-user`.
${cfg.activationScripts.etcChecks.text}
${cfg.activationScripts.createRun.text}
${cfg.activationScripts.checks.text}
${cfg.activationScripts.extraActivation.text}
${cfg.activationScripts.groups.text}
${cfg.activationScripts.users.text}
@ -114,45 +131,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.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

@ -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

@ -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