diff --git a/modules/lib/write-text.nix b/modules/lib/write-text.nix index 7719a230..ddf40769 100644 --- a/modules/lib/write-text.nix +++ b/modules/lib/write-text.nix @@ -44,6 +44,12 @@ in Path of the source file. ''; }; + + knownSha256Hashes = mkOption { + internal = true; + type = types.listOf types.str; + default = []; + }; }; config = { diff --git a/modules/system/etc.nix b/modules/system/etc.nix index 6577aec5..fc1ff064 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