mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
* fix: address pr-bug-scan validated finding from #6952 throwNodeNotFound() now re-raises AbortError when the shared signal is aborted, so a signal-cancelled node probe no longer launders into 'Node.js not found'; sequential fallback runs. * fix(ssh): make session-limited (MaxSessions=1) relay deploys actually succeed Review of #7180 verified the parent fallback end-to-end against a real MaxSessions=1 sshd and found the connect still failed. Four gaps, in order of discovery: - isSshSessionLimitError missed stock OpenSSH, which refuses session channels over MaxSessions with SSH2_OPEN_CONNECT_FAILED (2) and 'open failed' — reason 4 never matched, so the fallback never triggered. - execCommand settled aborted commands before the channel finished closing, so the sequential fallback reissued execs while sshd still counted the old session. - SshConnection.waitForSshCallback rejected aborts mid-channel-open immediately, leaking a confirmed-late channel that held the only session slot; it now settles after the late channel closes (bounded) and drains its streams so ssh2 emits 'close'. - Session channel opens now retry transient session-limit refusals (sshd frees the slot only after processing our close-ack, which the next open can beat by microseconds), and the remote orca CLI shim install is non-fatal like the managed-hook install — after the relay bridge occupies the sole session slot, raw-connection extras must degrade instead of failing the connection. Verified live against Docker sshd (OpenSSH 9.2, MaxSessions=1): fresh deploy (upload + native deps + launch), reconnect cycles, and a PTY round-trip all succeed; unrestricted-sshd regression run also passes. Co-authored-by: Orca <help@stably.ai> * Handle ssh execution aborts immediately during retry backoff or hangs - Cancel the session-limit retry delay immediately if the operation is aborted during backoff. - Limit the wait time to a 5-second grace period when aborted during a channel open that is hung and never invokes its callback, rather than waiting for the full connection timeout. --------- Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai> Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Co-authored-by: Orca <help@stably.ai>
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { isSshSessionLimitError } from './ssh-session-limit-error'
|
|
|
|
describe('isSshSessionLimitError', () => {
|
|
it('matches ssh2 open failures with the resource-shortage reason code', () => {
|
|
expect(
|
|
isSshSessionLimitError(
|
|
Object.assign(new Error('(SSH) Channel open failure: open failed'), { reason: 4 })
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
it('matches the OpenSSH MaxSessions rejection (SSH2_OPEN_CONNECT_FAILED + "open failed")', () => {
|
|
// Why: stock OpenSSH sshd refuses session channels over MaxSessions with
|
|
// reason 2, not resource-shortage — observed against OpenSSH 9.2.
|
|
expect(
|
|
isSshSessionLimitError(
|
|
Object.assign(new Error('(SSH) Channel open failure: open failed'), { reason: 2 })
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
it('matches OpenSSH mux and MaxSessions failures', () => {
|
|
expect(
|
|
isSshSessionLimitError(
|
|
new Error(
|
|
'mux_client_request_session: session request failed: Session open refused by peer'
|
|
)
|
|
)
|
|
).toBe(true)
|
|
expect(
|
|
isSshSessionLimitError(new Error('open failed: MaxSessions limit reached on remote host'))
|
|
).toBe(true)
|
|
})
|
|
|
|
it('does not match generic channel-open failures without a session-limit reason', () => {
|
|
expect(
|
|
isSshSessionLimitError(
|
|
Object.assign(new Error('(SSH) Channel open failure: open failed'), { reason: 1 })
|
|
)
|
|
).toBe(false)
|
|
expect(
|
|
isSshSessionLimitError(
|
|
Object.assign(new Error('(SSH) Channel open failure: open failed'), { reason: 3 })
|
|
)
|
|
).toBe(false)
|
|
})
|
|
|
|
it('does not match unrelated command failures', () => {
|
|
expect(
|
|
isSshSessionLimitError(new Error('Command "node" failed (exit 1): Node.js not found'))
|
|
).toBe(false)
|
|
expect(isSshSessionLimitError(new Error('channel open failure while parsing output'))).toBe(
|
|
false
|
|
)
|
|
expect(
|
|
isSshSessionLimitError(
|
|
new Error('open failed: administratively prohibited: forwarding disabled')
|
|
)
|
|
).toBe(false)
|
|
})
|
|
})
|