Task 001: dockerized monorepo foundation
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml"
|
||||
|
||||
BACKEND_URL="${BACKEND_URL:-http://localhost:8000}"
|
||||
RUNNER_URL="${RUNNER_URL:-http://localhost:8010}"
|
||||
FRONTEND_URL="${FRONTEND_URL:-http://localhost:3000}"
|
||||
WAIT_SECONDS="${WAIT_SECONDS:-60}"
|
||||
PYTHON_BIN="${PYTHON_BIN:-python3}"
|
||||
|
||||
cleanup() {
|
||||
docker compose -f "${COMPOSE_FILE}" down --remove-orphans >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
fetch_health() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local deadline=$((SECONDS + WAIT_SECONDS))
|
||||
local body
|
||||
|
||||
while (( SECONDS < deadline )); do
|
||||
if body="$(curl -fsS "${url}" 2>/dev/null)"; then
|
||||
printf '%s' "${body}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Timed out waiting for ${name} at ${url}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
assert_service_health() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local expected_service="$3"
|
||||
local body
|
||||
|
||||
body="$(fetch_health "${name}" "${url}")"
|
||||
HEALTH_NAME="${name}" EXPECTED_SERVICE="${expected_service}" HEALTH_BODY="${body}" "${PYTHON_BIN}" - <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
name = os.environ["HEALTH_NAME"]
|
||||
expected_service = os.environ["EXPECTED_SERVICE"]
|
||||
body = os.environ["HEALTH_BODY"]
|
||||
|
||||
try:
|
||||
payload = json.loads(body)
|
||||
except json.JSONDecodeError as error:
|
||||
print(f"{name}: expected JSON response, got: {body!r}", file=sys.stderr)
|
||||
raise SystemExit(1) from error
|
||||
|
||||
if payload.get("service") != expected_service:
|
||||
print(
|
||||
f"{name}: expected service={expected_service!r}, got {payload.get('service')!r}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise SystemExit(1)
|
||||
|
||||
if payload.get("status") != "ok":
|
||||
print(f"{name}: expected status='ok', got {payload.get('status')!r}", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
echo "${name} health ok"
|
||||
}
|
||||
|
||||
assert_backend_dependencies() {
|
||||
local body
|
||||
|
||||
body="$(fetch_health "backend dependencies" "${BACKEND_URL}/health/dependencies")"
|
||||
HEALTH_BODY="${body}" "${PYTHON_BIN}" - <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
body = os.environ["HEALTH_BODY"]
|
||||
required = ("postgres", "redis", "object_storage")
|
||||
|
||||
try:
|
||||
payload = json.loads(body)
|
||||
except json.JSONDecodeError as error:
|
||||
print(f"backend dependencies: expected JSON response, got: {body!r}", file=sys.stderr)
|
||||
raise SystemExit(1) from error
|
||||
|
||||
if payload.get("service") != "backend":
|
||||
print(
|
||||
f"backend dependencies: expected service='backend', got {payload.get('service')!r}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise SystemExit(1)
|
||||
|
||||
if payload.get("status") != "ok":
|
||||
print(
|
||||
f"backend dependencies: expected status='ok', got {payload.get('status')!r}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise SystemExit(1)
|
||||
|
||||
dependencies = payload.get("dependencies")
|
||||
if not isinstance(dependencies, dict):
|
||||
print("backend dependencies: expected dependencies object", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
failed = [name for name in required if dependencies.get(name) != "ok"]
|
||||
if failed:
|
||||
print(
|
||||
"backend dependencies: expected ok for " + ", ".join(failed),
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
echo "backend dependencies ok"
|
||||
}
|
||||
|
||||
cd "${ROOT_DIR}"
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "Starting stack with docker compose..."
|
||||
docker compose -f "${COMPOSE_FILE}" up --build -d
|
||||
|
||||
assert_service_health "backend" "${BACKEND_URL}/health" "backend"
|
||||
assert_service_health "runner" "${RUNNER_URL}/health" "runner"
|
||||
assert_service_health "frontend" "${FRONTEND_URL}/health" "frontend"
|
||||
assert_backend_dependencies
|
||||
|
||||
echo "public health smoke ok"
|
||||
Reference in New Issue
Block a user