From 37598a13e877980d4654c632d10921c41c9ad976 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 09:26:48 +0100 Subject: [PATCH 01/16] Revert "Check _NIX_TEST_NO_SANDBOX when setting _canUseSandbox." This reverts commit 7ed0ab2dabececd84578ddf70ecad0e528d67a28. --- tests/common/vars-and-functions.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/vars-and-functions.sh.in b/tests/common/vars-and-functions.sh.in index ad062387149..dc7ce13ccd0 100644 --- a/tests/common/vars-and-functions.sh.in +++ b/tests/common/vars-and-functions.sh.in @@ -141,7 +141,7 @@ restartDaemon() { startDaemon } -if [[ -z "${_NIX_TEST_NO_SANDBOX:-}" ]] && [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then +if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then _canUseSandbox=1 fi From f66b65a30ad1f14dd757874c12255eef42368b04 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 09:29:27 +0100 Subject: [PATCH 02/16] Revert "Skip build-remote-trustless unless sandbox is supported." This reverts commit fad0dd4afb66577f9c17b5a315d120ac0f5acd94. --- tests/build-remote-trustless-should-fail-0.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/build-remote-trustless-should-fail-0.sh b/tests/build-remote-trustless-should-fail-0.sh index b14101f83a5..fad1def59ff 100644 --- a/tests/build-remote-trustless-should-fail-0.sh +++ b/tests/build-remote-trustless-should-fail-0.sh @@ -2,7 +2,6 @@ source common.sh enableFeatures "daemon-trust-override" -requireSandboxSupport restartDaemon [[ $busybox =~ busybox ]] || skipTest "no busybox" From a33ee5c84305b85f5bcd0ea1be43b44cf601693f Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 10:49:44 +0100 Subject: [PATCH 03/16] Paths added to lower store are accessible via overlay. --- tests/overlay-local-store/add-lower-inner.sh | 31 +++++++++++++++++++ tests/overlay-local-store/add-lower.sh | 5 +++ tests/overlay-local-store/common.sh | 11 ++++++- tests/overlay-local-store/local.mk | 3 +- .../redundant-add-inner.sh | 5 +-- 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100755 tests/overlay-local-store/add-lower-inner.sh create mode 100755 tests/overlay-local-store/add-lower.sh diff --git a/tests/overlay-local-store/add-lower-inner.sh b/tests/overlay-local-store/add-lower-inner.sh new file mode 100755 index 00000000000..40a1f397ce7 --- /dev/null +++ b/tests/overlay-local-store/add-lower-inner.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +set -x + +source common.sh + +# Avoid store dir being inside sandbox build-dir +unset NIX_STORE_DIR +unset NIX_STATE_DIR + +storeDirs + +initLowerStore + +mountOverlayfs + +# Add something to the overlay store +overlayPath=$(addTextToStore "$storeB" "overlay-file" "Add to overlay store") +stat "$TEST_ROOT/merged-store/$overlayPath" + +# Now add something to the lower store +lowerPath=$(addTextToStore "$storeA" "lower-file" "Add to lower store") +stat "$TEST_ROOT/store-a/$lowerPath" + +# Remount overlayfs to ensure synchronization +mount -o remount "$TEST_ROOT/merged-store/nix/store" + +# Path should be accessible via overlay store +stat "$TEST_ROOT/merged-store/$lowerPath" diff --git a/tests/overlay-local-store/add-lower.sh b/tests/overlay-local-store/add-lower.sh new file mode 100755 index 00000000000..f0ac46a91b5 --- /dev/null +++ b/tests/overlay-local-store/add-lower.sh @@ -0,0 +1,5 @@ +source common.sh + +requireEnvironment +setupConfig +execUnshare ./add-lower-inner.sh diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 14910200043..7850c068bf8 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -8,7 +8,7 @@ requireEnvironment () { } setupConfig () { - echo "drop-supplementary-groups = false" >> "$NIX_CONF_DIR"/nix.conf + echo "require-drop-supplementary-groups = false" >> "$NIX_CONF_DIR"/nix.conf echo "build-users-group = " >> "$NIX_CONF_DIR"/nix.conf } @@ -54,3 +54,12 @@ initLowerStore () { execUnshare () { exec unshare --mount --map-root-user "$@" } + +addTextToStore() { + storeDir=$1; shift + filename=$1; shift + content=$1; shift + filePath="$TEST_HOME/$filename" + echo "$content" > "$filePath" + nix-store --store "$storeDir" --add "$filePath" +} diff --git a/tests/overlay-local-store/local.mk b/tests/overlay-local-store/local.mk index b94238a675b..5d14e2561ea 100644 --- a/tests/overlay-local-store/local.mk +++ b/tests/overlay-local-store/local.mk @@ -2,6 +2,7 @@ overlay-local-store-tests := \ $(d)/check-post-init.sh \ $(d)/redundant-add.sh \ $(d)/build.sh \ - $(d)/bad-uris.sh + $(d)/bad-uris.sh \ + $(d)/add-lower.sh install-tests-groups += overlay-local-store diff --git a/tests/overlay-local-store/redundant-add-inner.sh b/tests/overlay-local-store/redundant-add-inner.sh index 97969b40e4f..cfdae68b4c9 100755 --- a/tests/overlay-local-store/redundant-add-inner.sh +++ b/tests/overlay-local-store/redundant-add-inner.sh @@ -7,7 +7,7 @@ set -x source common.sh # Avoid store dir being inside sandbox build-dir -unset NIX_STORE_DIR +unset NIX_STORE_DIR # TODO: This causes toRealPath to fail (it expects this var to be set) unset NIX_STATE_DIR storeDirs @@ -27,4 +27,5 @@ path=$(nix-store --store "$storeB" --add ../dummy) stat $(toRealPath "$storeA/nix/store" "$path") # upper layer should still not have it (no redundant copy) -expect 1 stat $(toRealPath "$storeB/nix/store" "$path") +expect 1 stat $(toRealPath "$storeB/nix/store" "$path") # TODO: Check this is failing for the right reason. + # $storeB is a store URI not a directory path From 0ccf6382af4c34dafacd2a417ba658e62d81adbf Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 12:30:33 +0100 Subject: [PATCH 04/16] Add test for verifying overlay store. --- tests/overlay-local-store/local.mk | 3 ++- tests/overlay-local-store/verify-inner.sh | 32 +++++++++++++++++++++++ tests/overlay-local-store/verify.sh | 5 ++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 tests/overlay-local-store/verify-inner.sh create mode 100755 tests/overlay-local-store/verify.sh diff --git a/tests/overlay-local-store/local.mk b/tests/overlay-local-store/local.mk index 5d14e2561ea..5e8c76b4ee6 100644 --- a/tests/overlay-local-store/local.mk +++ b/tests/overlay-local-store/local.mk @@ -3,6 +3,7 @@ overlay-local-store-tests := \ $(d)/redundant-add.sh \ $(d)/build.sh \ $(d)/bad-uris.sh \ - $(d)/add-lower.sh + $(d)/add-lower.sh \ + $(d)/verify.sh install-tests-groups += overlay-local-store diff --git a/tests/overlay-local-store/verify-inner.sh b/tests/overlay-local-store/verify-inner.sh new file mode 100755 index 00000000000..b68800e5c47 --- /dev/null +++ b/tests/overlay-local-store/verify-inner.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +set -x + +source common.sh + +# Avoid store dir being inside sandbox build-dir +unset NIX_STORE_DIR +unset NIX_STATE_DIR + +storeDirs + +initLowerStore + +mountOverlayfs + +#path=$(nix-store --store "$storeB" --add ../dummy) + +path=$(nix-build --store $storeB ../hermetic.nix --arg busybox "$busybox" --arg seed 1) + +inputDrvPath=$(find "$storeA" -name "*-hermetic-input-1.drv") +rm -v "$inputDrvPath" + +#tree "$TEST_ROOT" + +#rm -v "$TEST_ROOT/store-a/$path" + +nix-store --store "$storeB" --verify + +echo "SUCCESS" diff --git a/tests/overlay-local-store/verify.sh b/tests/overlay-local-store/verify.sh new file mode 100755 index 00000000000..8b44603ff83 --- /dev/null +++ b/tests/overlay-local-store/verify.sh @@ -0,0 +1,5 @@ +source common.sh + +requireEnvironment +setupConfig +execUnshare ./verify-inner.sh From 58085e4eff1e06524f9ad8f6e9f271c19dcbba9e Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 13:10:34 +0100 Subject: [PATCH 05/16] Have verify test exercise check-contents too. --- tests/overlay-local-store/verify-inner.sh | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/overlay-local-store/verify-inner.sh b/tests/overlay-local-store/verify-inner.sh index b68800e5c47..5f8cbcf0e81 100755 --- a/tests/overlay-local-store/verify-inner.sh +++ b/tests/overlay-local-store/verify-inner.sh @@ -16,17 +16,24 @@ initLowerStore mountOverlayfs -#path=$(nix-store --store "$storeB" --add ../dummy) +# Realise a derivation from the lower store to propagate paths to overlay DB +nix-store --store "$storeB" --realise $drvPath -path=$(nix-build --store $storeB ../hermetic.nix --arg busybox "$busybox" --arg seed 1) +# Also ensure dummy file exists in overlay DB +dummyPath=$(nix-store --store "$storeB" --add ../dummy) -inputDrvPath=$(find "$storeA" -name "*-hermetic-input-1.drv") -rm -v "$inputDrvPath" +# Verify should be successful at this point +nix-store --store "$storeB" --verify --check-contents -#tree "$TEST_ROOT" +# Now delete one of the derivation inputs in the lower store +inputDrvFullPath=$(find "$storeA" -name "*-hermetic-input-1.drv") +inputDrvPath=${inputDrvFullPath/*\/nix\/store\///nix/store/} +rm -v "$inputDrvFullPath" -#rm -v "$TEST_ROOT/store-a/$path" +# And truncate the contents of dummy file in lower store +find "$storeA" -name "*-dummy" -exec truncate -s 0 {} \; -nix-store --store "$storeB" --verify - -echo "SUCCESS" +# Verify should fail with the messages about missing input and modified dummy file +verifyOutput=$(expectStderr 1 nix-store --store "$storeB" --verify --check-contents) +<<<"$verifyOutput" grepQuiet "path '$inputDrvPath' disappeared, but it still has valid referrers!" +<<<"$verifyOutput" grepQuiet "path '$dummyPath' was modified! expected hash" From d5cd74a4012d583d11d491bec9f1fa9a07b11973 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 13:49:13 +0100 Subject: [PATCH 06/16] Override verifyStore to always pass NoRepair for LocalOverlayStore. --- src/libstore/local-overlay-store.cc | 7 +++++++ src/libstore/local-overlay-store.hh | 2 ++ tests/overlay-local-store/verify-inner.sh | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libstore/local-overlay-store.cc b/src/libstore/local-overlay-store.cc index ddccb8c5aa9..182955fbe40 100644 --- a/src/libstore/local-overlay-store.cc +++ b/src/libstore/local-overlay-store.cc @@ -188,6 +188,13 @@ void LocalOverlayStore::deleteGCPath(const Path & path, uint64_t & bytesFreed) } } +bool LocalOverlayStore::verifyStore(bool checkContents, RepairFlag repair) +{ + if (repair) + warn("local-overlay: store does not support --verify --repair"); + return LocalStore::verifyStore(checkContents, NoRepair); +} + static RegisterStoreImplementation regLocalOverlayStore; } diff --git a/src/libstore/local-overlay-store.hh b/src/libstore/local-overlay-store.hh index 6f995ba393c..8fa99ee141f 100644 --- a/src/libstore/local-overlay-store.hh +++ b/src/libstore/local-overlay-store.hh @@ -112,6 +112,8 @@ private: Callback> callback) noexcept override; void deleteGCPath(const Path & path, uint64_t & bytesFreed) override; + + bool verifyStore(bool checkContents, RepairFlag repair) override; }; } diff --git a/tests/overlay-local-store/verify-inner.sh b/tests/overlay-local-store/verify-inner.sh index 5f8cbcf0e81..8f8839302e0 100755 --- a/tests/overlay-local-store/verify-inner.sh +++ b/tests/overlay-local-store/verify-inner.sh @@ -34,6 +34,7 @@ rm -v "$inputDrvFullPath" find "$storeA" -name "*-dummy" -exec truncate -s 0 {} \; # Verify should fail with the messages about missing input and modified dummy file -verifyOutput=$(expectStderr 1 nix-store --store "$storeB" --verify --check-contents) +verifyOutput=$(expectStderr 1 nix-store --store "$storeB" --verify --check-contents --repair) <<<"$verifyOutput" grepQuiet "path '$inputDrvPath' disappeared, but it still has valid referrers!" <<<"$verifyOutput" grepQuiet "path '$dummyPath' was modified! expected hash" +<<<"$verifyOutput" grepQuiet "store does not support --verify --repair" From 614efc1240dbfefbdabced808decd8defd33df8e Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 18 Jul 2023 13:59:22 +0100 Subject: [PATCH 07/16] Add test for store optimise path deduplication. --- src/libstore/local-overlay-store.cc | 5 +++++ src/libstore/local-overlay-store.hh | 2 ++ tests/overlay-local-store/local.mk | 3 ++- tests/overlay-local-store/optimise-inner.sh | 19 +++++++++++++++++++ tests/overlay-local-store/optimise.sh | 5 +++++ 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100755 tests/overlay-local-store/optimise-inner.sh create mode 100755 tests/overlay-local-store/optimise.sh diff --git a/src/libstore/local-overlay-store.cc b/src/libstore/local-overlay-store.cc index 182955fbe40..da0c8e3d57c 100644 --- a/src/libstore/local-overlay-store.cc +++ b/src/libstore/local-overlay-store.cc @@ -188,6 +188,11 @@ void LocalOverlayStore::deleteGCPath(const Path & path, uint64_t & bytesFreed) } } +void LocalOverlayStore::optimiseStore() +{ + warn("not implemented"); +} + bool LocalOverlayStore::verifyStore(bool checkContents, RepairFlag repair) { if (repair) diff --git a/src/libstore/local-overlay-store.hh b/src/libstore/local-overlay-store.hh index 8fa99ee141f..ef377b7a6ac 100644 --- a/src/libstore/local-overlay-store.hh +++ b/src/libstore/local-overlay-store.hh @@ -113,6 +113,8 @@ private: void deleteGCPath(const Path & path, uint64_t & bytesFreed) override; + void optimiseStore() override; + bool verifyStore(bool checkContents, RepairFlag repair) override; }; diff --git a/tests/overlay-local-store/local.mk b/tests/overlay-local-store/local.mk index 5e8c76b4ee6..3a6d00bc1e8 100644 --- a/tests/overlay-local-store/local.mk +++ b/tests/overlay-local-store/local.mk @@ -4,6 +4,7 @@ overlay-local-store-tests := \ $(d)/build.sh \ $(d)/bad-uris.sh \ $(d)/add-lower.sh \ - $(d)/verify.sh + $(d)/verify.sh \ + $(d)/optimise.sh install-tests-groups += overlay-local-store diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh new file mode 100755 index 00000000000..76c5a0cb6f9 --- /dev/null +++ b/tests/overlay-local-store/optimise-inner.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +set -x + +source common.sh + +# Avoid store dir being inside sandbox build-dir +unset NIX_STORE_DIR +unset NIX_STATE_DIR + +storeDirs + +initLowerStore + +mountOverlayfs + +nix-store --store "$storeB" --optimise diff --git a/tests/overlay-local-store/optimise.sh b/tests/overlay-local-store/optimise.sh new file mode 100755 index 00000000000..569afa248a9 --- /dev/null +++ b/tests/overlay-local-store/optimise.sh @@ -0,0 +1,5 @@ +source common.sh + +requireEnvironment +setupConfig +execUnshare ./optimise-inner.sh From a9510f950228957cde98001b67e123aa2d4d62c9 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Wed, 19 Jul 2023 11:23:54 +0100 Subject: [PATCH 08/16] Implement test for store path deduplication. --- tests/overlay-local-store/common.sh | 16 ++++------ tests/overlay-local-store/optimise-inner.sh | 33 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 7850c068bf8..5a678c947fc 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -22,11 +22,12 @@ storeDirs () { # Mounting Overlay Store mountOverlayfs () { + mergedStorePath="$TEST_ROOT/merged-store/nix/store" mount -t overlay overlay \ -o lowerdir="$storeA/nix/store" \ -o upperdir="$storeBTop" \ -o workdir="$TEST_ROOT/workdir" \ - "$TEST_ROOT/merged-store/nix/store" \ + "$mergedStorePath" \ || skipTest "overlayfs is not supported" cleanupOverlay () { @@ -36,6 +37,10 @@ mountOverlayfs () { trap cleanupOverlay EXIT } +remountOverlayfs () { + mount -o remount "$mergedStorePath" +} + toRealPath () { storeDir=$1; shift storePath=$1; shift @@ -54,12 +59,3 @@ initLowerStore () { execUnshare () { exec unshare --mount --map-root-user "$@" } - -addTextToStore() { - storeDir=$1; shift - filename=$1; shift - content=$1; shift - filePath="$TEST_HOME/$filename" - echo "$content" > "$filePath" - nix-store --store "$storeDir" --add "$filePath" -} diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh index 76c5a0cb6f9..c60c742a2c2 100755 --- a/tests/overlay-local-store/optimise-inner.sh +++ b/tests/overlay-local-store/optimise-inner.sh @@ -16,4 +16,37 @@ initLowerStore mountOverlayfs +# Create a file to add to store +dupFilePath="$TEST_ROOT/dup-file" +echo Duplicate > "$dupFilePath" + +# Add it to the overlay store (it will be written to the upper layer) +dupFileStorePath=$(nix-store --store "$storeB" --add "$dupFilePath") + +# Now add it to the lower store so the store path is duplicated +nix-store --store "$storeA" --add "$dupFilePath" + +# Ensure overlayfs and layers and synchronised +remountOverlayfs + +dupFilename="${dupFileStorePath#/nix/store}" +lowerPath="$storeA/$dupFileStorePath" +upperPath="$storeBTop/$dupFilename" +overlayPath="$mergedStorePath/$dupFilename" + +# Check store path exists in both layers and overlay +lowerInode=$(stat -c %i "$lowerPath") +upperInode=$(stat -c %i "$upperPath") +overlayInode=$(stat -c %i "$overlayPath") +[[ $upperInode == $overlayInode ]] +[[ $upperInode != $lowerInode ]] + +# Run optimise to deduplicate store paths nix-store --store "$storeB" --optimise +remountOverlayfs + +stat "$lowerPath" +stat "$overlayPath" +expect 1 stat "$upperPath" + +#expect 1 stat $(toRealPath "$storeA/nix/store" "$path") From 8ddbcb736a17d08ce899de345548064eebf673c9 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Wed, 19 Jul 2023 12:32:32 +0100 Subject: [PATCH 09/16] Implement overlay store deduplication. --- src/libstore/local-overlay-store.cc | 18 +++++++++++++++++- tests/overlay-local-store/optimise-inner.sh | 3 +-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/libstore/local-overlay-store.cc b/src/libstore/local-overlay-store.cc index da0c8e3d57c..9e530ed9b81 100644 --- a/src/libstore/local-overlay-store.cc +++ b/src/libstore/local-overlay-store.cc @@ -190,7 +190,23 @@ void LocalOverlayStore::deleteGCPath(const Path & path, uint64_t & bytesFreed) void LocalOverlayStore::optimiseStore() { - warn("not implemented"); + Activity act(*logger, actOptimiseStore); + + // Note for LocalOverlayStore, queryAllValidPaths only returns paths in upper layer + auto paths = queryAllValidPaths(); + + act.progress(0, paths.size()); + + uint64_t done = 0; + + for (auto & path : paths) { + if (lowerStore->isValidPath(path)) { + // Deduplicate store path + deletePath(toUpperPath(path)); + } + done++; + act.progress(done, paths.size()); + } } bool LocalOverlayStore::verifyStore(bool checkContents, RepairFlag repair) diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh index c60c742a2c2..2b778b311c8 100755 --- a/tests/overlay-local-store/optimise-inner.sh +++ b/tests/overlay-local-store/optimise-inner.sh @@ -45,8 +45,7 @@ overlayInode=$(stat -c %i "$overlayPath") nix-store --store "$storeB" --optimise remountOverlayfs +# Check path only exists in lower store stat "$lowerPath" stat "$overlayPath" expect 1 stat "$upperPath" - -#expect 1 stat $(toRealPath "$storeA/nix/store" "$path") From d1c77b201a1b0e6c14470b69c134652a8858fc18 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Wed, 19 Jul 2023 13:25:37 +0100 Subject: [PATCH 10/16] Explicitly exec shell to fix ENOENT errors. --- tests/overlay-local-store/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 5a678c947fc..0e98e931fc1 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -57,5 +57,5 @@ initLowerStore () { } execUnshare () { - exec unshare --mount --map-root-user "$@" + exec unshare --mount --map-root-user "$SHELL" "$@" } From 44f855d14ee40dfeaf52c4f01e2de124fe0f18fc Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Wed, 19 Jul 2023 15:09:58 +0100 Subject: [PATCH 11/16] Missing addTextToStore function. --- tests/overlay-local-store/common.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 0e98e931fc1..2fba2e7f60d 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -59,3 +59,12 @@ initLowerStore () { execUnshare () { exec unshare --mount --map-root-user "$SHELL" "$@" } + +addTextToStore() { + storeDir=$1; shift + filename=$1; shift + content=$1; shift + filePath="$TEST_HOME/$filename" + echo "$content" > "$filePath" + nix-store --store "$storeDir" --add "$filePath" +} From 7fda19e2f139a7e41cb53cdbdd692dbc98755d91 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Wed, 19 Jul 2023 16:46:51 +0100 Subject: [PATCH 12/16] Mount tmpfs first to ensure overlayfs works consistently. --- tests/overlay-local-store/common.sh | 19 +++++++++++-------- tests/overlay-local-store/optimise-inner.sh | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 2fba2e7f60d..6aec96ba17b 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -13,26 +13,29 @@ setupConfig () { } storeDirs () { - storeA="$TEST_ROOT/store-a" - storeBTop="$TEST_ROOT/store-b" - storeB="local-overlay?root=$TEST_ROOT/merged-store&lower-store=$storeA&upper-layer=$storeBTop" + storesRoot="$TEST_ROOT/stores" + mkdir -p "$storesRoot" + mount -t tmpfs tmpfs "$storesRoot" + storeA="$storesRoot/store-a" + storeBTop="$storesRoot/store-b" + storeB="local-overlay?root=$storesRoot/merged-store&lower-store=$storeA&upper-layer=$storeBTop" # Creating testing directories - mkdir -p "$TEST_ROOT"/{store-a/nix/store,store-b,merged-store/nix/store,workdir} + mkdir -p "$storesRoot"/{store-a/nix/store,store-b,merged-store/nix/store,workdir} } # Mounting Overlay Store mountOverlayfs () { - mergedStorePath="$TEST_ROOT/merged-store/nix/store" + mergedStorePath="$storesRoot/merged-store/nix/store" mount -t overlay overlay \ -o lowerdir="$storeA/nix/store" \ -o upperdir="$storeBTop" \ - -o workdir="$TEST_ROOT/workdir" \ + -o workdir="$storesRoot/workdir" \ "$mergedStorePath" \ || skipTest "overlayfs is not supported" cleanupOverlay () { - umount "$TEST_ROOT/merged-store/nix/store" - rm -r $TEST_ROOT/workdir + umount "$storesRoot/merged-store/nix/store" + rm -r $storesRoot/workdir } trap cleanupOverlay EXIT } diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh index 2b778b311c8..079e2232687 100755 --- a/tests/overlay-local-store/optimise-inner.sh +++ b/tests/overlay-local-store/optimise-inner.sh @@ -17,7 +17,7 @@ initLowerStore mountOverlayfs # Create a file to add to store -dupFilePath="$TEST_ROOT/dup-file" +dupFilePath="$storesRoot/dup-file" echo Duplicate > "$dupFilePath" # Add it to the overlay store (it will be written to the upper layer) From 9769a0ae7d840f1df7db3de4524180016830e57e Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Thu, 20 Jul 2023 10:27:11 +0100 Subject: [PATCH 13/16] Ensure all overlay tests use new tmpfs store paths. --- tests/overlay-local-store/add-lower-inner.sh | 8 +++--- tests/overlay-local-store/bad-uris.sh | 4 +-- .../check-post-init-inner.sh | 2 +- tests/overlay-local-store/common.sh | 28 +++++++++++-------- tests/overlay-local-store/optimise-inner.sh | 2 +- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/tests/overlay-local-store/add-lower-inner.sh b/tests/overlay-local-store/add-lower-inner.sh index 40a1f397ce7..8c71f078066 100755 --- a/tests/overlay-local-store/add-lower-inner.sh +++ b/tests/overlay-local-store/add-lower-inner.sh @@ -18,14 +18,14 @@ mountOverlayfs # Add something to the overlay store overlayPath=$(addTextToStore "$storeB" "overlay-file" "Add to overlay store") -stat "$TEST_ROOT/merged-store/$overlayPath" +stat "$storeVolume/merged-store/$overlayPath" # Now add something to the lower store lowerPath=$(addTextToStore "$storeA" "lower-file" "Add to lower store") -stat "$TEST_ROOT/store-a/$lowerPath" +stat "$storeVolume/store-a/$lowerPath" # Remount overlayfs to ensure synchronization -mount -o remount "$TEST_ROOT/merged-store/nix/store" +mount -o remount "$storeVolume/merged-store/nix/store" # Path should be accessible via overlay store -stat "$TEST_ROOT/merged-store/$lowerPath" +stat "$storeVolume/merged-store/$lowerPath" diff --git a/tests/overlay-local-store/bad-uris.sh b/tests/overlay-local-store/bad-uris.sh index d4261bd97db..c5926473507 100644 --- a/tests/overlay-local-store/bad-uris.sh +++ b/tests/overlay-local-store/bad-uris.sh @@ -7,8 +7,8 @@ storeDirs mkdir -p $TEST_ROOT/bad_test badTestRoot=$TEST_ROOT/bad_test storeBadRoot="local-overlay?root=$badTestRoot&lower-store=$storeA&upper-layer=$storeBTop" -storeBadLower="local-overlay?root=$TEST_ROOT/merged-store&lower-store=$badTestRoot&upper-layer=$storeBTop" -storeBadUpper="local-overlay?root=$TEST_ROOT/merged-store&lower-store=$storeA&upper-layer=$badTestRoot" +storeBadLower="local-overlay?root=$storeVolume/merged-store&lower-store=$badTestRoot&upper-layer=$storeBTop" +storeBadUpper="local-overlay?root=$storeVolume/merged-store&lower-store=$storeA&upper-layer=$badTestRoot" declare -a storesBad=( "$storeBadRoot" "$storeBadLower" "$storeBadUpper" diff --git a/tests/overlay-local-store/check-post-init-inner.sh b/tests/overlay-local-store/check-post-init-inner.sh index 37ed8c113f9..c7d1c70d445 100755 --- a/tests/overlay-local-store/check-post-init-inner.sh +++ b/tests/overlay-local-store/check-post-init-inner.sh @@ -25,7 +25,7 @@ stat $(toRealPath "$storeA/nix/store" "$path") expect 1 stat $(toRealPath "$storeBTop" "$path") # Checking for path in overlay store matching lower layer -diff $(toRealPath "$storeA/nix/store" "$path") $(toRealPath "$TEST_ROOT/merged-store/nix/store" "$path") +diff $(toRealPath "$storeA/nix/store" "$path") $(toRealPath "$storeVolume/merged-store/nix/store" "$path") # Checking requisites query agreement [[ \ diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 6aec96ba17b..686523e9c98 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -12,30 +12,36 @@ setupConfig () { echo "build-users-group = " >> "$NIX_CONF_DIR"/nix.conf } + + storeDirs () { - storesRoot="$TEST_ROOT/stores" - mkdir -p "$storesRoot" - mount -t tmpfs tmpfs "$storesRoot" - storeA="$storesRoot/store-a" - storeBTop="$storesRoot/store-b" - storeB="local-overlay?root=$storesRoot/merged-store&lower-store=$storeA&upper-layer=$storeBTop" + # Attempt to create store dirs on tmpfs volume. + # This ensures lowerdir, upperdir and workdir will be on + # a consistent filesystem that fully supports OverlayFS. + storeVolume="$TEST_ROOT/stores" + mkdir -p "$storeVolume" + mount -t tmpfs tmpfs "$storeVolume" || true # But continue anyway if that fails. + + storeA="$storeVolume/store-a" + storeBTop="$storeVolume/store-b" + storeB="local-overlay?root=$storeVolume/merged-store&lower-store=$storeA&upper-layer=$storeBTop" # Creating testing directories - mkdir -p "$storesRoot"/{store-a/nix/store,store-b,merged-store/nix/store,workdir} + mkdir -p "$storeVolume"/{store-a/nix/store,store-b,merged-store/nix/store,workdir} } # Mounting Overlay Store mountOverlayfs () { - mergedStorePath="$storesRoot/merged-store/nix/store" + mergedStorePath="$storeVolume/merged-store/nix/store" mount -t overlay overlay \ -o lowerdir="$storeA/nix/store" \ -o upperdir="$storeBTop" \ - -o workdir="$storesRoot/workdir" \ + -o workdir="$storeVolume/workdir" \ "$mergedStorePath" \ || skipTest "overlayfs is not supported" cleanupOverlay () { - umount "$storesRoot/merged-store/nix/store" - rm -r $storesRoot/workdir + umount "$storeVolume/merged-store/nix/store" + rm -r $storeVolume/workdir } trap cleanupOverlay EXIT } diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh index 079e2232687..2b778b311c8 100755 --- a/tests/overlay-local-store/optimise-inner.sh +++ b/tests/overlay-local-store/optimise-inner.sh @@ -17,7 +17,7 @@ initLowerStore mountOverlayfs # Create a file to add to store -dupFilePath="$storesRoot/dup-file" +dupFilePath="$TEST_ROOT/dup-file" echo Duplicate > "$dupFilePath" # Add it to the overlay store (it will be written to the upper layer) From 878c84d5ee88f2e6c56abb42211a729c4d342e14 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Thu, 20 Jul 2023 10:27:35 +0100 Subject: [PATCH 14/16] Fix errors about NIX_STORE_DIR being unset. --- tests/overlay-local-store/check-post-init-inner.sh | 2 +- tests/overlay-local-store/common.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/overlay-local-store/check-post-init-inner.sh b/tests/overlay-local-store/check-post-init-inner.sh index c7d1c70d445..2e7db2adc41 100755 --- a/tests/overlay-local-store/check-post-init-inner.sh +++ b/tests/overlay-local-store/check-post-init-inner.sh @@ -62,7 +62,7 @@ nix-store --verify-path --store "$storeA" "$path" # Verifying path in merged-store nix-store --verify-path --store "$storeB" "$path" -hashPart=$(echo $path | sed "s^$NIX_STORE_DIR/^^" | sed 's/-.*//') +hashPart=$(echo $path | sed "s^${NIX_STORE_DIR:-/nix/store}/^^" | sed 's/-.*//') # Lower store can find from hash part [[ $(nix store --store $storeA path-from-hash-part $hashPart) == $path ]] diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index 686523e9c98..ac4a59cd8ed 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -53,7 +53,7 @@ remountOverlayfs () { toRealPath () { storeDir=$1; shift storePath=$1; shift - echo $storeDir$(echo $storePath | sed "s^$NIX_STORE_DIR^^") + echo $storeDir$(echo $storePath | sed "s^${NIX_STORE_DIR:-/nix/store}^^") } initLowerStore () { From 2c66a093e05bc466d00c9365bc43567fd9d5c334 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Thu, 20 Jul 2023 11:03:14 +0100 Subject: [PATCH 15/16] Define storeBRoot variable distinct from storeB URI. --- tests/overlay-local-store/add-lower-inner.sh | 6 +++--- tests/overlay-local-store/bad-uris.sh | 4 ++-- tests/overlay-local-store/check-post-init-inner.sh | 2 +- tests/overlay-local-store/common.sh | 10 +++++----- tests/overlay-local-store/redundant-add-inner.sh | 5 ++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tests/overlay-local-store/add-lower-inner.sh b/tests/overlay-local-store/add-lower-inner.sh index 8c71f078066..ca7db7ab6ce 100755 --- a/tests/overlay-local-store/add-lower-inner.sh +++ b/tests/overlay-local-store/add-lower-inner.sh @@ -18,14 +18,14 @@ mountOverlayfs # Add something to the overlay store overlayPath=$(addTextToStore "$storeB" "overlay-file" "Add to overlay store") -stat "$storeVolume/merged-store/$overlayPath" +stat "$storeBRoot/$overlayPath" # Now add something to the lower store lowerPath=$(addTextToStore "$storeA" "lower-file" "Add to lower store") stat "$storeVolume/store-a/$lowerPath" # Remount overlayfs to ensure synchronization -mount -o remount "$storeVolume/merged-store/nix/store" +remountOverlayfs # Path should be accessible via overlay store -stat "$storeVolume/merged-store/$lowerPath" +stat "$storeBRoot/$lowerPath" diff --git a/tests/overlay-local-store/bad-uris.sh b/tests/overlay-local-store/bad-uris.sh index c5926473507..462bf27ebcb 100644 --- a/tests/overlay-local-store/bad-uris.sh +++ b/tests/overlay-local-store/bad-uris.sh @@ -7,8 +7,8 @@ storeDirs mkdir -p $TEST_ROOT/bad_test badTestRoot=$TEST_ROOT/bad_test storeBadRoot="local-overlay?root=$badTestRoot&lower-store=$storeA&upper-layer=$storeBTop" -storeBadLower="local-overlay?root=$storeVolume/merged-store&lower-store=$badTestRoot&upper-layer=$storeBTop" -storeBadUpper="local-overlay?root=$storeVolume/merged-store&lower-store=$storeA&upper-layer=$badTestRoot" +storeBadLower="local-overlay?root=$storeBRoot&lower-store=$badTestRoot&upper-layer=$storeBTop" +storeBadUpper="local-overlay?root=$storeBRoot&lower-store=$storeA&upper-layer=$badTestRoot" declare -a storesBad=( "$storeBadRoot" "$storeBadLower" "$storeBadUpper" diff --git a/tests/overlay-local-store/check-post-init-inner.sh b/tests/overlay-local-store/check-post-init-inner.sh index 2e7db2adc41..0f4654cc21a 100755 --- a/tests/overlay-local-store/check-post-init-inner.sh +++ b/tests/overlay-local-store/check-post-init-inner.sh @@ -25,7 +25,7 @@ stat $(toRealPath "$storeA/nix/store" "$path") expect 1 stat $(toRealPath "$storeBTop" "$path") # Checking for path in overlay store matching lower layer -diff $(toRealPath "$storeA/nix/store" "$path") $(toRealPath "$storeVolume/merged-store/nix/store" "$path") +diff $(toRealPath "$storeA/nix/store" "$path") $(toRealPath "$storeBRoot/nix/store" "$path") # Checking requisites query agreement [[ \ diff --git a/tests/overlay-local-store/common.sh b/tests/overlay-local-store/common.sh index ac4a59cd8ed..2b23352ab59 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -24,30 +24,30 @@ storeDirs () { storeA="$storeVolume/store-a" storeBTop="$storeVolume/store-b" - storeB="local-overlay?root=$storeVolume/merged-store&lower-store=$storeA&upper-layer=$storeBTop" + storeBRoot="$storeVolume/merged-store" + storeB="local-overlay?root=$storeBRoot&lower-store=$storeA&upper-layer=$storeBTop" # Creating testing directories mkdir -p "$storeVolume"/{store-a/nix/store,store-b,merged-store/nix/store,workdir} } # Mounting Overlay Store mountOverlayfs () { - mergedStorePath="$storeVolume/merged-store/nix/store" mount -t overlay overlay \ -o lowerdir="$storeA/nix/store" \ -o upperdir="$storeBTop" \ -o workdir="$storeVolume/workdir" \ - "$mergedStorePath" \ + "$storeBRoot/nix/store" \ || skipTest "overlayfs is not supported" cleanupOverlay () { - umount "$storeVolume/merged-store/nix/store" + umount "$storeBRoot/nix/store" rm -r $storeVolume/workdir } trap cleanupOverlay EXIT } remountOverlayfs () { - mount -o remount "$mergedStorePath" + mount -o remount "$storeBRoot/nix/store" } toRealPath () { diff --git a/tests/overlay-local-store/redundant-add-inner.sh b/tests/overlay-local-store/redundant-add-inner.sh index cfdae68b4c9..34b841e38dc 100755 --- a/tests/overlay-local-store/redundant-add-inner.sh +++ b/tests/overlay-local-store/redundant-add-inner.sh @@ -7,7 +7,7 @@ set -x source common.sh # Avoid store dir being inside sandbox build-dir -unset NIX_STORE_DIR # TODO: This causes toRealPath to fail (it expects this var to be set) +unset NIX_STORE_DIR unset NIX_STATE_DIR storeDirs @@ -27,5 +27,4 @@ path=$(nix-store --store "$storeB" --add ../dummy) stat $(toRealPath "$storeA/nix/store" "$path") # upper layer should still not have it (no redundant copy) -expect 1 stat $(toRealPath "$storeB/nix/store" "$path") # TODO: Check this is failing for the right reason. - # $storeB is a store URI not a directory path +expect 1 stat $(toRealPath "$storeBTop" "$path") From 2fc00ec19f8eb7ec2285135a180763d632102762 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Thu, 20 Jul 2023 11:27:28 +0100 Subject: [PATCH 16/16] Fix unbound variable error in optimise test. --- tests/overlay-local-store/optimise-inner.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/overlay-local-store/optimise-inner.sh b/tests/overlay-local-store/optimise-inner.sh index 2b778b311c8..b7994054cc5 100755 --- a/tests/overlay-local-store/optimise-inner.sh +++ b/tests/overlay-local-store/optimise-inner.sh @@ -32,7 +32,7 @@ remountOverlayfs dupFilename="${dupFileStorePath#/nix/store}" lowerPath="$storeA/$dupFileStorePath" upperPath="$storeBTop/$dupFilename" -overlayPath="$mergedStorePath/$dupFilename" +overlayPath="$storeBRoot/nix/store/$dupFilename" # Check store path exists in both layers and overlay lowerInode=$(stat -c %i "$lowerPath")