#!/bin/sh set -eu cd "$(dirname "$0")/.." tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT HUP INT TERM fakebin="$tmp/bin" mkdir "$fakebin" project="thoth-task8" volume_name="${project}_qdrant-data" mountpoint="$tmp/docker-volumes/$volume_name/_data" mkdir -p "$mountpoint/collections/demo" printf '%s' before-backup >"$mountpoint/collections/demo/state.json" cat >"$fakebin/docker" <<'SH' #!/bin/sh set -eu log_file=${DOCKER_LOG:?} printf '%s\n' "$*" >>"$log_file" if [ "$1" = volume ] && [ "$2" = ls ]; then if [ "${VOLUME_LS_OUTPUT:-}" = multiple ]; then printf '%s\n%s\n' "${PROJECT_NAME}_qdrant-data" "${PROJECT_NAME}_qdrant-data-copy" exit 0 fi printf '%s\n' "${PROJECT_NAME}_qdrant-data" exit 0 fi if [ "$1" = volume ] && [ "$2" = inspect ]; then printf '%s\n' "${MOUNTPOINT:?}" exit 0 fi if [ "$1" = compose ] && [ "$2" = --project-name ]; then case "$4" in ps) if [ "${QDRANT_RUNNING:-1}" = 1 ]; then printf '%s\n' qdrant-container fi exit 0 ;; stop) exit 0 ;; start) exit 0 ;; esac fi exit 0 SH chmod 0755 "$fakebin/docker" backup_output="$tmp/qdrant-backup.tar" docker_log="$tmp/docker.log" PATH="$fakebin:$PATH" DOCKER_LOG="$docker_log" PROJECT_NAME="$project" MOUNTPOINT="$mountpoint" \ ./scripts/vector-backup.sh --project-name "$project" --output "$backup_output" >/dev/null test -s "$backup_output" tar -tf "$backup_output" | grep -q '^./collections/demo/state.json$' grep -q "volume ls --filter label=com.docker.compose.project=$project --filter label=com.docker.compose.volume=qdrant-data" "$docker_log" grep -q "compose --project-name $project ps --status running -q qdrant" "$docker_log" grep -q "compose --project-name $project stop qdrant" "$docker_log" grep -q "compose --project-name $project start qdrant" "$docker_log" existing="$tmp/existing.tar" printf '%s' sentinel >"$existing" if PATH="$fakebin:$PATH" DOCKER_LOG="$tmp/existing.log" PROJECT_NAME="$project" MOUNTPOINT="$mountpoint" \ ./scripts/vector-backup.sh --project-name "$project" --output "$existing" >"$tmp/existing.out" 2>"$tmp/existing.err"; then echo "backup overwrote an existing archive" >&2 exit 1 fi test "$(cat "$existing")" = sentinel if PATH="$fakebin:$PATH" DOCKER_LOG="$tmp/ambiguous.log" PROJECT_NAME="$project" MOUNTPOINT="$mountpoint" VOLUME_LS_OUTPUT=multiple \ ./scripts/vector-backup.sh --project-name "$project" --output "$tmp/ambiguous.tar" >"$tmp/ambiguous.out" 2>"$tmp/ambiguous.err"; then echo "backup accepted an ambiguous qdrant-data target" >&2 exit 1 fi grep -q 'exactly one qdrant-data volume' "$tmp/ambiguous.err" restore_input="$tmp/restore.tar" restore_source="$tmp/restore-source" mkdir -p "$restore_source/collections/demo" printf '%s' restored >"$restore_source/collections/demo/state.json" tar -C "$restore_source" -cf "$restore_input" . if PATH="$fakebin:$PATH" DOCKER_LOG="$tmp/restore-refuse.log" PROJECT_NAME="$project" MOUNTPOINT="$mountpoint" \ ./scripts/vector-restore.sh --project-name "$project" --input "$restore_input" --confirm-project wrong-project \ >"$tmp/restore-refuse.out" 2>"$tmp/restore-refuse.err"; then echo "restore skipped explicit project confirmation" >&2 exit 1 fi grep -q 'confirmation must match --project-name exactly' "$tmp/restore-refuse.err" test "$(cat "$mountpoint/collections/demo/state.json")" = before-backup printf '%s' modified-live >"$mountpoint/collections/demo/state.json" restore_log="$tmp/restore-ok.log" PATH="$fakebin:$PATH" DOCKER_LOG="$restore_log" PROJECT_NAME="$project" MOUNTPOINT="$mountpoint" \ ./scripts/vector-restore.sh --project-name "$project" --input "$restore_input" --confirm-project "$project" >/dev/null test "$(cat "$mountpoint/collections/demo/state.json")" = restored grep -q "compose --project-name $project stop qdrant" "$restore_log" grep -q "compose --project-name $project start qdrant" "$restore_log" grep -q "volume inspect --format {{ .Mountpoint }} $volume_name" "$restore_log" echo "qdrant backup/restore target resolution, refusal, and service-state contracts passed."