Files
ThothII/scripts/docker-smoke.sh
T

90 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
set -eu
cd "$(dirname "$0")/.."
marker="smoke-$(date +%s)-$$"
headers=""
smoke_project=${SMOKE_PROJECT:-"thothii-smoke-$(date +%s)-$$"}
keep_resources=${KEEP_SMOKE_RESOURCES:-0}
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
compose() {
docker compose --project-name "$smoke_project" --profile external "$@"
}
# Avoid colliding with a developer's existing service. Production/developer Compose still
# defaults to 8080; a published port of 0 asks Docker for a free ephemeral smoke port.
export THOTH_HTTP_PORT=${THOTH_HTTP_PORT:-0}
cleanup() {
if [ -n "$headers" ]; then rm -f "$headers"; fi
if [ "$keep_resources" = "1" ]; then
echo "Keeping smoke resources for project $smoke_project (KEEP_SMOKE_RESOURCES=1)." >&2
else
# The unique project namespace makes this safe: remove the smoke volume while leaving
# the fixed `thothii` operator project and every operator-owned volume untouched.
compose down --volumes >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT HUP INT TERM
compose config --quiet
compose up --build --wait core frontend
published=$(compose port frontend 8080)
http_port=${published##*:}
assert_health() {
health_headers=$(mktemp)
health_body=$(mktemp)
if ! curl --fail --silent --show-error --dump-header "$health_headers" \
"http://127.0.0.1:$http_port/health" >"$health_body"; then
rm -f "$health_headers" "$health_body"
return 1
fi
if ! grep -qi '^content-type: application/json' "$health_headers" ||
! jq -e 'type == "object" and keys == ["status"] and .status == "ok"' \
"$health_body" >/dev/null; then
rm -f "$health_headers" "$health_body"
return 1
fi
rm -f "$health_headers" "$health_body"
}
assert_health
# The nginx proxy must preserve streaming semantics for the backend SSE endpoint.
headers=$(mktemp)
curl --fail --silent --show-error --max-time 2 --dump-header "$headers" \
"http://127.0.0.1:$http_port/api/sessions/docker-smoke/events" \
>/dev/null 2>&1 || status=$?
status=${status:-0}
if [ "$status" -ne 0 ] && [ "$status" -ne 28 ]; then
echo "SSE probe failed with curl status $status" >&2
exit "$status"
fi
grep -qi '^content-type: text/event-stream' "$headers"
grep -qi '^cache-control: no-cache' "$headers"
rm -f "$headers"
headers=""
# Write through the named volume, restart the application, and prove persistence.
compose exec -T core sh -c 'printf "%s\n" "$1" > /data/.compose-smoke-marker' sh "$marker"
compose restart core
compose up --wait core frontend
persisted=$(compose exec -T core sh -c 'cat /data/.compose-smoke-marker')
[ "$persisted" = "$marker" ]
compose exec -T core rm -f /data/.compose-smoke-marker
assert_health
echo "Compose health, SSE proxy, and restart persistence checks passed."