Files
CosmicClash/scripts/verify_kind_agones.sh
T
2026-09-01 17:43:35 +01:00

105 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Disposable integration gate for multiplayer-next.md §8.49. This deliberately
# does not touch an existing cluster: kind creates an isolated cluster and the
# EXIT trap removes only that named cluster.
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$root_dir"
cluster_name="${KIND_CLUSTER_NAME:-cosmic-clash-agones-smoke}"
agones_version="${AGONES_VERSION:-1.49.0}"
game_server_image="${GAME_SERVER_IMAGE:-cosmic-clash-game-server:kind}"
kind_node_image="${KIND_NODE_IMAGE:-kindest/node:v1.33.1}"
work_dir="$(mktemp -d "${TMPDIR:-/tmp}/cosmic-clash-agones.XXXXXX")"
cleanup() {
local status=$?
kind delete cluster --name "$cluster_name" >/dev/null 2>&1 || true
rm -rf "$work_dir"
exit "$status"
}
trap cleanup EXIT
for tool in docker kind kubectl helm; do
command -v "$tool" >/dev/null 2>&1 || {
echo "8.49 requires '$tool'; install Docker, kind, kubectl, and Helm to run the disposable gate" >&2
exit 2
}
done
if ! docker info >/dev/null 2>&1; then
echo "8.49 requires a running Docker daemon" >&2
exit 2
fi
kind delete cluster --name "$cluster_name" >/dev/null 2>&1 || true
if ! docker image inspect "$game_server_image" >/dev/null 2>&1; then
echo "Building $game_server_image from the pinned game-server target"
docker build --target game-server -t "$game_server_image" .
fi
kind create cluster --name "$cluster_name" --image "$kind_node_image" --wait 120s
kind load docker-image "$game_server_image" --name "$cluster_name"
helm repo add agones https://agones.dev/chart/stable >/dev/null
helm repo update >/dev/null
helm upgrade --install agones agones/agones \
--namespace agones-system --create-namespace \
--version "$agones_version" \
--set agones.crds.cleanup.enabled=true \
--set agones.controller.replicas=1 \
--set agones.extensions.replicas=1 \
--set agones.allocator.replicas=1 \
--wait --timeout 5m
kubectl wait --for=condition=available deployment/agones-controller \
-n agones-system --timeout=180s
kubectl wait --for=condition=available deployment/agones-allocator \
-n agones-system --timeout=180s
# The base Fleet intentionally carries a release-time digest placeholder. For
# this isolated run only, replace that exact placeholder with the image loaded
# into kind. No repository manifest is modified and no mutable image is used
# outside the disposable cluster.
sed "s|ghcr.io/cosmic-clash/game-server@sha256:$(printf '0%.0s' {1..64})|$game_server_image|" \
deploy/k8s/base/fleet.yaml > "$work_dir/fleet.yaml"
kubectl apply -f deploy/k8s/base/namespace.yaml
kubectl -n cosmic-clash create secret generic cosmic-clash-game-server \
--from-literal=drain-token=kind-smoke-drain-token \
--from-literal=join-signing-key=kind-smoke-signing-key \
--dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f deploy/k8s/base/service-accounts.yaml
kubectl apply -f "$work_dir/fleet.yaml"
kubectl wait --for=jsonpath='{.status.ready}'=2 \
fleet/cosmic-clash-game -n cosmic-clash --timeout=5m
cat > "$work_dir/allocation.yaml" <<'EOF'
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
metadata:
generateName: cosmic-clash-smoke-
namespace: cosmic-clash
spec:
fleet:
name: cosmic-clash-game
EOF
kubectl create -f "$work_dir/allocation.yaml" -o json > "$work_dir/allocation.json"
python3 - "$work_dir/allocation.json" <<'PY'
import json
import sys
doc = json.load(open(sys.argv[1], encoding="utf-8"))
status = doc.get("status", {})
if status.get("state") != "Allocated":
raise SystemExit(f"allocation state is {status.get('state')!r}, expected 'Allocated'")
ports = status.get("gameServer", {}).get("status", {}).get("ports", [])
if not ports or not any(p.get("port", 0) > 0 and p.get("port") != 7777 for p in ports):
raise SystemExit(f"allocation did not return a dynamic UDP port: {ports!r}")
print("8.49 PASS: Fleet became ready and allocation returned a dynamic UDP port")
PY