#!/usr/bin/env bash set -euo pipefail REGISTRY_HOST="gitea.nehmer.net" OWNER="torben" IMAGE_NAME="gitea-mcp-auth-proxy" TAG="latest" USERNAME="torben" RUNTIME="" REQUIRED_LABELS=() usage() { cat <<'EOF' Usage: scripts/test-registry-image.sh [options] Pulls the published container image from the Gitea registry, starts it locally with the committed demo hashes, and verifies expected HTTP responses. Options: --tag Image tag to test (default: latest) --runtime Container runtime to use (auto-detect by default) --username Registry username (default: torben) --require-label Require image label to exist --require-label Require image label to equal a specific value -h, --help Show this help Examples: scripts/test-registry-image.sh scripts/test-registry-image.sh --tag v1.2.3 scripts/test-registry-image.sh --require-label org.opencontainers.image.source EOF } while [[ $# -gt 0 ]]; do case "$1" in --tag) TAG="${2:-}" shift 2 ;; --runtime) RUNTIME="${2:-}" shift 2 ;; --username) USERNAME="${2:-}" shift 2 ;; --require-label) REQUIRED_LABELS+=("${2:-}") shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 1 ;; esac done if [[ -z "$TAG" ]]; then echo "Tag must not be empty" >&2 exit 1 fi if [[ -z "$RUNTIME" ]]; then if command -v docker >/dev/null 2>&1; then RUNTIME="docker" elif command -v podman >/dev/null 2>&1; then RUNTIME="podman" else echo "Neither docker nor podman is available" >&2 exit 1 fi fi if ! command -v "$RUNTIME" >/dev/null 2>&1; then echo "Container runtime not found: $RUNTIME" >&2 exit 1 fi if ! command -v curl >/dev/null 2>&1; then echo "curl is required" >&2 exit 1 fi script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" repo_root="$(cd "$script_dir/.." && pwd)" hash_dir="$repo_root/demo/token-hashes" if [[ ! -d "$hash_dir" ]]; then echo "Demo hash directory not found: $hash_dir" >&2 exit 1 fi image_ref="$REGISTRY_HOST/$OWNER/$IMAGE_NAME:$TAG" container_name="authproxy-registry-test-$$" container_id="" host_port="" cleanup() { local exit_code=$? if [[ -n "$container_id" ]]; then "$RUNTIME" rm -f "$container_id" >/dev/null 2>&1 || true fi exit "$exit_code" } trap cleanup EXIT printf 'Registry password for %s@%s: ' "$USERNAME" "$REGISTRY_HOST" >&2 stty -echo IFS= read -r registry_password stty echo printf '\n' >&2 if [[ -z "$registry_password" ]]; then echo "Empty password/token is not allowed" >&2 exit 1 fi printf '%s' "$registry_password" | "$RUNTIME" login "$REGISTRY_HOST" --username "$USERNAME" --password-stdin >/dev/null unset registry_password echo "Pulling $image_ref" "$RUNTIME" pull "$image_ref" >/dev/null for required_label in "${REQUIRED_LABELS[@]}"; do label_key="$required_label" label_expected="" if [[ "$required_label" == *=* ]]; then label_key="${required_label%%=*}" label_expected="${required_label#*=}" fi label_value="$("$RUNTIME" image inspect "$image_ref" --format "{{ index .Config.Labels \"$label_key\" }}" 2>/dev/null || true)" if [[ -z "$label_value" || "$label_value" == "" ]]; then echo "Required image label missing: $label_key" >&2 exit 1 fi if [[ -n "$label_expected" && "$label_value" != "$label_expected" ]]; then echo "Image label mismatch for $label_key: expected $label_expected, got $label_value" >&2 exit 1 fi done echo "Starting container from $image_ref" container_id="$($RUNTIME run -d \ --name "$container_name" \ -p 127.0.0.1::8080 \ -e AUTH_PROXY_LISTEN_ADDR=:8080 \ -e AUTH_PROXY_TOKEN_HASHES_DIR=/token-hashes \ -e AUTH_PROXY_LOG_LEVEL=debug \ -v "$hash_dir:/token-hashes:ro" \ "$image_ref")" host_port="$($RUNTIME port "$container_id" 8080/tcp | awk -F: 'NR==1 {print $NF}')" if [[ -z "$host_port" ]]; then echo "Failed to determine mapped host port" >&2 "$RUNTIME" logs "$container_id" >&2 || true exit 1 fi base_url="http://127.0.0.1:$host_port" wait_for_health() { local attempt http_code for attempt in $(seq 1 30); do http_code="$(curl -s -o /dev/null -w '%{http_code}' "$base_url/healthz" || true)" if [[ "$http_code" == "200" ]]; then return 0 fi sleep 1 done return 1 } assert_status() { local expected=$1 local description=$2 shift 2 local http_code http_code="$(curl -s -o /dev/null -w '%{http_code}' "$@")" if [[ "$http_code" != "$expected" ]]; then echo "FAIL: $description expected $expected, got $http_code" >&2 "$RUNTIME" logs "$container_id" >&2 || true exit 1 fi echo "OK: $description -> $http_code" } if ! wait_for_health; then echo "Container did not become healthy: $image_ref" >&2 "$RUNTIME" logs "$container_id" >&2 || true exit 1 fi assert_status 200 "healthz" "$base_url/healthz" assert_status 401 "missing token" "$base_url/" assert_status 401 "wrong token" -H "Authorization: Bearer wrong" "$base_url/" assert_status 200 "demo-token-1" -H "Authorization: Bearer demo-token-1" "$base_url/" echo "Registry image test succeeded: $image_ref"