fix: close internal semantic review gaps

This commit is contained in:
2026-08-08 23:27:58 +02:00
parent 43d8063922
commit 2c4534d968
18 changed files with 806 additions and 77 deletions
+133 -1
View File
@@ -3,7 +3,17 @@ set -eu
cd "$(dirname "$0")/.."
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
holder_pid=
holder_release="$tmp/holder-release"
cleanup() {
touch "$holder_release"
if [ -n "${holder_pid:-}" ]; then
kill "$holder_pid" 2>/dev/null || true
wait "$holder_pid" 2>/dev/null || true
fi
rm -rf "$tmp"
}
trap cleanup EXIT HUP INT TERM
fakebin="$tmp/bin"
mkdir "$fakebin"
@@ -28,6 +38,15 @@ run_backup() {
volume_name=$1
backup_dir=$2
output_name=$3
if [ -n "${RUN_BLOCK_READY:-}" ]; then
: >"$RUN_BLOCK_READY"
attempts=0
while [ ! -e "${RUN_BLOCK_RELEASE:?}" ]; do
attempts=$((attempts + 1))
[ "$attempts" -lt 400 ] || exit 24
sleep 0.05
done
fi
staging=$(mktemp -d "${TMPDIR:-/tmp}/fake-qdrant-backup.XXXXXX")
mkdir -p "$staging/payload"
cat >"$staging/manifest.env" <<EOF
@@ -36,12 +55,59 @@ project_name=${PROJECT_NAME:?}
volume_name=$volume_name
volume_role=qdrant-data
helper_image=${HELPER_IMAGE:?}
created_utc=2026-08-08T17:35:36Z
EOF
cp -R "$(volume_dir_for "$volume_name")"/. "$staging/payload"/
tar -C "$staging" -cf "$backup_dir/$output_name" manifest.env payload
rm -rf "$staging"
}
lock_state_root=${LOCK_ROOT:-$(dirname "${VOLUME_ROOT:?}")/locks}
mkdir -p "$lock_state_root"
if [ "$1" = create ]; then
shift
lock_name=
lock_owner=
lock_volume=
while [ "$#" -gt 0 ]; do
case "$1" in
--name) lock_name=$2; shift 2 ;;
--label)
case "$2" in
com.thothii.qdrant-operation-owner=*) lock_owner=${2#*=} ;;
com.thothii.qdrant-operation-volume=*) lock_volume=${2#*=} ;;
esac
shift 2
;;
*) shift ;;
esac
done
[ -n "$lock_name" ] && [ -n "$lock_owner" ] && [ -n "$lock_volume" ] || exit 25
state="$lock_state_root/$lock_name"
mkdir "$state" 2>/dev/null || exit 1
printf '%s\n' "$lock_owner" >"$state/owner"
printf '%s\n' "$lock_volume" >"$state/volume"
printf '%s\n' "$lock_name"
exit 0
fi
if [ "$1" = inspect ]; then
for lock_name in "$@"; do :; done
state="$lock_state_root/$lock_name"
[ -d "$state" ] || exit 1
printf '%s %s\n' "$(cat "$state/owner")" "$(cat "$state/volume")"
exit 0
fi
if [ "$1" = rm ]; then
for lock_name in "$@"; do :; done
state="$lock_state_root/$lock_name"
[ -d "$state" ] || exit 1
rm -rf "$state"
exit 0
fi
run_restore() {
volume_name=$1
backup_dir=$2
@@ -219,6 +285,7 @@ PY
backup_output="$tmp/qdrant-backup.tar"
docker_log="$tmp/docker-backup.log"
lock_name="${project}_qdrant-data-operation-lock"
PATH="$fakebin:$PATH" DOCKER_LOG="$docker_log" PROJECT_NAME="$project" VOLUME_ROOT="$volume_root" \
HELPER_IMAGE="qdrant/qdrant:v1.18.2@sha256:75eab8c4ba42096724fdcfde8b4de0b5713d529dde32f285a1f86fdcb2c9e50c" \
./scripts/vector-backup.sh --project-name "$project" --output "$backup_output" >/dev/null
@@ -231,6 +298,15 @@ tar -xOf "$backup_output" manifest.env | grep -qx "volume_name=$volume_name"
grep -q "run --rm --mount type=volume,src=$volume_name,dst=/qdrant-data,readonly --mount type=bind,src=$tmp,dst=/backup" "$docker_log"
grep -q "compose --project-name $project stop qdrant" "$docker_log"
grep -q "compose --project-name $project start qdrant" "$docker_log"
grep -q "create --name $lock_name" "$docker_log"
grep -q "rm -f $lock_name" "$docker_log"
test ! -e "$tmp/locks/$lock_name"
lock_line=$(grep -n "create --name $lock_name" "$docker_log" | sed -n '1s/:.*//p')
volume_line=$(grep -n '^volume ls ' "$docker_log" | sed -n '1s/:.*//p')
[ "$lock_line" -lt "$volume_line" ] || {
echo "backup resolved volume state before acquiring the operation lock" >&2
exit 1
}
if grep -q "volume inspect --format {{ .Mountpoint }}" "$docker_log"; then
echo "backup consulted Docker mountpoints" >&2
exit 1
@@ -240,6 +316,61 @@ if grep -q "prune" "$docker_log"; then
exit 1
fi
mkdir -p "$tmp/locks/$lock_name"
printf '%s\n' foreign-owner >"$tmp/locks/$lock_name/owner"
printf '%s\n' "$volume_name" >"$tmp/locks/$lock_name/volume"
foreign_lock_log="$tmp/foreign-lock.log"
if PATH="$fakebin:$PATH" DOCKER_LOG="$foreign_lock_log" PROJECT_NAME="$project" VOLUME_ROOT="$volume_root" \
HELPER_IMAGE="qdrant/qdrant:v1.18.2@sha256:75eab8c4ba42096724fdcfde8b4de0b5713d529dde32f285a1f86fdcb2c9e50c" \
./scripts/vector-backup.sh --project-name "$project" --output "$tmp/foreign-lock.tar" \
>"$tmp/foreign-lock.out" 2>"$tmp/foreign-lock.err"; then
echo "backup ignored a foreign operation lock" >&2
exit 1
fi
grep -q 'operation already in progress' "$tmp/foreign-lock.err"
test "$(cat "$tmp/locks/$lock_name/owner")" = foreign-owner
rm -rf "$tmp/locks/$lock_name"
holder_ready="$tmp/holder-ready"
holder_output="$tmp/holder.tar"
holder_log="$tmp/holder.log"
PATH="$fakebin:$PATH" DOCKER_LOG="$holder_log" PROJECT_NAME="$project" VOLUME_ROOT="$volume_root" \
RUN_BLOCK_READY="$holder_ready" RUN_BLOCK_RELEASE="$holder_release" \
HELPER_IMAGE="qdrant/qdrant:v1.18.2@sha256:75eab8c4ba42096724fdcfde8b4de0b5713d529dde32f285a1f86fdcb2c9e50c" \
./scripts/vector-backup.sh --project-name "$project" --output "$holder_output" >/dev/null 2>"$tmp/holder.err" &
holder_pid=$!
attempts=0
while [ ! -e "$holder_ready" ]; do
attempts=$((attempts + 1))
[ "$attempts" -lt 400 ] || { echo "lock holder did not reach copy phase" >&2; exit 1; }
sleep 0.05
done
for contender in backup restore; do
contender_log="$tmp/contender-$contender.log"
if [ "$contender" = backup ]; then
set -- ./scripts/vector-backup.sh --project-name "$project" --output "$tmp/contender.tar"
else
set -- ./scripts/vector-restore.sh --project-name "$project" --input "$backup_output" --confirm-project "$project"
fi
if PATH="$fakebin:$PATH" DOCKER_LOG="$contender_log" PROJECT_NAME="$project" VOLUME_ROOT="$volume_root" \
HELPER_IMAGE="qdrant/qdrant:v1.18.2@sha256:75eab8c4ba42096724fdcfde8b4de0b5713d529dde32f285a1f86fdcb2c9e50c" \
"$@" >"$tmp/contender-$contender.out" 2>"$tmp/contender-$contender.err"; then
echo "$contender interleaved with an active qdrant operation" >&2
exit 1
fi
grep -q 'operation already in progress' "$tmp/contender-$contender.err"
if grep -Eq '^volume (ls|inspect)|^compose .* (stop|start) qdrant|^run ' "$contender_log"; then
echo "$contender touched qdrant state after lock contention" >&2
exit 1
fi
done
touch "$holder_release"
wait "$holder_pid"
holder_pid=
test -s "$holder_output"
test ! -e "$tmp/locks/$lock_name"
existing="$tmp/existing.tar"
printf '%s' sentinel >"$existing"
if PATH="$fakebin:$PATH" DOCKER_LOG="$tmp/existing.log" PROJECT_NAME="$project" VOLUME_ROOT="$volume_root" \
@@ -392,5 +523,6 @@ fi
test "$(cat "$volume_dir/collections/demo/state.json")" = rollback-source
grep -q "compose --project-name $project stop qdrant" "$rollback_log"
grep -q "compose --project-name $project start qdrant" "$rollback_log"
test ! -e "$tmp/locks/$lock_name"
echo "qdrant backup/restore archive validation, scoped helper execution, and rollback safety passed."