90 lines
2.9 KiB
Bash
Executable File
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."
|