#!/usr/bin/env bash # apisix 이미지 기능 검증 — 호스트에서 bash 로 실행된다(build-hardened-image.sh 가 # `env TAG=... PLATFORM=... bash verify.sh` 형태로 호출한다). # # 최종 베이스가 bci-base 라 bash/coreutils/awk 가 있다 — 게스트 셸 스크립트를 그대로 # 주입한다. 단순 --help 스모크가 아니라 실제로 nginx worker 를 기동해 APISIX 라우터가 # HTTP 요청에 응답하는지까지 확인한다(standalone/yaml config, etcd 불필요) — 15개 # 커스텀 nginx 모듈 + ~90개 Lua 플러그인(lua-resty-saml 같은 C 확장 포함) 로딩까지 # 실제로 거치는 유일한 방법이다. keycloak-authz 커스텀 플러그인은 실제 Keycloak 연동이 # 필요해 이 스모크 범위 밖 — 이건 dev 클러스터 배포 검증(.claude/deploy-test-procedure.md) # 이 담당한다. # # 마지막 줄에 VERIFY-OK 를 출력하면 통과다. build-hardened-image.sh 가 그것으로 판정한다. set -e TAG="${TAG:?TAG 환경변수가 필요하다}" PLATFORM="${PLATFORM:-linux/amd64}" echo "== apisix version ==" OUT="$(docker run --rm --platform "$PLATFORM" --entrypoint sh "$TAG" -c ' export PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin /usr/bin/apisix version ')" echo " $OUT" case "$OUT" in *3.17.0*) ;; *) echo "FAIL: apisix version 출력에 3.17.0 이 없다"; exit 1 ;; esac echo "== nginx 설정 문법 검사 (init + nginx -t) ==" CONTAINER="verify-apisix-$$" docker run -d --rm --platform "$PLATFORM" --name "$CONTAINER" --entrypoint sh "$TAG" -c ' export PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin cd /usr/local/apisix export APISIX_STAND_ALONE=true cat > conf/config.yaml < conf/apisix.yaml </tmp/init.log 2>&1 /usr/local/openresty/nginx/sbin/nginx -p /usr/local/apisix -t >>/tmp/init.log 2>&1 exec /usr/local/openresty/bin/openresty -p /usr/local/apisix -g "daemon off;" ' >/dev/null trap 'docker rm -f "$CONTAINER" >/dev/null 2>&1 || true' EXIT echo "== HTTP 응답 대기 (최대 15초) ==" # curl 은 연결 자체가 실패해도 %{http_code} 로 "000" 을 찍는다 — 빈 문자열이 아니라서 # `[ -n "$CODE" ]` 만으로는 연결 실패를 통과로 오판한다(2026-08-12 실측: 파이프라인 # 첫 실행에서 "HTTP 000" 인데도 VERIFY-OK 가 나온 버그). "000" 은 명시적으로 실패로 친다. ok=0 for i in $(seq 1 15); do CODE="$(docker run --rm --platform "$PLATFORM" --network "container:$CONTAINER" curlimages/curl:latest \ -s -o /dev/null -w '%{http_code}' -m 2 http://127.0.0.1:9080/ 2>/dev/null || true)" if [ -n "$CODE" ] && [ "$CODE" != "000" ]; then ok=1; break; fi sleep 1 done if [ "$ok" != "1" ]; then echo "FAIL: 15초 내에 9080 포트가 유효한 HTTP 응답을 하지 않았다 (마지막 시도: '${CODE:-없음}')" docker logs "$CONTAINER" 2>&1 | tail -40 exit 1 fi echo " HTTP $CODE (라우트가 없어 404 가 정상 — nginx/APISIX 라우터가 실제로 요청을 처리했다는 뜻)" case "$CODE" in 404) ;; *) echo "FAIL: 예상한 404(라우트 없음)가 아니라 $CODE 가 나왔다 — 로그 확인 필요"; docker logs "$CONTAINER" 2>&1 | tail -40; exit 1 ;; esac echo "VERIFY-OK"