2016-11-05 21:47:09 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
2017-01-02 07:21:27 +00:00
|
|
|
text = import ../lib/write-text.nix {
|
2016-11-05 21:47:09 +00:00
|
|
|
inherit lib;
|
|
|
|
mkTextDerivation = name: text: pkgs.writeText "etc-${name}" text;
|
|
|
|
};
|
|
|
|
|
|
|
|
etc = filter (f: f.enable) (attrValues config.environment.etc);
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
|
|
|
|
environment.etc = mkOption {
|
2020-09-02 04:20:00 +00:00
|
|
|
type = types.attrsOf (types.submodule text);
|
2022-09-25 18:12:08 +00:00
|
|
|
default = { };
|
2024-04-14 21:02:32 +00:00
|
|
|
description = ''
|
2023-06-22 11:21:32 +00:00
|
|
|
Set of files that have to be linked in {file}`/etc`.
|
2016-11-05 21:47:09 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
2022-09-25 18:12:08 +00:00
|
|
|
system.build.etc = pkgs.runCommand "etc"
|
2018-01-21 12:46:30 +00:00
|
|
|
{ preferLocalBuild = true; }
|
|
|
|
''
|
|
|
|
mkdir -p $out/etc
|
|
|
|
cd $out/etc
|
2023-07-16 16:02:10 +00:00
|
|
|
${concatMapStringsSep "\n" (attr: ''
|
|
|
|
mkdir -p "$(dirname ${escapeShellArg attr.target})"
|
|
|
|
ln -s ${escapeShellArgs [ attr.source attr.target ]}
|
|
|
|
'') etc}
|
2018-01-21 12:46:30 +00:00
|
|
|
'';
|
2016-11-05 21:47:09 +00:00
|
|
|
|
2023-07-12 07:35:11 +00:00
|
|
|
system.activationScripts.etcChecks.text = ''
|
|
|
|
declare -A etcSha256Hashes=(
|
|
|
|
${concatMapStringsSep "\n "
|
|
|
|
(attr:
|
|
|
|
"[${escapeShellArg attr.target}]=" +
|
|
|
|
escapeShellArg (concatStringsSep " " attr.knownSha256Hashes))
|
|
|
|
etc}
|
|
|
|
)
|
|
|
|
|
2023-11-09 11:44:10 +00:00
|
|
|
declare -a etcProblems=()
|
2023-07-12 07:35:11 +00:00
|
|
|
|
|
|
|
while IFS= read -r -d "" configFile; do
|
|
|
|
subPath=''${configFile#"$systemConfig"/etc/}
|
|
|
|
etcStaticFile=/etc/static/$subPath
|
|
|
|
etcFile=/etc/$subPath
|
|
|
|
|
|
|
|
# We need to check files that exist and aren't already links to
|
|
|
|
# $etcStaticFile for known hashes.
|
|
|
|
if [[
|
|
|
|
-e $etcFile
|
|
|
|
&& $(readlink "$etcFile") != "$etcStaticFile"
|
|
|
|
]]; then
|
|
|
|
# Only check hashes of paths that resolve to regular files;
|
|
|
|
# everything else (e.g. directories) we complain about
|
|
|
|
# unconditionally.
|
|
|
|
if [[ -f $(readlink -f "$etcFile") ]]; then
|
|
|
|
etcFileSha256Output=$(shasum -a 256 "$etcFile")
|
|
|
|
etcFileSha256Hash=''${etcFileSha256Output%% *}
|
|
|
|
for knownSha256Hash in ''${etcSha256Hashes[$subPath]}; do
|
|
|
|
if [[ $etcFileSha256Hash == "$knownSha256Hash" ]]; then
|
|
|
|
# Hash matches, OK to overwrite; go to the next file.
|
|
|
|
continue 2
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
etcProblems+=("$etcFile")
|
|
|
|
fi
|
|
|
|
done < <(find -H "$systemConfig/etc" -type l -print0)
|
|
|
|
|
|
|
|
if (( ''${#etcProblems[@]} )); then
|
|
|
|
printf >&2 '\x1B[1;31merror: Unexpected files in /etc, aborting '
|
|
|
|
printf >&2 'activation\x1B[0m\n'
|
|
|
|
printf >&2 'The following files have unrecognized content and would be '
|
|
|
|
printf >&2 'overwritten:\n\n'
|
|
|
|
printf >&2 ' %s\n' "''${etcProblems[@]}"
|
|
|
|
printf >&2 '\nPlease check there is nothing critical in these files, '
|
|
|
|
printf >&2 'rename them by adding .before-nix-darwin to the end, and '
|
|
|
|
printf >&2 'then try again.\n'
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
'';
|
|
|
|
|
2016-11-05 21:47:09 +00:00
|
|
|
system.activationScripts.etc.text = ''
|
|
|
|
# Set up the statically computed bits of /etc.
|
2023-07-12 07:35:11 +00:00
|
|
|
printf >&2 'setting up /etc...\n'
|
2016-11-05 21:47:09 +00:00
|
|
|
|
2023-07-12 07:35:11 +00:00
|
|
|
ln -sfn "$(readlink -f "$systemConfig/etc")" /etc/static
|
2020-06-17 16:29:20 +00:00
|
|
|
|
2023-07-12 07:35:11 +00:00
|
|
|
while IFS= read -r -d "" etcStaticFile; do
|
2023-07-16 11:13:27 +00:00
|
|
|
etcFile=/etc/''${etcStaticFile#/etc/static/}
|
|
|
|
etcDir=''${etcFile%/*}
|
2023-07-12 07:35:11 +00:00
|
|
|
|
|
|
|
if [[ ! -d $etcDir ]]; then
|
2023-07-16 11:13:27 +00:00
|
|
|
mkdir -p "$etcDir"
|
2017-01-02 19:09:54 +00:00
|
|
|
fi
|
2023-07-12 07:35:11 +00:00
|
|
|
|
|
|
|
if [[ -e $etcFile ]]; then
|
|
|
|
if [[ $(readlink -- "$etcFile") == "$etcStaticFile" ]]; then
|
|
|
|
continue
|
|
|
|
else
|
|
|
|
mv "$etcFile" "$etcFile.before-nix-darwin"
|
2016-11-05 21:47:09 +00:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2023-07-12 07:35:11 +00:00
|
|
|
ln -s "$etcStaticFile" "$etcFile"
|
|
|
|
done < <(find -H /etc/static -type l -print0)
|
2023-06-24 03:58:56 +00:00
|
|
|
|
2023-07-12 07:35:11 +00:00
|
|
|
while IFS= read -r -d "" etcFile; do
|
2023-07-16 11:13:27 +00:00
|
|
|
etcStaticFile=/etc/static/''${etcFile#/etc/}
|
2023-07-12 07:35:11 +00:00
|
|
|
|
|
|
|
# Delete stale links into /etc/static.
|
|
|
|
if [[
|
2023-07-16 16:02:10 +00:00
|
|
|
$(readlink -- "$etcFile") == "$etcStaticFile"
|
2023-07-12 07:35:11 +00:00
|
|
|
&& ! -e $etcStaticFile
|
|
|
|
]]; then
|
2023-07-16 11:13:27 +00:00
|
|
|
rm "$etcFile"
|
2016-11-05 21:47:09 +00:00
|
|
|
fi
|
2023-07-12 07:35:11 +00:00
|
|
|
done < <(find -H /etc -type l -print0)
|
2016-11-05 21:47:09 +00:00
|
|
|
'';
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|