1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2024-12-14 11:57:34 +00:00
nix-darwin/modules/system/checks.nix

240 lines
8 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.system.checks;
darwinChanges = ''
darwinChanges=/dev/null
if test -e /run/current-system/darwin-changes; then
darwinChanges=/run/current-system/darwin-changes
fi
darwinChanges=$(diff --changed-group-format='%>' --unchanged-group-format= /run/current-system/darwin-changes $systemConfig/darwin-changes 2> /dev/null) || true
if test -n "$darwinChanges"; then
echo >&2
echo "CHANGELOG" >&2
echo >&2
echo "$darwinChanges" >&2
echo >&2
fi
'';
runLink = ''
if ! test -e /run; then
echo "error: Directory /run does not exist, aborting activation" >&2
echo "Create a symlink to /var/run with:" >&2
if test -e /etc/synthetic.conf; then
echo >&2
echo "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" >&2
echo "$ /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B # For Catalina" >&2
echo "$ /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later" >&2
echo >&2
echo "The current contents of /etc/synthetic.conf is:" >&2
echo >&2
sed 's/^/ /' /etc/synthetic.conf >&2
echo >&2
else
echo >&2
echo "$ sudo ln -s private/var/run /run" >&2
echo >&2
fi
exit 2
fi
'';
oldBuildUsers = ''
if dscl . -list /Users | grep -q '^nixbld'; then
echo "warning: Detected old style nixbld users" >&2
echo "These can cause migration problems when upgrading to certain macOS versions" >&2
echo "Running the installer again will remove and recreate the users in a way that avoids these problems" >&2
echo >&2
echo "$ darwin-install" >&2
echo >&2
echo "or enable to automatically manage the users" >&2
echo >&2
echo " nix.configureBuildUsers = true;" >&2
echo >&2
fi
'';
buildUsers = ''
buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true
if [ -z $buildUser ]; then
echo "error: Using the nix-daemon requires build users, aborting activation" >&2
echo "Create the build users or disable the daemon:" >&2
echo "$ darwin-install" >&2
echo >&2
echo "or set (this requires some manual intervention to restore permissions)" >&2
echo >&2
echo " services.nix-daemon.enable = false;" >&2
echo >&2
exit 2
fi
'';
singleUser = ''
if grep -q 'build-users-group =' /etc/nix/nix.conf; then
echo "error: The daemon is not enabled but this is a multi-user install, aborting activation" >&2
echo "Enable the nix-daemon service:" >&2
echo >&2
echo " services.nix-daemon.enable = true;" >&2
echo >&2
echo "or set" >&2
echo >&2
echo " nix.useDaemon = true;" >&2
echo >&2
exit 2
fi
'';
nixChannels = ''
channelsLink=$(readlink "$HOME/.nix-defexpr/channels") || true
case "$channelsLink" in
*"$USER"*)
;;
"")
;;
*)
echo "error: The ~/.nix-defexpr/channels symlink does not point your users channels, aborting activation" >&2
echo "Running nix-channel will regenerate it" >&2
echo >&2
echo " rm ~/.nix-defexpr/channels" >&2
echo " nix-channel --update" >&2
echo >&2
exit 2
;;
esac
'';
nixInstaller = ''
if grep -q 'etc/profile.d/nix-daemon.sh' /etc/profile; then
echo "error: Found nix-daemon.sh reference in /etc/profile, aborting activation" >&2
echo "This will override options like nix.nixPath because it runs later," >&2
echo "remove this snippet from /etc/profile:" >&2
echo >&2
echo " # Nix" >&2
echo " if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then" >&2
echo " . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'" >&2
echo " fi" >&2
echo " # End Nix" >&2
echo >&2
exit 2
fi
'';
nixPath = ''
nixPath=${concatStringsSep ":" config.nix.nixPath}:$HOME/.nix-defexpr/channels
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:-~/.nixpkgs/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
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 "$ nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin" >&2
echo "$ 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
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 "$ nix-channel --add http://nixos.org/channels/nixpkgs-unstable nixpkgs" >&2
echo "$ 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
'';
nixStore = ''
if test -w /nix/var/nix/db -a ! -O /nix/store; then
echo >&2 "error: the store is not owned by this user, but /nix/var/nix/db is writable"
echo >&2 "If you are using the daemon:"
echo >&2
echo >&2 " sudo chown -R root:wheel /nix/var/nix/db"
echo >&2
echo >&2 "Otherwise:"
echo >&2
echo >&2 " sudo chown -R $USER:staff /nix/store"
echo >&2
exit 2
fi
'';
nixGarbageCollector = ''
if test -O /nix/store; then
echo "error: A single-user install can't run gc as root, aborting activation" >&2
echo "Configure the garbage collector to run as the current user:" >&2
echo >&2
echo " nix.gc.user = \"$USER\";" >&2
echo >&2
exit 2
fi
'';
in
{
options = {
system.checks.verifyNixPath = mkOption {
type = types.bool;
default = true;
description = "Whether to run the NIX_PATH validation checks.";
};
system.checks.text = mkOption {
internal = true;
type = types.lines;
default = "";
};
};
config = {
system.checks.text = mkMerge [
darwinChanges
runLink
oldBuildUsers
(mkIf config.nix.useDaemon buildUsers)
(mkIf (!config.nix.useDaemon) singleUser)
nixStore
(mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector)
nixChannels
nixInstaller
(mkIf cfg.verifyNixPath nixPath)
];
system.activationScripts.checks.text = ''
${cfg.text}
if test ''${checkActivation:-0} -eq 1; then
echo "ok" >&2
exit 0
fi
'';
};
}