diff --git a/.gitea/workflows/rebuild.yml b/.gitea/workflows/rebuild.yml index aff2728..f30a07e 100644 --- a/.gitea/workflows/rebuild.yml +++ b/.gitea/workflows/rebuild.yml @@ -21,6 +21,10 @@ jobs: bash scripts/deploy-unraid.sh - name: Verify authenticated deployment run: | - curl -sf http://127.0.0.1:8092/health -o /dev/null - curl -sfk https://127.0.0.1:9178/ -o /dev/null - test "$(curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:9178/token)" = 401 + # CI runner loopback is not the Docker host's loopback. + host_curl() { + docker run --rm --network host --entrypoint curl hope-voice-api-voice:latest "$@" + } + host_curl -sf http://127.0.0.1:8092/health -o /dev/null + host_curl -sfk https://127.0.0.1:9178/ -o /dev/null + test "$(host_curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:9178/token)" = 401 diff --git a/scripts/deploy-unraid.sh b/scripts/deploy-unraid.sh index 2609a6f..2177ba9 100644 --- a/scripts/deploy-unraid.sh +++ b/scripts/deploy-unraid.sh @@ -15,6 +15,11 @@ if [ ! -d /mnt/user/dev/hope-voice-api/certs ]; then --mount type=bind,source=/mnt/user/dev/hope-voice-api/certs,target=/certs,readonly \ hope-voice-api-voice:latest -d /certs fi +# The runner also has its own loopback network. Probe the host namespace through +# a short-lived container, without exposing private control endpoints on the LAN. +host_curl() { + docker run --rm --network host --entrypoint curl hope-voice-api-voice:latest "$@" +} STAMP=$(date -u +%Y%m%dT%H%M%SZ) BACKUP="$ROOT/rollback/$STAMP" mkdir -p "$BACKUP" @@ -70,7 +75,7 @@ docker run -d --name hope-control --network host --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ --log-opt max-size=10m --log-opt max-file=3 hope-voice-control:latest >/dev/null for attempt in $(seq 1 30); do - if curl -sf http://127.0.0.1:8092/health -o /dev/null; then break; fi + if host_curl -sf http://127.0.0.1:8092/health -o /dev/null; then break; fi if [ "$attempt" = 30 ]; then false; fi sleep 2 done @@ -87,6 +92,6 @@ for attempt in $(seq 1 30); do if [ "$attempt" = 30 ]; then false; fi sleep 2 done -test "$(curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:9178/token)" = 401 +test "$(host_curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:9178/token)" = 401 trap - ERR printf 'Deployment healthy; rollback containers retained with suffix %s\n' "$STAMP" diff --git a/tests/unit/test_deploy_rollback.py b/tests/unit/test_deploy_rollback.py index 8fb2413..5fd4fcc 100644 --- a/tests/unit/test_deploy_rollback.py +++ b/tests/unit/test_deploy_rollback.py @@ -30,6 +30,10 @@ elif cmd=='rm': assert c['id'] not in ['original-voice','original-control'] s['containers'].remove(c);save() elif cmd=='run': + if '--entrypoint' in a: + entry=a[a.index('--entrypoint')+1] + if entry=='curl' and '%{http_code}' in a:print('401') + sys.exit(0) name=a[a.index('--name')+1] if name=='voice' and s['failure']=='run':sys.exit(9) s['containers'].append({'name':name,'id':'new-'+name,'running':True});save()