diff --git a/src/libstore/local-overlay-store.cc b/src/libstore/local-overlay-store.cc index 9e530ed9b..c8464f64d 100644 --- a/src/libstore/local-overlay-store.cc +++ b/src/libstore/local-overlay-store.cc @@ -209,13 +209,6 @@ void LocalOverlayStore::optimiseStore() } } -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 ef377b7a6..349d9e6ed 100644 --- a/src/libstore/local-overlay-store.hh +++ b/src/libstore/local-overlay-store.hh @@ -114,8 +114,6 @@ 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/common.sh b/tests/overlay-local-store/common.sh index 2b23352ab..6bb5bc391 100644 --- a/tests/overlay-local-store/common.sh +++ b/tests/overlay-local-store/common.sh @@ -7,9 +7,13 @@ requireEnvironment () { needLocalStore "The test uses --store always so we would just be bypassing the daemon" } +addConfig () { + echo "$1" >> "$NIX_CONF_DIR/nix.conf" +} + setupConfig () { - echo "require-drop-supplementary-groups = false" >> "$NIX_CONF_DIR"/nix.conf - echo "build-users-group = " >> "$NIX_CONF_DIR"/nix.conf + addConfig "require-drop-supplementary-groups = false" + addConfig "build-users-group = " } diff --git a/tests/overlay-local-store/verify-inner.sh b/tests/overlay-local-store/verify-inner.sh index 8f8839302..de40c3d05 100755 --- a/tests/overlay-local-store/verify-inner.sh +++ b/tests/overlay-local-store/verify-inner.sh @@ -16,25 +16,51 @@ initLowerStore mountOverlayfs + +## Initialise stores for test + # Realise a derivation from the lower store to propagate paths to overlay DB nix-store --store "$storeB" --realise $drvPath # Also ensure dummy file exists in overlay DB dummyPath=$(nix-store --store "$storeB" --add ../dummy) +# Add something to the lower store that will not be propagated to overlay DB +lowerOnlyPath=$(addTextToStore "$storeA" lower-only "Only in lower store") + # Verify should be successful at this point nix-store --store "$storeB" --verify --check-contents -# Now delete one of the derivation inputs in the lower store +# Make a backup so we can repair later +backupStore="$storeVolume/backup" +mkdir "$backupStore" +tar -cC "$storeBRoot" nix | tar -xC "$backupStore" + + +## Deliberately corrupt store paths + +# 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" -# And truncate the contents of dummy file in lower store +# Truncate the contents of dummy file in lower store 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 --repair) +# Also truncate the file that only exists in lower store +truncate -s 0 "$storeA/$lowerOnlyPath" + + +## Now test that verify and repair work as expected + +# Verify overlay store without attempting to repair it +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" -<<<"$verifyOutput" grepQuiet "store does not support --verify --repair" +<<<"$verifyOutput" expectStderr 1 grepQuiet "$lowerOnlyPath" # Expect no error for corrupted lower-only path + +# Attempt to repair using backup +addConfig "substituters = $backupStore" +repairOutput=$(nix-store --store "$storeB" --verify --check-contents --repair 2>&1) +<<<"$repairOutput" grepQuiet "copying path '$inputDrvPath'" +<<<"$repairOutput" grepQuiet "copying path '$dummyPath'"