#!/bin/sh # Bounded wait for a TCP listener. Exits 0 as soon as it connects, 1 on timeout. # # Used as the FIFA17 host's ExecStartPre so the host cannot start "successfully" # while Core is absent. A TCP connect is a MEANINGFUL readiness signal here, not # a guess: openfut-core binds its listener only after it has opened the # database, run migrations and loaded the content pack — the startup log order # is `Running database migrations` -> `Loaded N cards` -> `Listening`, and the # 2026-08-22 promotion demonstrated it directly when a bind collision aborted a # Core that had already applied migration 0028. So "port open" implies # "migrations done, content loaded". # # Deliberately no retry-forever: a host that blocks indefinitely looks healthy # to a supervisor while serving nothing. It fails, and the restart policy # decides what happens next. # # usage: openfut-wait-tcp.sh set -eu HOST="${1:?host}" PORT="${2:?port}" TIMEOUT="${3:-30}" i=0 while [ "$i" -lt "$TIMEOUT" ]; do # /dev/tcp is a bash-ism; use a portable connect instead. if command -v nc >/dev/null 2>&1; then nc -z "$HOST" "$PORT" 2>/dev/null && exit 0 else python3 - "$HOST" "$PORT" <<'PY' && exit 0 import socket, sys s = socket.socket() s.settimeout(1) sys.exit(0 if s.connect_ex((sys.argv[1], int(sys.argv[2]))) == 0 else 1) PY fi i=$((i + 1)) sleep 1 done echo "openfut-wait-tcp: $HOST:$PORT did not accept connections within ${TIMEOUT}s" >&2 exit 1