diff --git a/scripts/ci/run_integration_tests.sh b/scripts/ci/run_integration_tests.sh index d61f02ca5..73f0e6285 100755 --- a/scripts/ci/run_integration_tests.sh +++ b/scripts/ci/run_integration_tests.sh @@ -43,29 +43,72 @@ bash scripts/ci/step_install_ffmpeg.sh # --- DooD模式检测:确定宿主机访问地址 --- # DooD模式下,docker run启动的容器跑在宿主机Docker上 # 需要用宿主机IP访问映射端口 -# 检测策略:host.docker.internal -> 默认网关 -> 127.0.0.1 +# 检测策略:host.docker.internal -> docker0桥接IP -> 容器IP直连 -> 默认网关 -> 127.0.0.1 detect_docker_host() { - # 1. 尝试 host.docker.internal(runner配置了--add-host时可用) + local test_port="${1:-5432}" + + # 候选IP列表 + local candidates=() + + # 1. host.docker.internal(runner配置了--add-host时可用) if python3 -c "import socket; socket.gethostbyname('host.docker.internal')" 2>/dev/null; then - echo "host.docker.internal" - return 0 + candidates+=("host.docker.internal") fi - # 2. 尝试默认网关(Docker容器默认网关即宿主机) - local gateway="" - gateway=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1) - if [ -n "$gateway" ] && [ "$gateway" != "127.0.0.1" ]; then - echo "$gateway" - return 0 + # 2. docker0 桥接网关 (172.17.0.1) + candidates+=("172.17.0.1") + + # 3. 默认网关(容器网络的网关即宿主机) + local gw="" + gw=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1) + if [ -n "$gw" ] && [ "$gw" != "127.0.0.1" ]; then + candidates+=("$gw") fi - # 3. 回退到 127.0.0.1 + # 4. 宿主机可能的IP:容器同网段的.1或.254 + local my_ip="" + my_ip=$(hostname -I 2>/dev/null | awk '{print $1}') + if [ -n "$my_ip" ]; then + # 尝试同网段的常见宿主机IP + local subnet=$(echo "$my_ip" | cut -d. -f1-3) + candidates+=("${subnet}.1") + candidates+=("${subnet}.254") + fi + + # 5. 127.0.0.1 最后尝试 + candidates+=("127.0.0.1") + + # 测试每个候选IP + for candidate in "${candidates[@]}"; do + if python3 -c " +import socket +s = socket.socket() +s.settimeout(2) +try: + s.connect(('$candidate', $test_port)) + s.close() + print('ok') +except: + pass +" 2>/dev/null | grep -q ok; then + echo "$candidate" + return 0 + fi + done + + # 都失败则返回127.0.0.1 echo "127.0.0.1" - return 0 + return 1 } +# 获取宿主机IP(先尝试用共享PG端口5433测试,再回退到其他端口) if [ -S /var/run/docker.sock ]; then - DOCKER_HOST_IP=$(detect_docker_host) + # 先用共享PG端口5433探测 + DOCKER_HOST_IP=$(detect_docker_host 5433) + if [ "$DOCKER_HOST_IP" = "127.0.0.1" ]; then + # 如果共享PG端口探测失败,说明不在DooD或共享PG不可用,再试其他端口 + DOCKER_HOST_IP=$(detect_docker_host 22) + fi echo "检测到DooD模式(/var/run/docker.sock已挂载),宿主机地址: $DOCKER_HOST_IP" else DOCKER_HOST_IP="127.0.0.1" diff --git a/scripts/ci/run_validate.sh b/scripts/ci/run_validate.sh index 16737fd5c..8f05396fb 100755 --- a/scripts/ci/run_validate.sh +++ b/scripts/ci/run_validate.sh @@ -182,48 +182,78 @@ echo "=== [8/8] Alembic migrations validation ===" # --- DooD模式检测:确定宿主机访问地址 --- # DooD模式下,docker run启动的容器跑在宿主机Docker上 # 需要用宿主机IP访问映射端口 -# 检测策略:host.docker.internal -> 默认网关 -> 127.0.0.1 +# 检测策略:host.docker.internal -> docker0桥接IP -> 容器IP直连 -> 默认网关 -> 127.0.0.1 detect_docker_host() { - # 1. 尝试 host.docker.internal(runner配置了--add-host时可用) + local test_port="${1:-5432}" + + # 候选IP列表 + local candidates=() + + # 1. host.docker.internal(runner配置了--add-host时可用) if python3 -c "import socket; socket.gethostbyname('host.docker.internal')" 2>/dev/null; then - # 确认端口可达性(用一个常用端口快速检测) + candidates+=("host.docker.internal") + fi + + # 2. docker0 桥接网关 (172.17.0.1) + candidates+=("172.17.0.1") + + # 3. 默认网关(容器网络的网关即宿主机) + local gw="" + gw=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1) + if [ -n "$gw" ] && [ "$gw" != "127.0.0.1" ]; then + candidates+=("$gw") + fi + + # 4. 宿主机可能的IP:容器同网段的.1或.254 + local my_ip="" + my_ip=$(hostname -I 2>/dev/null | awk '{print $1}') + if [ -n "$my_ip" ]; then + # 尝试同网段的常见宿主机IP + local subnet=$(echo "$my_ip" | cut -d. -f1-3) + candidates+=("${subnet}.1") + candidates+=("${subnet}.254") + fi + + # 5. 127.0.0.1 最后尝试 + candidates+=("127.0.0.1") + + # 测试每个候选IP + for candidate in "${candidates[@]}"; do if python3 -c " import socket s = socket.socket() -s.settimeout(1) +s.settimeout(2) try: - s.connect(('host.docker.internal', 5433)) + s.connect(('$candidate', $test_port)) s.close() print('ok') except: - # 端口不通不代表host不对,可能只是没服务 - print('ok') -" 2>/dev/null; then - echo "host.docker.internal" + pass +" 2>/dev/null | grep -q ok; then + echo "$candidate" return 0 fi - fi + done - # 2. 尝试默认网关(Docker容器默认网关即宿主机) - local gateway="" - gateway=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1) - if [ -n "$gateway" ] && [ "$gateway" != "127.0.0.1" ]; then - echo "$gateway" - return 0 - fi - - # 3. 回退到 127.0.0.1 + # 都失败则返回127.0.0.1 echo "127.0.0.1" - return 0 + return 1 } +# 获取宿主机IP(先尝试用共享PG端口5433测试,再回退到其他端口) if [ -S /var/run/docker.sock ]; then - PG_HOST=$(detect_docker_host) - echo "检测到DooD模式(/var/run/docker.sock已挂载),宿主机地址: $PG_HOST" + # 先用共享PG端口5433探测 + DOCKER_HOST_IP=$(detect_docker_host 5433) + if [ "$DOCKER_HOST_IP" = "127.0.0.1" ]; then + # 如果共享PG端口探测失败,说明不在DooD或共享PG不可用,再试其他端口 + DOCKER_HOST_IP=$(detect_docker_host 22) + fi + echo "检测到DooD模式(/var/run/docker.sock已挂载),宿主机地址: $DOCKER_HOST_IP" else - PG_HOST="127.0.0.1" + DOCKER_HOST_IP="127.0.0.1" echo "非DooD模式,使用 127.0.0.1" fi +PG_HOST="$DOCKER_HOST_IP" echo "PG host: $PG_HOST" # 指数退避TCP连接检查函数