#!/usr/bin/env bash # CNPG PostgreSQL 이미지 기능 검증 — 호스트에서 bash 로 실행된다(build-hardened-image.sh 가 # `env TAG=... PLATFORM=... PG_MAJOR=... bash verify.sh` 형태로 호출한다). 이 이미지는 셸 # (`/bin/sh`)이 있으므로, 실제 점검은 컨테이너 안에서 게스트 셸 스크립트로 수행한다. # # 마지막 줄에 VERIFY-OK 를 출력하면 통과다. build-hardened-image.sh 가 그것으로 판정한다. # # 왜 이미지 디렉토리에 두나: 검증 항목은 이미지마다 다르다. 빌드 스크립트에 하드코딩하면 # 이미지가 둘 이상이 될 때 깨진다. 실제로 apt·suse 두 변종이 생겨 분리했다. # # CNPG 가 이미지에 요구하는 것(오퍼레이터 소스 기준) # - uid 26 — 다르면 오퍼레이터가 관리하는 볼륨 권한이 깨진다 # - PATH 에서 initdb/pg_ctl/postgres 를 찾을 수 있어야 한다 (경로 하드코딩 아님) # - 차트가 선언한 확장이 실제로 생성되어야 한다 set -e TAG="${TAG:?TAG 환경변수가 필요하다}" PLATFORM="${PLATFORM:-linux/amd64}" PG_MAJOR="${PG_MAJOR:?PG_MAJOR 환경변수가 필요하다 (build-hardened-image.sh 가 build.env 에서 전달)}" docker run --rm -i --platform "$PLATFORM" -e PG_MAJOR="$PG_MAJOR" --entrypoint sh "$TAG" <<'GUEST' set -e export PGDATA=/tmp/_verify export PATH="/usr/lib/postgresql/${PG_MAJOR}/bin:/usr/pgsql-${PG_MAJOR}/bin:$PATH" echo "== 실행 사용자 ==" uid=$(id -u) gid=$(id -g) gname=$(id -gn 2>/dev/null || echo '?') echo " uid=$uid gid=$gid($gname)" [ "$uid" = "26" ] || { echo "FAIL: uid=$uid — CNPG 는 26 을 요구한다"; exit 1; } # gid 는 실패시키지 않고 경고만 한다. 실측 사례: Ubuntu 베이스에서 gid 26 이 `tape` # 그룹에 선점되어 있어 postgres 가 tape 그룹으로 동작했다. 기능은 동작하지만 위생 문제다. if [ "$gname" != "postgres" ]; then echo " WARN: gid $gid 의 그룹명이 '$gname' 이다 (postgres 가 아님)" fi echo "== 바이너리 탐색 (PATH 기준) ==" for b in initdb pg_ctl postgres psql; do p=$(command -v "$b") || { echo "FAIL: $b 를 PATH 에서 찾을 수 없다"; exit 1; } echo " $b → $p" done echo "== initdb + 기동 ==" initdb -D "$PGDATA" -A trust >/dev/null pg_ctl -D "$PGDATA" -w start >/dev/null \ -o "-c shared_preload_libraries=pgaudit,pg_stat_statements -c unix_socket_directories=/tmp" psql -h /tmp -U postgres -Atc "SELECT version();" | sed 's/^/ /' echo "== 확장 생성 ==" # 차트(cnpg-cluster)가 Database CRD 로 선언하는 것과 같은 목록이다. psql -h /tmp -U postgres -q -c \ "CREATE EXTENSION pgaudit; CREATE EXTENSION vector; CREATE EXTENSION pg_stat_statements;" psql -h /tmp -U postgres -Atc \ "SELECT extname||' '||extversion FROM pg_extension ORDER BY 1;" | sed 's/^/ /' echo "== libxml2 링크 (XML 함수) ==" psql -h /tmp -U postgres -Atc \ "SELECT xml_is_well_formed_document('x');" | sed 's/^/ /' echo "== 로케일 ==" # 업스트림 standard 는 전 로케일을 포함한다. 줄어들면 정렬·비교 동작이 달라진다. n=$(psql -h /tmp -U postgres -Atc "SELECT count(*) FROM pg_collation;") echo " pg_collation: ${n}개" [ "$n" -gt 100 ] || echo " WARN: collation 이 ${n}개다 — 로케일 패키지 누락 의심" pg_ctl -D "$PGDATA" -w stop >/dev/null echo "VERIFY-OK" GUEST