mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
compose.network.yml brings up three ghcr.io/hanzoai/base:dev pods in a
quasar quorum (N=3, k=2) plus a gateway using the base-network upstream
type (shipped in hanzo/gateway). Ports 18080 (gateway), 18090-18092
(direct pod access). Kill any one base-* to exercise quorum failure
tolerance.
hack/gateway.network.json configures the gateway side of the stack:
three endpoints (GET/POST/DELETE on /api/{path}) backed by the
base-network upstream with shard_key_source=header:X-User-Id so the
dev loop doesn't require IAM/Casdoor.
hack/smoke-compose.sh is the end-to-end check: spin up, write a row
through the gateway, kill base-b, read it back, tear down. Exits 0 on
success; exit 2 documents the "Agent #1 /-/base/members not yet in
image" condition so the script is runnable pre-merge.
83 lines
2.7 KiB
Bash
Executable File
83 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# smoke-compose.sh — bring up compose.network.yml, drive a write through the
|
|
# gateway, kill a node, read it back, tear down. Exits 0 on success.
|
|
#
|
|
# Prereqs:
|
|
# - Docker + compose v2.
|
|
# - ghcr.io/hanzoai/base:dev and ghcr.io/hanzoai/gateway:latest available
|
|
# (either pulled locally or network-accessible).
|
|
#
|
|
# This script is deliberately strict: any broken rung (members endpoint not
|
|
# responding, write fails, read fails after kill) aborts with a non-zero exit
|
|
# code and a pointer to the failing assertion.
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
COMPOSE="docker compose -f compose.network.yml"
|
|
GATEWAY="http://localhost:18080"
|
|
USER="alice"
|
|
|
|
cleanup() {
|
|
echo "--- tearing down ---"
|
|
$COMPOSE down -v >/dev/null 2>&1 || true
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "--- docker compose up ---"
|
|
$COMPOSE up -d
|
|
|
|
echo "--- wait for gateway + all 3 pods healthy ---"
|
|
deadline=$((SECONDS + 60))
|
|
while [[ $SECONDS -lt $deadline ]]; do
|
|
# Any response at all (including 404/400) means gateway is listening.
|
|
if curl -s -o /dev/null -w '%{http_code}' "$GATEWAY/api/__probe" | grep -qE '^[0-9]+$'; then
|
|
# Probe each pod directly to confirm it's up.
|
|
if curl -fsS "http://localhost:18090/api/health" >/dev/null 2>&1 \
|
|
|| curl -fsS "http://localhost:18090/-/base/members" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo "--- verify /-/base/members is exposed by each pod ---"
|
|
for pod in 18090 18091 18092; do
|
|
if ! curl -fsS "http://localhost:$pod/-/base/members" | grep -q members; then
|
|
echo "FAIL: pod :$pod does not expose /-/base/members" >&2
|
|
echo "(this is Agent #1's territory — base/network package. If you're" >&2
|
|
echo " seeing this before Agent #1 lands, the image is too old.)" >&2
|
|
exit 2
|
|
fi
|
|
done
|
|
|
|
echo "--- write a row via gateway ---"
|
|
write_resp=$(curl -fsS -XPOST "$GATEWAY/api/collections/_pbc/records" \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-User-Id: $USER" \
|
|
-d '{"payload":"smoke"}')
|
|
echo "write: $write_resp"
|
|
|
|
echo "--- kill base-b to simulate a node failure ---"
|
|
$COMPOSE kill base-b
|
|
sleep 2
|
|
|
|
echo "--- read back via gateway (must still succeed with 2/3 quorum) ---"
|
|
if ! curl -fsS "$GATEWAY/api/collections/_pbc/records?filter=payload=smoke" \
|
|
-H "X-User-Id: $USER" >/dev/null; then
|
|
echo "FAIL: read after node kill did not succeed" >&2
|
|
$COMPOSE logs --tail=50 base-a base-c gateway >&2 || true
|
|
exit 3
|
|
fi
|
|
|
|
echo "--- shard_key_missing is enforced (no X-User-Id → 400) ---"
|
|
status=$(curl -s -o /dev/null -w '%{http_code}' -XPOST "$GATEWAY/api/collections/_pbc/records" \
|
|
-H "Content-Type: application/json" -d '{}')
|
|
if [[ "$status" != "400" ]]; then
|
|
echo "FAIL: expected 400 for missing shard key, got $status" >&2
|
|
exit 4
|
|
fi
|
|
|
|
echo ""
|
|
echo "--- OK: base-network compose smoke passed ---"
|