22set -euo pipefail
33
44# Idempotent waiter for emulator services.
5- # Usage: bash scripts/wait-for-services.sh [--default <sec>] [--a2a <sec>]
5+ # Usage: bash scripts/wait-for-services.sh [--default <sec>] [--a2a <sec>] [--postgres <sec>]
66
77DEFAULT_WAIT=60
88A2A_WAIT=180
9+ POSTGRES_WAIT=" "
910
1011while [[ $# -gt 0 ]]; do
1112 case " $1 " in
1213 --default)
1314 DEFAULT_WAIT=" ${2:- 60} " ; shift 2 ;;
1415 --a2a)
1516 A2A_WAIT=" ${2:- 180} " ; shift 2 ;;
17+ --postgres)
18+ POSTGRES_WAIT=" ${2:- 120} " ; shift 2 ;;
1619 * )
1720 echo " Unknown argument: $1 " >&2 ; exit 2 ;;
1821 esac
1922done
2023
24+ # Use POSTGRES_WAIT if set, otherwise use DEFAULT_WAIT
25+ POSTGRES_WAIT=" ${POSTGRES_WAIT:- $DEFAULT_WAIT } "
26+
2127echo " Waiting for emulator services..."
2228
2329wait_http () {
2430 local name=" $1 " ; shift
2531 local url=" $1 " ; shift
2632 local max=" ${1:- $DEFAULT_WAIT } "
2733 echo " - Waiting for ${name} at ${url} "
28- for i in $( seq 1 " $max " ) ; do
34+ for _ in $( seq 1 " $max " ) ; do
2935 local code
3036 code=$( curl -s -o /dev/null -w " %{http_code}" " $url " || true)
3137 if [[ " $code " =~ ^2| 3 ]]; then
@@ -44,8 +50,8 @@ wait_tcp() {
4450 local port=" $1 " ; shift
4551 local max=" ${1:- $DEFAULT_WAIT } "
4652 echo " - Waiting for ${name} at ${host} :${port} "
47- for i in $( seq 1 " $max " ) ; do
48- if (echo > /dev/tcp/${host} /${port} ) > /dev/null 2>&1 ; then
53+ for _ in $( seq 1 " $max " ) ; do
54+ if (echo > " /dev/tcp/${host} /${port} " ) > /dev/null 2>&1 ; then
4955 echo " ${name} is ready"
5056 return 0
5157 fi
@@ -55,6 +61,63 @@ wait_tcp() {
5561 return 1
5662}
5763
64+ wait_postgres () {
65+ local name=" $1 " ; shift
66+ local host=" $1 " ; shift
67+ local port=" $1 " ; shift
68+ local max=" ${1:- $DEFAULT_WAIT } "
69+ echo " - Waiting for ${name} at ${host} :${port} "
70+
71+ local restart_count=0
72+ for _ in $( seq 1 " $max " ) ; do
73+ # Check container status
74+ local container_status
75+ container_status=$( docker inspect -f ' {{.State.Status}}' postgres-18 2> /dev/null || echo " not-found" )
76+
77+ case " $container_status " in
78+ " running" )
79+ # Container is running, check if PostgreSQL is ready
80+ if docker exec postgres-18 pg_isready -U postgres > /dev/null 2>&1 ; then
81+ echo " ${name} is ready"
82+ return 0
83+ fi
84+ restart_count=0
85+ ;;
86+ " restarting" )
87+ restart_count=$(( restart_count + 1 ))
88+ if [[ $restart_count -ge 5 ]]; then
89+ echo " ERROR: ${name} is in restart loop" >&2
90+ echo " Container logs (last 30 lines):" >&2
91+ docker logs postgres-18 --tail 30 2>&1 >&2 || true
92+ return 1
93+ fi
94+ ;;
95+ " exited" |" dead" )
96+ echo " ERROR: ${name} container has stopped (status: ${container_status} )" >&2
97+ echo " Container logs (last 30 lines):" >&2
98+ docker logs postgres-18 --tail 30 2>&1 >&2 || true
99+ return 1
100+ ;;
101+ " not-found" )
102+ echo " ERROR: postgres-18 container not found" >&2
103+ docker ps --all --filter " name=postgres-18" >&2
104+ return 1
105+ ;;
106+ esac
107+
108+ sleep 2
109+ done
110+
111+ # Debug: show final state
112+ echo " ERROR: ${name} not ready in time" >&2
113+ echo " Container status: $( docker inspect -f ' {{.State.Status}}' postgres-18 2> /dev/null || echo ' unknown' ) " >&2
114+ echo " Last pg_isready output:" >&2
115+ docker exec postgres-18 pg_isready -U postgres 2>&1 >&2 || true
116+ echo " Container logs (last 30 lines):" >&2
117+ docker logs postgres-18 --tail 30 2>&1 >&2 || true
118+ return 1
119+ }
120+
58121wait_http " Firebase UI" " http://localhost:4000" " $DEFAULT_WAIT "
59122wait_http " Elasticsearch" " http://localhost:9200/_cluster/health" " $DEFAULT_WAIT "
60123wait_http " Qdrant" " http://localhost:6333/healthz" " $DEFAULT_WAIT "
@@ -65,6 +128,6 @@ wait_http "MLflow" "http://localhost:5252/" "$DEFAULT_WAIT"
65128wait_tcp " Spanner gRPC" localhost 9010 " $DEFAULT_WAIT "
66129wait_tcp " pgAdapter" localhost " ${PGADAPTER_PORT:- 55432} " " $DEFAULT_WAIT "
67130wait_tcp " Bigtable Emulator" localhost 8086 " $DEFAULT_WAIT "
68- wait_tcp " PostgreSQL 18" localhost " ${POSTGRES_PORT:- 5433} " " $DEFAULT_WAIT "
131+ wait_postgres " PostgreSQL 18" localhost " ${POSTGRES_PORT:- 5433} " " $POSTGRES_WAIT "
69132
70133echo " All targeted services reported ready."
0 commit comments