Files
ThothII/scripts/vector-backup.sh
T

81 lines
2.4 KiB
Bash
Executable File

#!/bin/sh
set -eu
usage() {
echo "usage: $0 --project-name NAME --output FILE" >&2
exit 2
}
project_name=
output=
while [ "$#" -gt 0 ]; do
case "$1" in
--project-name) project_name=${2-}; shift 2 ;;
--output) output=${2-}; shift 2 ;;
*) usage ;;
esac
done
[ -n "$project_name" ] && [ -n "$output" ] || usage
[ ! -e "$output" ] || { echo "refusing to overwrite existing backup: $output" >&2; exit 2; }
output_dir=$(dirname "$output")
output_name=$(basename "$output")
[ -d "$output_dir" ] || { echo "backup destination directory does not exist" >&2; exit 2; }
resolve_volume() {
names=$(docker volume ls \
--filter "label=com.docker.compose.project=$project_name" \
--filter "label=com.docker.compose.volume=qdrant-data" \
--format '{{.Name}}')
count=$(printf '%s\n' "$names" | sed '/^$/d' | wc -l | tr -d ' ')
[ "$count" -eq 1 ] || {
echo "expected exactly one qdrant-data volume for compose project $project_name" >&2
exit 2
}
printf '%s\n' "$names" | sed -n '/./{p;q;}'
}
resolve_mountpoint() {
mountpoint=$(docker volume inspect --format '{{ .Mountpoint }}' "$1")
[ -n "$mountpoint" ] || { echo "docker did not return a qdrant-data mountpoint" >&2; exit 2; }
case "$mountpoint" in
/*) ;;
*) echo "qdrant-data mountpoint is not absolute: $mountpoint" >&2; exit 2 ;;
esac
[ -d "$mountpoint" ] || { echo "qdrant-data mountpoint is not a directory: $mountpoint" >&2; exit 2; }
printf '%s\n' "$mountpoint"
}
volume_name=$(resolve_volume)
mountpoint=$(resolve_mountpoint "$volume_name")
running_container=$(docker compose --project-name "$project_name" ps --status running -q qdrant)
restart_qdrant=0
cleanup() {
status=$?
if [ "${temporary_output:-}" ] && [ -e "${temporary_output:-}" ]; then
rm -f "$temporary_output"
fi
if [ "$restart_qdrant" -eq 1 ]; then
docker compose --project-name "$project_name" start qdrant >/dev/null
fi
exit "$status"
}
trap cleanup EXIT HUP INT TERM
if [ -n "$running_container" ]; then
docker compose --project-name "$project_name" stop qdrant >/dev/null
restart_qdrant=1
fi
umask 077
temporary_output=$(mktemp "$output_dir/.${output_name}.tmp.XXXXXX")
tar -C "$mountpoint" -cf "$temporary_output" .
if ! ln "$temporary_output" "$output"; then
echo "refusing to replace backup destination created concurrently: $output" >&2
exit 2
fi
rm -f "$temporary_output"
temporary_output=
echo "Qdrant backup written from $volume_name to $output"