2023-07-18 14:30:33 +03:00
|
|
|
#!/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
|
|
|
|
|
2023-12-11 20:30:40 +02:00
|
|
|
setupStoreDirs
|
2023-07-18 14:30:33 +03:00
|
|
|
|
|
|
|
initLowerStore
|
|
|
|
|
|
|
|
mountOverlayfs
|
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
|
|
|
|
## Initialise stores for test
|
|
|
|
|
2023-07-18 15:10:34 +03:00
|
|
|
# Realise a derivation from the lower store to propagate paths to overlay DB
|
|
|
|
nix-store --store "$storeB" --realise $drvPath
|
2023-07-18 14:30:33 +03:00
|
|
|
|
2023-07-18 15:10:34 +03:00
|
|
|
# Also ensure dummy file exists in overlay DB
|
|
|
|
dummyPath=$(nix-store --store "$storeB" --add ../dummy)
|
2023-07-18 14:30:33 +03:00
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
# Add something to the lower store that will not be propagated to overlay DB
|
|
|
|
lowerOnlyPath=$(addTextToStore "$storeA" lower-only "Only in lower store")
|
|
|
|
|
2023-07-18 15:10:34 +03:00
|
|
|
# Verify should be successful at this point
|
|
|
|
nix-store --store "$storeB" --verify --check-contents
|
2023-07-18 14:30:33 +03:00
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
# Make a backup so we can repair later
|
|
|
|
backupStore="$storeVolume/backup"
|
|
|
|
mkdir "$backupStore"
|
2023-12-11 20:55:43 +02:00
|
|
|
cp -ar "$storeBRoot/nix" "$backupStore"
|
2023-07-25 15:30:21 +03:00
|
|
|
|
|
|
|
|
|
|
|
## Deliberately corrupt store paths
|
|
|
|
|
|
|
|
# Delete one of the derivation inputs in the lower store
|
2023-07-18 15:10:34 +03:00
|
|
|
inputDrvFullPath=$(find "$storeA" -name "*-hermetic-input-1.drv")
|
|
|
|
inputDrvPath=${inputDrvFullPath/*\/nix\/store\///nix/store/}
|
|
|
|
rm -v "$inputDrvFullPath"
|
2023-07-18 14:30:33 +03:00
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
# Truncate the contents of dummy file in lower store
|
2023-07-18 15:10:34 +03:00
|
|
|
find "$storeA" -name "*-dummy" -exec truncate -s 0 {} \;
|
2023-07-18 14:30:33 +03:00
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
# Also truncate the file that only exists in lower store
|
|
|
|
truncate -s 0 "$storeA/$lowerOnlyPath"
|
|
|
|
|
2023-07-28 12:59:16 +03:00
|
|
|
# Ensure overlayfs is synchronised
|
|
|
|
remountOverlayfs
|
|
|
|
|
2023-07-25 15:30:21 +03:00
|
|
|
|
|
|
|
## 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)
|
2023-07-18 15:10:34 +03:00
|
|
|
<<<"$verifyOutput" grepQuiet "path '$inputDrvPath' disappeared, but it still has valid referrers!"
|
|
|
|
<<<"$verifyOutput" grepQuiet "path '$dummyPath' was modified! expected hash"
|
2023-07-25 15:30:21 +03:00
|
|
|
<<<"$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'"
|