fix(adapters): support macOS hosts in port-listening probe and prevent edge container termination - #647
Open
chbndrhnns wants to merge 2 commits into
Open
Conversation
…robe
On macOS hosts (such as local self-hosted servers or developer workstations),
/proc/net/tcp does not exist. The previous probe command executed `cat /proc/net/tcp 2>/dev/null; ...; true`,
which produced an empty string with exit code 0.
parseListeningPorts evaluated this as an empty socket table, returning false (instead of null),
causing waitForPortListening to conclude { listening: false, checked: true }.
Consequently, ensureContainerEdge concluded newly started edge containers failed to listen on :80,
threw an error, and executed docker rm -f openship-edge (killing the container with SIGKILL).
- Introduce buildPortProbeCommand and parsePortProbeOutput in port-listen.ts with tiered support:
1. /proc/net/tcp{,6} (Linux / containers)
2. lsof -ti tcp:PORT / lsof -ti :PORT (macOS / BSD)
3. ss -tln sport = :PORT (Linux procfs fallback)
4. __UNAVAILABLE__ emission yielding null (checked: false) when no probe tool exists
- Add unit tests covering parsePortProbeOutput across procfs, lsof, ss, sentinels, and waitForPortFree/waitForPortListening.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #646
Summary
On macOS / Darwin hosts (such as local self-hosted Openship servers or developer machines), the edge controller container (
openship-edge) was repeatedly terminated with SIGKILL (docker rm -f) during deploys, routing retries, and reconcile passes.The root cause was in
packages/adapters/src/system/port-listen.ts:cat /proc/net/tcp 2>/dev/null; cat /proc/net/tcp6 2>/dev/null; true./procdoes not exist. The command exited 0 with an empty string"".parseListeningPorts("")returned an empty set, causingprobePortListeningOnceto returnfalse(instead ofnullfor inconclusive).waitForPortListeninginterpreted this as a conclusive negative ({ listening: false, checked: true }).ensureContainerEdge's post-start verification (verifyEdgeServing) concluded port 80 failed to bind and executeddocker rm -f openship-edgein itscatchblock.Changes
packages/adapters/src/system/port-listen.ts:buildPortProbeCommand(port):/proc/net/tcp{,6}on Linux / runtime containers.lsof -ti tcp:PORT -sTCP:LISTEN/lsof -ti :PORT -sTCP:LISTENon macOS / Darwin / BSD hosts.ss -tln sport = :PORTfallback on Linux when procfs is unmounted.__UNAVAILABLE__sentinel when no probe mechanism exists on the target.parsePortProbeOutput(out, port):lsofPIDs and__LISTEN__/__FREE__sentinels.null(inconclusive /checked: false) for__UNAVAILABLE__, empty output, or command errors, preventing false-negative container deletions on unmeasurable hosts.PROC_NET_TCP_CMDexport for backwards compatibility with tests and callers.packages/adapters/src/system/port-listen.test.ts:buildPortProbeCommand.parsePortProbeOutputacross procfs, lsof single/multi PIDs,__FREE__,__LISTEN__,__UNAVAILABLE__, and empty output.waitForPortListeningandwaitForPortFreefor macOSlsofPIDs,__FREE__, and inconclusive probe handling.Verification
port-listen.tsverified across all cases (procfs, macOS lsof, ss sentinels, inconclusive output).{ listening: false, checked: true }{ listening: true, checked: true }waitForPortFree):{ free: true, checked: true }