feat(deploy): add optional local pgvector profile
This commit is contained in:
Executable
+112
@@ -0,0 +1,112 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
smoke_project=${SMOKE_PROJECT:-"thothii-vector-smoke-$(date +%s)-$$"}
|
||||
keep_resources=${KEEP_SMOKE_RESOURCES:-0}
|
||||
secret_dir=$(mktemp -d)
|
||||
marker="local-vector-$smoke_project"
|
||||
|
||||
case "$smoke_project" in
|
||||
thothii)
|
||||
echo "SMOKE_PROJECT=thothii is reserved for the operator stack" >&2
|
||||
exit 2
|
||||
;;
|
||||
""|*[!a-z0-9_-]*|[!a-z0-9]*)
|
||||
echo "invalid SMOKE_PROJECT: use lowercase letters, digits, hyphens, or underscores" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
for secret in bootstrap migrator reader writer; do
|
||||
password="smoke-${secret}-${smoke_project}"
|
||||
printf '%s' "$password" >"$secret_dir/$secret"
|
||||
chmod 0600 "$secret_dir/$secret"
|
||||
done
|
||||
|
||||
export THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE="$secret_dir/bootstrap"
|
||||
export THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE="$secret_dir/migrator"
|
||||
export THT_VECTOR_READER_PASSWORD_SECRET_FILE="$secret_dir/reader"
|
||||
export THT_VECTOR_WRITER_PASSWORD_SECRET_FILE="$secret_dir/writer"
|
||||
export THT_VECTOR_READER_PASSWORD="smoke-reader-${smoke_project}"
|
||||
export THT_VECTOR_WRITER_PASSWORD="smoke-writer-${smoke_project}"
|
||||
|
||||
compose() {
|
||||
docker compose --project-name "$smoke_project" --profile local-vector "$@"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if [ "$keep_resources" = "1" ]; then
|
||||
echo "Keeping smoke resources for project $smoke_project (KEEP_SMOKE_RESOURCES=1)." >&2
|
||||
else
|
||||
compose down --volumes >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -rf "$secret_dir"
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
probe_vector() {
|
||||
compose exec -T core /opt/venv/bin/python - "$marker" <<'PY'
|
||||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
from tht.adapters.vector.pgvector import PgVectorStore
|
||||
from tht.config import DatabaseConfig
|
||||
from tht.ports.vector import VectorWriteRecord
|
||||
from tht.vectorstore.records import VectorRecord
|
||||
|
||||
marker = sys.argv[1]
|
||||
database = "thoth"
|
||||
host = "vector-db"
|
||||
|
||||
def credential(role: str) -> DatabaseConfig:
|
||||
return DatabaseConfig(
|
||||
host=host,
|
||||
port=5432,
|
||||
database=database,
|
||||
schema="vectors",
|
||||
user=f"thoth_vector_{role}",
|
||||
password=os.environ[f"THT_VECTOR_{role.upper()}_PASSWORD"],
|
||||
)
|
||||
|
||||
store = PgVectorStore(credential("reader"), credential("writer"), expected_dimension=768)
|
||||
health = store.health()
|
||||
assert health.ok, health
|
||||
assert health.read_reachable is True and health.write_reachable is True, health
|
||||
|
||||
record = VectorRecord(
|
||||
id=marker,
|
||||
kind="memory",
|
||||
ref=marker,
|
||||
title="Local vector persistence smoke",
|
||||
content=marker,
|
||||
metadata={"smoke": True},
|
||||
)
|
||||
embedding = [1.0] + [0.0] * 767
|
||||
store.upsert(
|
||||
"memory",
|
||||
[VectorWriteRecord(record, embedding, hashlib.sha256(marker.encode()).hexdigest())],
|
||||
)
|
||||
hits = store.search(["memory"], embedding, limit=1, kinds=["memory"])
|
||||
assert hits and hits[0].id == marker, hits
|
||||
print(f"role health, upsert, and search passed for {marker}")
|
||||
PY
|
||||
}
|
||||
|
||||
compose config --quiet
|
||||
services=$(compose config --services)
|
||||
printf '%s\n' "$services" | grep -qx vector-db
|
||||
printf '%s\n' "$services" | grep -qx vector-migrate
|
||||
|
||||
compose up --build --wait vector-migrate core
|
||||
migration_status=$(compose run --rm --no-deps vector-migrate)
|
||||
printf '%s\n' "$migration_status" | grep -q '"pending": \[\]'
|
||||
probe_vector
|
||||
|
||||
compose restart vector-db core
|
||||
compose up --wait vector-db core
|
||||
probe_vector
|
||||
|
||||
echo "Local pgvector migration, least-privilege roles, search, and restart persistence passed."
|
||||
Reference in New Issue
Block a user