summaryrefslogtreecommitdiff
path: root/modules/system
diff options
context:
space:
mode:
authorDaiderd Jordan <daiderd@gmail.com>2020-06-17 18:29:20 +0200
committerDaiderd Jordan <daiderd@gmail.com>2020-06-17 19:23:31 +0200
commitb22481d03a686f59ee2a2dbba5ee4ff7b10c6594 (patch)
tree3c3ab7d187f30a6a5d88d0199ff21f03ae18bd8d /modules/system
parent2d6479b72e06ae4cbd34562bae753deeef9e24c8 (diff)
etc: allow replacing files with known content
This enables replacing existing system files like /etc/bashrc by default while keeping the safer behaviour for other files like /etc/passwd, etc. that could potentially cause major problems for the system when replaced.
Diffstat (limited to 'modules/system')
-rw-r--r--modules/system/etc.nix24
1 files changed, 21 insertions, 3 deletions
diff --git a/modules/system/etc.nix b/modules/system/etc.nix
index 6577aec..fc1ff06 100644
--- a/modules/system/etc.nix
+++ b/modules/system/etc.nix
@@ -44,6 +44,9 @@ in
# Set up the statically computed bits of /etc.
echo "setting up /etc..." >&2
+ declare -A etcSha256Hashes
+ ${concatMapStringsSep "\n" (attr: "etcSha256Hashes['/etc/${attr.target}']='${concatStringsSep " " attr.knownSha256Hashes}'") etc}
+
ln -sfn "$(readlink -f $systemConfig/etc)" /etc/static
for f in $(find /etc/static/* -type l); do
@@ -53,9 +56,24 @@ in
mkdir -p "$d"
fi
if [ -e "$l" ]; then
- if [ "$(readlink $l)" != "$f" ]; then
+ if [ "$(readlink "$l")" != "$f" ]; then
if ! grep -q /etc/static "$l"; then
- echo "warning: not linking environment.etc.\"''${l#/etc/}\" because $l exists, skipping..." >&2
+ o=''$(shasum -a256 "$l")
+ o=''${o%% *}
+ for h in ''${etcSha256Hashes["$l"]}; do
+ if [ "$o" = "$h" ]; then
+ mv "$l" "$l.orig"
+ ln -s "$f" "$l"
+ break
+ else
+ h=
+ fi
+ done
+
+ if [ -z "$h" ]; then
+ echo "error: not linking environment.etc.\"''${l#/etc/}\" because $l already exists, skipping..." >&2
+ echo "existing file has unknown content $o, move and activate again to apply" >&2
+ fi
fi
fi
else
@@ -66,7 +84,7 @@ in
for l in $(find /etc/* -type l 2> /dev/null); do
f="$(echo $l | sed 's,/etc/,/etc/static/,')"
f=/etc/static/''${l#/etc/}
- if [ "$(readlink $l)" = "$f" -a ! -e "$(readlink -f $l)" ]; then
+ if [ "$(readlink "$l")" = "$f" -a ! -e "$(readlink -f "$l")" ]; then
rm "$l"
fi
done