From 4486c3b76887be261b377f290b5347f6dee4d0aa Mon Sep 17 00:00:00 2001 From: Felix Uhl Date: Sun, 15 Jan 2023 15:42:24 +0100 Subject: [PATCH 1/3] Don't overwrite already-copied files on install Fixes #6679 and all issues that contain `cp: cannot overwrite directory ... with non-directory` errors. These were caused by 475fc109e72e494039b253131314e3a3ea5723c6 and bb0c4b9f25b6d064d91aedd71940f14b1b624291. Or rather, installations after 475fc109 erroneously followed and deep-copied symlinks, which was fixed in bb0c4b9f. This meant installations installed with the installer released between these commits had some paths in their nix store with directories where symlinks should have been, causing the fixed installer to try to overwrite them with symlinks. The -n will not overwrite existing files, which is fine inside of the nix-store as identical store paths will have identical content. For additional details and examples, see https://github.com/NixOS/nix/pull/7603#issuecomment-1411124619 --- scripts/install-multi-user.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh index 656769d84d4..474df5826c4 100644 --- a/scripts/install-multi-user.sh +++ b/scripts/install-multi-user.sh @@ -816,7 +816,7 @@ install_from_extracted_nix() { cd "$EXTRACTED_NIX_PATH" _sudo "to copy the basic Nix files to the new store at $NIX_ROOT/store" \ - cp -RPp ./store/* "$NIX_ROOT/store/" + cp -RPnp ./store/* "$NIX_ROOT/store/" _sudo "to make the new store non-writable at $NIX_ROOT/store" \ chmod -R ugo-w "$NIX_ROOT/store/" From 09a3b0991f49155073f3b48f0b9e360fb310e259 Mon Sep 17 00:00:00 2001 From: Felix Uhl Date: Sun, 15 Jan 2023 20:55:30 +0100 Subject: [PATCH 2/3] Test for idempotency of installer --- tests/installer/default.nix | 40 ++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/installer/default.nix b/tests/installer/default.nix index 49cfd2bccba..0b0e0e23677 100644 --- a/tests/installer/default.nix +++ b/tests/installer/default.nix @@ -131,7 +131,8 @@ let with nixpkgsFor.${image.system}.native; runCommand "installer-test-${imageName}-${testName}" - { buildInputs = [ qemu_kvm openssh ]; + { + buildInputs = [ qemu_kvm openssh ]; image = image.image; postBoot = image.postBoot or ""; installScript = installScripts.${testName}.script; @@ -230,15 +231,40 @@ let [[ \$(nix-instantiate --eval --expr 'builtins.readFile ') = '"someContent"' ]] EOF + echo "Running installer again to test for idempotency..." + $ssh "set -eux; $installScript" + + echo "Testing Nix installation..." + $ssh < \$out"]; }') + [[ \$(cat \$out) = foobar ]] + EOF + echo "Done!" touch $out ''; in -builtins.mapAttrs (imageName: image: - { ${image.system} = builtins.mapAttrs (testName: test: - makeTest imageName testName - ) installScripts; - } -) images +builtins.mapAttrs + (imageName: image: + { + ${image.system} = builtins.mapAttrs + (testName: test: + makeTest imageName testName + ) + installScripts; + } + ) + images From f09d0e9729699a8ef3e0929772e62f360f8d7ac2 Mon Sep 17 00:00:00 2001 From: Felix Uhl Date: Tue, 17 Jan 2023 01:00:01 +0100 Subject: [PATCH 3/3] Make multi-user installer fully idempotent Fixes #7215, #7069 and #6617 --- scripts/install-multi-user.sh | 48 +++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh index 474df5826c4..1dae0cdec24 100644 --- a/scripts/install-multi-user.sh +++ b/scripts/install-multi-user.sh @@ -441,19 +441,31 @@ $(uninstall_directions) EOF fi - # TODO: I think it would be good for this step to accumulate more - # knowledge of older obsolete artifacts, if there are any. - # We could issue a "reminder" here that the user might want - # to clean them up? - + problematic_profile_targets=() for profile_target in "${PROFILE_TARGETS[@]}"; do - # TODO: I think it would be good to accumulate a list of all - # of the copies so that people don't hit this 2 or 3x in - # a row for different files. - if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then - # this backup process first released in Nix 2.1 - failure <