From 0ca6346f75b69108231b37f26d520e58b0ffd444 Mon Sep 17 00:00:00 2001 From: mptyl Date: Sat, 11 Jul 2026 22:16:51 +0200 Subject: [PATCH] fix(deploy): isolate compose smoke resources --- README.md | 6 ++++- scripts/docker-smoke.sh | 43 +++++++++++++++++++++++++++--------- scripts/test-docker-smoke.sh | 19 ++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100755 scripts/test-docker-smoke.sh diff --git a/README.md b/README.md index 963169a6..15a23d91 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,8 @@ Run the end-to-end packaging check with: The smoke script validates Compose, builds and waits for both services, checks health through the frontend, verifies SSE response headers, restarts the core, and confirms `/data` survives. -Its cleanup preserves the named volume. +Each run uses a unique Compose project and removes that project's containers, network, and test +volume afterward. It never targets the fixed `thothii` operator project or its volume. Set +`SMOKE_PROJECT` to a different explicit project name for reproducible debugging, and set +`KEEP_SMOKE_RESOURCES=1` to retain that smoke project's resources for inspection; remove them +later with `docker compose --project-name "$SMOKE_PROJECT" --profile external down --volumes`. diff --git a/scripts/docker-smoke.sh b/scripts/docker-smoke.sh index 42081604..d1059528 100755 --- a/scripts/docker-smoke.sh +++ b/scripts/docker-smoke.sh @@ -3,23 +3,44 @@ set -eu cd "$(dirname "$0")/.." -compose="docker compose --profile external" 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 - # Deliberately omit --volumes: an ordinary smoke run must preserve user data. - $compose down --remove-orphans >/dev/null 2>&1 || true + 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) +compose config --quiet +compose up --build --wait core frontend +published=$(compose port frontend 8080) http_port=${published##*:} curl --fail --silent --show-error "http://127.0.0.1:$http_port/health" >/dev/null @@ -40,12 +61,12 @@ 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') +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 +compose exec -T core rm -f /data/.compose-smoke-marker curl --fail --silent --show-error "http://127.0.0.1:$http_port/health" >/dev/null echo "Compose health, SSE proxy, and restart persistence checks passed." diff --git a/scripts/test-docker-smoke.sh b/scripts/test-docker-smoke.sh new file mode 100755 index 00000000..59e9f7ae --- /dev/null +++ b/scripts/test-docker-smoke.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +cd "$(dirname "$0")/.." + +script=scripts/docker-smoke.sh +sh -n "$script" + +grep -q 'SMOKE_PROJECT' "$script" +grep -q -- '--project-name' "$script" +grep -q 'KEEP_SMOKE_RESOURCES' "$script" +grep -q 'down --volumes' "$script" + +if grep -q -- 'down --remove-orphans' "$script"; then + echo "smoke cleanup must not remove operator orphans" >&2 + exit 1 +fi + +echo "docker-smoke isolation contract passed."