From 4b68729a8a9d0af293abcb3a093f49f59d10b4be Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 11 Nov 2026 10:12:49 -0500 Subject: [PATCH] fix(ci): find the docker host without `ip` in the act_runner job image (#860) catthehacker/ubuntu:act-latest ships no iproute2, so fixture_host() fell back to 127.0.0.1 inside the job container and every published-port fixture timed out (QuestDB is the first one probed over the network). Read the default gateway from /proc/net/route in plain bash, warn when none is found, and log the chosen host. Verified in that image on a user-defined network: gateway parsed, published port 200. Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk --- scripts/ci/integration-fixtures.sh | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/ci/integration-fixtures.sh b/scripts/ci/integration-fixtures.sh index 4a4a8effd..41ff32bf8 100755 --- a/scripts/ci/integration-fixtures.sh +++ b/scripts/ci/integration-fixtures.sh @@ -42,10 +42,30 @@ questdb_image() { echo "$img" } +# The job container's default gateway, read from /proc/net/route (#860): the act_runner job image +# (catthehacker/ubuntu:act-latest) ships no `ip`, so the old `ip route` probe silently fell back to 127.0.0.1 +# inside the container and every published-port fixture (QuestDB first) timed out. +default_gateway() { + if command -v ip >/dev/null 2>&1; then + ip route | awk '/^default/{print $3; exit}'; return + fi + # Columns: Iface Destination Gateway ...; the default route has Destination 00000000. Gateway is little-endian hex. + # Plain bash (no gawk strtonum: the image's awk may be mawk). + local iface dest gw _ + [ -r /proc/net/route ] || return 0 + while read -r iface dest gw _; do + if [ "$dest" = "00000000" ] && [ "$gw" != "00000000" ] && [ ${#gw} -eq 8 ]; then + echo "$((16#${gw:6:2})).$((16#${gw:4:2})).$((16#${gw:2:2})).$((16#${gw:0:2}))"; return 0 + fi + done < /proc/net/route +} + fixture_host() { if [ -n "${FIXTURE_HOST:-}" ]; then echo "$FIXTURE_HOST"; return; fi - if [ -f /.dockerenv ] && command -v ip >/dev/null 2>&1; then - ip route | awk '/^default/{print $3; exit}'; return + if [ -f /.dockerenv ]; then + local gw; gw="$(default_gateway)" + if [ -n "$gw" ]; then echo "$gw"; return; fi + echo "WARNING: in a container but no default gateway found; falling back to 127.0.0.1" >&2 fi echo 127.0.0.1 } @@ -88,6 +108,7 @@ up() { < "$ROOT/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.IntegrationTests/Docker/postgres/seed-pg.sql" >/dev/null echo "seeded: postgres" + echo "fixture host: $(fixture_host) (in container: $([ -f /.dockerenv ] && echo yes || echo no))" local sqlcmd=/opt/mssql-tools18/bin/sqlcmd wait_for "sql server" 300 docker exec otopcua-ci-mssql "$sqlcmd" -C -S localhost -U sa -P "$SA_PASSWORD" -Q 'SELECT 1' wait_for "questdb" 120 curl -fsS "http://$(fixture_host):$QDB_HTTP_PORT/exec?query=select%201"