From f35e4ec46daefa73d220f2f41dd3fec92ea62482 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Thu, 18 Jun 2026 09:23:36 +0200 Subject: [PATCH] fix(migration): multiplex operator-window SSH pushes through one master connection Forgejo rate-limits rapid port-22 handshakes. The bare per-target `git push --all` + `git push --tags` opened ~22 SSH connections in rapid succession; the server refused around the 6th (voyage's tag push) with "port 22: Connection refused" (TCP-level, not auth), deterministically, on every run. Export GIT_SSH_COMMAND with ControlMaster/ControlPath/ControlPersist so all git-over-SSH reuses ONE persistent master connection (one TCP handshake for the whole rollout). Verified: 8 rapid multiplexed connections all succeed where the 6th bare connection is refused; the full 11-target rollout then completed clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../migration/run-operator-window.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/marketplace-polyrepo-migration/migration/run-operator-window.sh b/docs/marketplace-polyrepo-migration/migration/run-operator-window.sh index 7755360..d123eb2 100644 --- a/docs/marketplace-polyrepo-migration/migration/run-operator-window.sh +++ b/docs/marketplace-polyrepo-migration/migration/run-operator-window.sh @@ -56,6 +56,15 @@ command -v curl >/dev/null 2>&1 || die "curl not found" BR="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD)" [ "$BR" = "main" ] || die "catalog repo not on main (on '$BR')" +# ---- SSH connection multiplexing (REQUIRED — Forgejo rate-limits rapid port-22 handshakes) ---- +# The bare per-target `git push --all` + `git push --tags` opens 2 SSH connections per target (22 total) +# in rapid succession; Forgejo refuses around the 6th handshake ("ssh: connect to host ... port 22: +# Connection refused" — TCP-level, not auth), which killed voyage's tag push on every run. Route ALL +# git-over-SSH through ONE persistent master connection so the whole rollout costs a single TCP handshake. +# Verified: 8 rapid multiplexed connections all succeed where the 6th bare connection is refused. +# ControlPersist keeps the master alive across the inter-target validate/clone gaps. +export GIT_SSH_COMMAND="ssh -o ControlMaster=auto -o ControlPath=/tmp/polyrepo-ssh-%C -o ControlPersist=600" + mapget() { python3 -c "import json;print(json.load(open('$MAP'))['targets']['$1'].get('$2',''))"; } entry_present() {