Skip to content

run-testbox: count established sshd connections as activity on macOS - #19

Merged
aayushshah15 merged 1 commit into
mainfrom
aayushshah15/macos-ssh-activity
Oct 24, 2026
Merged

aayushshah15 merged 1 commit into
mainfrom
aayushshah15/macos-ssh-activity

Conversation

@aayushshah15

@aayushshah15 aayushshah15 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

An open SSH session on a macOS testbox never reset the idle timer, because the idle loop only looked for connections with ss, which macOS does not have. The loop now falls back to netstat on macOS, so an interactive session or a long rsync keeps a Mac testbox alive just like the activity marker does.

SSHD_PORT=22

ssh_connected() {
  if command -v ss >/dev/null; then
    [ -n "$(ss -Htn state established "( sport = :${SSHD_PORT} )" 2>/dev/null)" ]
  else
    netstat -an -p tcp 2>/dev/null | awk -v suffix=".${SSHD_PORT}" '
      $6 == "ESTABLISHED" && substr($4, length($4) - length(suffix) + 1) == suffix { found = 1 }
      END { exit !found }'
  fi
}

The port changes on Linux too

The old check grepped for RUNNER_SSH_PORT, which begin-testbox copies from BLACKSMITH_SSH_PORT. That is the host's public port (e.g. 64000). The host agent forwards it to port 22 in the VM: iptables DNAT on Linux and a pf rdr rule on macOS (FastActions/fa agent/vm/ssh.go calls tunnelMgr.Expose(ctx, vmID, vmIP, 22, ...); agent/tunnel/manager.go and agent/tunnel/proxy_manager.go). Inside the VM, the sshd socket's local port is always 22, so grep ":64000\b" only matched by coincidence (a peer ephemeral port that happened to equal the public port). In practice the Linux SSH signal never fired and the marker file carried all activity detection.

The new check matches what the VM sees: established sockets whose local port is 22. It ignores the runner's own outbound connections to port 22 (e.g. git over SSH to GitHub), because those have 22 as the peer port, not the local one. On Linux an open SSH session now keeps the testbox alive, which matches the existing comment's stated intent.

bash -e safety

ssh_connected only runs as an if condition, so a probe that finds nothing returns false without aborting the loop. The ss branch tests captured output instead of piping into grep -q, which under pipefail can fail on SIGPIPE even when it matched.

Validation on a real blacksmith-6vcpu-macos-26 runner: useblacksmith/web adds a copy of ssh_connected to .github/scripts/testbox-macos-check.sh, opens a TCP connection to sshd, asserts it is detected, closes it, and asserts it is no longer detected. On Linux the ss branch was checked against a held loopback connection. Do not move the v2 tag until after merge.


View with [code]smith Show before/after
Need help on this PR? Tag @codesmith-bot with what you need.

Matches macOS: open SSH session keeps testbox alive

Before, the box shut down at the 2-minute mark with the SSH session still open. After, the open session kept it alive, and it shut down 2 minutes after the last tick that saw the session.

Merge-base

macOS loop before

This PR 5661ca52

macOS loop after

Also checked · 2 match

Matches Linux: open SSH session keeps testbox alive
Matches Outbound SSH to port 22 is ignored

Proof on 5661ca52


View with [code]smith View full Proof
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled. (Staging)

macOS has no ss, so an open SSH session never reset the idle timer there.
Fall back to netstat, and match the VM's sshd port (22) instead of
RUNNER_SSH_PORT, the host's public port that iptables/pf forward to it.

Co-authored-by: Codesmith Staging <codesmith-bot@users.noreply.github.com>

Copy link
Copy Markdown
Contributor Author

Live proof on staging testboxes running this branch (5661ca52), --idle-timeout 2, with one SSH session held for 4 minutes and no other activity:

OS Last other activity SSH held Idle shutdown Run
macOS 26 (arm64) 17:54:05 17:54:10 to 17:58:10 18:00:09 https://github.com/useblacksmith/web/actions/runs/40118114495
Ubuntu 24.04 17:53:03 17:53:59 to 17:57:59 17:59:33 https://github.com/useblacksmith/web/actions/runs/40118116902

Each testbox stayed up through the whole SSH session (on main it would have stopped about 2 minutes after the last activity), then shut down within the 2-minute timeout after the session closed. Both runs passed.

@aayushshah15
aayushshah15 marked this pull request as ready for review October 24, 2026 18:03

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants