fix(build-and-push): hard-timeout the SSH probe so it can't hang
All checks were successful
Test build-and-push (self-test) / Build tiny multi-arch image (push) Successful in 8s
All checks were successful
Test build-and-push (self-test) / Build tiny multi-arch image (push) Successful in 8s
ConnectTimeout only bounds the TCP handshake; wrap ssh in a 25s timeout plus keepalives so a firewall that accepts SYN then drops packets fails fast with a clear diagnostic instead of hanging the runner.
This commit is contained in:
@@ -1,9 +1,5 @@
|
|||||||
name: Test build-and-push (self-test)
|
name: Test build-and-push (self-test)
|
||||||
|
|
||||||
# Validates the build-and-push composite action end-to-end against the remote
|
|
||||||
# docker-build.haven buildx builder, using a tiny throwaway image. Runs on
|
|
||||||
# manual dispatch and whenever the action itself changes.
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
push:
|
push:
|
||||||
@@ -14,8 +10,6 @@ on:
|
|||||||
- .gitea/workflows/test-build.yaml
|
- .gitea/workflows/test-build.yaml
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# Throwaway image ref — kept separate from any real project image so this
|
|
||||||
# self-test can never clobber a production tag.
|
|
||||||
IMAGE: git.ivanch.me/ivanch/pipeline-actions-selftest
|
IMAGE: git.ivanch.me/ivanch/pipeline-actions-selftest
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -73,12 +73,30 @@ runs:
|
|||||||
|
|
||||||
# Fail fast with a real diagnostic instead of a slow buildx
|
# Fail fast with a real diagnostic instead of a slow buildx
|
||||||
# "context deadline exceeded" if the runner can't reach / auth to the
|
# "context deadline exceeded" if the runner can't reach / auth to the
|
||||||
# remote docker daemon over SSH.
|
# remote docker daemon over SSH. A hard `timeout` wrapper guarantees we
|
||||||
|
# never hang: ConnectTimeout only bounds the TCP handshake, so a
|
||||||
|
# firewall that accepts the SYN but drops later packets would otherwise
|
||||||
|
# stall SSH negotiation indefinitely.
|
||||||
echo "== probing ssh://${BUILDER_USER}@${BUILDER_HOST} =="
|
echo "== probing ssh://${BUILDER_USER}@${BUILDER_HOST} =="
|
||||||
ssh -o BatchMode=yes -o ConnectTimeout=10 \
|
if timeout 25 ssh \
|
||||||
|
-o BatchMode=yes \
|
||||||
|
-o ConnectTimeout=10 \
|
||||||
|
-o ServerAliveInterval=5 \
|
||||||
|
-o ServerAliveCountMax=2 \
|
||||||
|
-o StrictHostKeyChecking=accept-new \
|
||||||
-i ~/.ssh/id_ed25519 \
|
-i ~/.ssh/id_ed25519 \
|
||||||
"${BUILDER_USER}@${BUILDER_HOST}" \
|
"${BUILDER_USER}@${BUILDER_HOST}" \
|
||||||
'docker version --format "server={{.Server.Version}}"'
|
'docker version --format "server={{.Server.Version}}"'; then
|
||||||
|
echo "SSH probe OK"
|
||||||
|
else
|
||||||
|
rc=$?
|
||||||
|
echo "SSH probe FAILED (exit ${rc})"
|
||||||
|
if [ "${rc}" = "124" ]; then
|
||||||
|
echo "-> timed out: TCP likely opens but SSH negotiation stalls."
|
||||||
|
echo "-> Check firewall path runner -> ${BUILDER_HOST}:22 (VLAN), or MTU."
|
||||||
|
fi
|
||||||
|
exit "${rc}"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Set up remote Docker Buildx builder
|
- name: Set up remote Docker Buildx builder
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
Reference in New Issue
Block a user