mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
refactor(ssh): import the system-ssh and ssh -G modules directly, not through re-export shims (#30255)
Deletes ssh-system-fallback.ts and the re-export lines in ssh-config-parser.ts, ssh-connection.ts, system-ssh-file-binary-transfer.ts and ssh-remote-powershell.ts; importers name the real modules. SshConnection tests mock each real module, keeping the parser stub that holds ~/.ssh/config out.
This commit is contained in:
@@ -6349,7 +6349,7 @@
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/shared/browser-client-host-protocol.test.ts src/main/browser/browser-client-host-attach-request.test.ts src/main/browser/browser-client-network-route-registry.test.ts src/main/browser/paired-runtime-browser-client-host-composition.test.ts src/main/browser/paired-runtime-browser-client-host.test.ts src/main/browser/paired-runtime-browser-client-host-reconnect.test.ts src/main/browser/paired-runtime-browser-host-lease.test.ts src/main/browser/paired-runtime-browser-host-lease-reconnect.test.ts src/main/browser/browser-host-lease-reconnect-delay.test.ts src/main/browser/paired-runtime-browser-network-route.test.ts src/main/runtime/browser-host/browser-host-command-ledger.test.ts src/main/runtime/browser-host/browser-host-command-ledger-capacity.test.ts src/main/runtime/browser-host/browser-host-lease-placement-retirement.test.ts src/main/runtime/browser-host/browser-host-lease-registry.test.ts src/main/runtime/runtime-rpc-browser-host-admission.test.ts src/main/runtime/rpc/methods/browser-client-host.test.ts",
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/browser/browser-client-network-route-registry.test.ts src/main/browser/paired-runtime-browser-client-host-composition.test.ts src/main/browser/paired-runtime-browser-client-host-registry.test.ts src/main/browser/paired-runtime-browser-client-host-runtime.test.ts src/main/browser/browser-client-page-command-executor.test.ts src/main/browser/browser-session-startup.test.ts src/main/ipc/runtime-environments-subscription-teardown.test.ts",
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/browser-host-command-ledger.test.ts src/main/runtime/browser-host/browser-host-command-ledger-capacity.test.ts src/main/runtime/browser-host/browser-host-lease-registry.test.ts src/main/runtime/rpc/methods/browser-client-host.test.ts",
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/browser-host-lease-registry.test.ts src/main/browser/browser-network-deferred-socket.test.ts src/main/browser/browser-network-execution-route.test.ts src/main/browser/paired-runtime-browser-network-route.test.ts src/main/runtime/rpc/methods/browser-network-tunnel.test.ts src/main/browser/ssh-browser-network-execution-route.test.ts src/main/browser/system-ssh-socks-client-socket.test.ts src/main/ssh/system-ssh-dynamic-forward-process.test.ts src/shared/browser-client-host-protocol.test.ts src/main/ssh/system-ssh-forward-process.test.ts src/main/ssh/ssh-system-fallback.test.ts src/main/ssh/ssh-port-forward.test.ts",
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/browser-host/browser-host-lease-registry.test.ts src/main/browser/browser-network-deferred-socket.test.ts src/main/browser/browser-network-execution-route.test.ts src/main/browser/paired-runtime-browser-network-route.test.ts src/main/runtime/rpc/methods/browser-network-tunnel.test.ts src/main/browser/ssh-browser-network-execution-route.test.ts src/main/browser/system-ssh-socks-client-socket.test.ts src/main/ssh/system-ssh-dynamic-forward-process.test.ts src/shared/browser-client-host-protocol.test.ts src/main/ssh/system-ssh-forward-process.test.ts src/main/ssh/system-ssh-operations.test.ts src/main/ssh/ssh-port-forward.test.ts",
|
||||
"ORCA_RUN_DOCKER_SSH_BROWSER_E2E=1 pnpm exec vitest run --config config/vitest.config.ts tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts",
|
||||
"ORCA_RUN_DOCKER_SSH_BROWSER_E2E=1 node_modules/.bin/vitest run --config config/vitest.config.ts tests/e2e/ssh-browser-network-execution-route.docker.unit.test.ts"
|
||||
],
|
||||
|
||||
@@ -5802,7 +5802,7 @@
|
||||
"src/main/ssh/ssh-request-outcome-verdict.test.ts": 37,
|
||||
"src/main/ssh/ssh-security-key-identity.test.ts": 147,
|
||||
"src/main/ssh/ssh-session-limit-error.test.ts": 27,
|
||||
"src/main/ssh/ssh-system-fallback.test.ts": 275,
|
||||
"src/main/ssh/system-ssh-operations.test.ts": 275,
|
||||
"src/main/ssh/ssh-system-transport.integration.test.ts": 277,
|
||||
"src/main/ssh/ssh-target-id-migration.test.ts": 46,
|
||||
"src/main/ssh/ssh-target-orcad-claims.test.ts": 306,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SshConnectionCallbacks } from '../ssh/ssh-connection'
|
||||
import type { SshConnectionCallbacks } from '../ssh/ssh-connection-utils'
|
||||
import type { SshConnectionState } from '../../shared/ssh-types'
|
||||
import { isSshHostCensusInFlight } from '../ssh/ssh-connection-attribution'
|
||||
import { clearSshCredentialDeclined, isSshCredentialDeclined } from '../ssh/ssh-credential-decline'
|
||||
|
||||
@@ -21,7 +21,8 @@ import {
|
||||
REMOTE_NODE_RUNTIME_SELFTEST_FAILED,
|
||||
REMOTE_NODE_RUNTIME_VERIFIED_MARKER
|
||||
} from './orcad-remote-node-runtime-report'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
|
||||
function windowsPath(...segments: string[]): string {
|
||||
return segments
|
||||
|
||||
@@ -22,7 +22,7 @@ import type { OrcadHostTransport } from './orcad-host-transport'
|
||||
import { execCommand, isUnconfirmedSshCommandTermination } from './ssh-relay-exec-command'
|
||||
import { RELAY_REMOTE_DIR } from './relay-protocol'
|
||||
import { joinRemotePath, remoteDirname, type RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import { ORCAD_WINDOWS_COMMAND_LINE_UNSAFE_CODE } from '../orcad/orcad-host-unavailable'
|
||||
import {
|
||||
ORCAD_WINDOWS_HOST_SCRIPT,
|
||||
|
||||
@@ -24,7 +24,8 @@ import {
|
||||
} from './remote-node-runtime-store-inventory'
|
||||
import { RELAY_REMOTE_DIR } from './relay-protocol'
|
||||
import { isWindowsRemoteHost, joinRemotePath, type RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
|
||||
const REPARSE = '[IO.FileAttributes]::ReparsePoint'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { existsSync, readFileSync } from 'node:fs'
|
||||
import { utils, type BaseAgent, type ParsedKey } from 'ssh2'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import { createIdentityFilteredAgent } from './ssh-agent-identity-filter'
|
||||
import { resolveSshConfigHomePath } from './ssh-config-path-expansion'
|
||||
import { isOpenSshConfigBackedTarget } from './system-ssh-args'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { join } from 'node:path'
|
||||
import { parseSshConfig, sshConfigHostsToTargets, parseSshGOutput } from './ssh-config-parser'
|
||||
import { parseSshConfig, sshConfigHostsToTargets } from './ssh-config-parser'
|
||||
import { parseSshGOutput } from './ssh-g-config-resolution'
|
||||
import { searchSshConfigHosts } from './ssh-config-host-picker'
|
||||
|
||||
const sshConfigHostsToSummaries = (
|
||||
|
||||
@@ -4,7 +4,6 @@ import { homedir } from 'node:os'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import { expandSshConfigIncludes } from './ssh-config-include-expander'
|
||||
import { resolveSshConfigHomePath } from './ssh-config-path-expansion'
|
||||
export { parseSshGOutput, resolveWithSshG, type SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
|
||||
export type SshConfigHost = {
|
||||
host: string
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import { runProcess } from '@orca/process-host'
|
||||
|
||||
vi.mock('os', () => ({
|
||||
|
||||
@@ -16,14 +16,27 @@ import {
|
||||
walkInitialAuthLadder
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).createSsh2Module())
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -31,6 +44,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -9,8 +9,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -18,6 +31,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
beforeEach(resetSshConnectionMocks)
|
||||
afterEach(() => {
|
||||
|
||||
@@ -14,8 +14,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -23,6 +36,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -4,14 +4,27 @@ import { resetSshConnectionMocks, spawnSystemSshCommandMock } from './ssh-connec
|
||||
import { createCallbacks, createResolvedConfig, createTarget } from './ssh-connection-test-fixtures'
|
||||
import type { createSystemCommandChannel } from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).createSsh2Module())
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -19,6 +32,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -2,22 +2,34 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'
|
||||
import { resetSshConnectionMocks } from './ssh-connection-test-harness'
|
||||
import { createCallbacks, createResolvedConfig, createTarget } from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import {
|
||||
downloadFileViaSystemSsh,
|
||||
uploadDirectoryViaSystemSsh,
|
||||
uploadFileViaSystemSsh,
|
||||
writeBufferViaSystemSsh,
|
||||
writeFileViaSystemSsh
|
||||
} from './ssh-system-fallback'
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
import { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import { getRemoteHostPlatform } from './ssh-remote-platform'
|
||||
|
||||
vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).createSsh2Module())
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -25,6 +37,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -12,12 +12,11 @@ import {
|
||||
import type { RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import {
|
||||
downloadFileViaSystemSsh,
|
||||
uploadDirectoryViaSystemSsh,
|
||||
uploadFileViaSystemSsh,
|
||||
writeBufferViaSystemSsh,
|
||||
writeFileViaSystemSsh,
|
||||
type SystemSshBuildArgsOptions
|
||||
} from './ssh-system-fallback'
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
import { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import type { SystemSshBuildArgsOptions } from './system-ssh-args'
|
||||
|
||||
export type SshRemoteFileOptions = {
|
||||
hostPlatform?: RemoteHostPlatform
|
||||
|
||||
@@ -7,14 +7,27 @@ import {
|
||||
createTarget
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).createSsh2Module())
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -22,6 +35,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -17,14 +17,27 @@ import {
|
||||
createTarget
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).createSsh2Module())
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -32,6 +45,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:f
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
// Type-only, so it is erased before vi.mock's hoisted factory runs.
|
||||
import type * as SshConfigParser from './ssh-config-parser'
|
||||
import type * as SshGConfigResolution from './ssh-g-config-resolution'
|
||||
import type * as Ssh2 from 'ssh2'
|
||||
|
||||
const VALID_ED25519_HOST_KEY = Buffer.from(
|
||||
@@ -76,8 +76,8 @@ vi.mock('ssh2', async (importOriginal) => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('./ssh-config-parser', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshConfigParser>()),
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshGConfigResolution>()),
|
||||
resolveWithSshG: vi.fn(async () => null)
|
||||
}))
|
||||
|
||||
|
||||
@@ -10,8 +10,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -19,6 +32,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
const UNIDENTIFIABLE_HOST_KEY = Buffer.from('not-a-real-host-key-blob')
|
||||
|
||||
|
||||
@@ -7,8 +7,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -16,6 +29,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnectionManager', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -17,8 +17,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -26,6 +39,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
const authFailure = (): Error => new Error('All configured authentication methods failed')
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { SshTarget, SshConnectionState } from '../../shared/ssh-types'
|
||||
import {
|
||||
SshConnection,
|
||||
type SshCachedCredentials,
|
||||
type SshConnectionCallbacks
|
||||
} from './ssh-connection'
|
||||
import { SshConnection, type SshCachedCredentials } from './ssh-connection'
|
||||
import type { SshConnectionCallbacks } from './ssh-connection-utils'
|
||||
import { recordSshConnectionOpened, recordSshConnectionReused } from './ssh-connection-attribution'
|
||||
import { createSshCredentialDeclinedError, isSshCredentialDeclined } from './ssh-credential-decline'
|
||||
import { createSshUserDisconnectedError, isSshUserDisconnected } from './ssh-user-disconnect'
|
||||
|
||||
@@ -15,8 +15,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -24,6 +37,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
// ssh2's exact shape when TCP connects but the socket closes before the server banner.
|
||||
const preBannerLoss = (): Error =>
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
createTarget
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import { CONNECT_TIMEOUT_MS, RECONNECT_BACKOFF_MS } from './ssh-connection-utils'
|
||||
import { MIN_SSH_RELAY_GRACE_PERIOD_SECONDS } from '../../shared/ssh-types'
|
||||
|
||||
@@ -25,8 +25,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -34,6 +47,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -7,6 +7,10 @@ import { mkdtempSync, realpathSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type * as SystemSshArgs from './system-ssh-args'
|
||||
import type * as SystemSshFileBinaryTransfer from './system-ssh-file-binary-transfer'
|
||||
import type * as SystemSshFileTransfer from './system-ssh-file-transfer'
|
||||
import type * as SshGConfigResolution from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('ssh2', () => ({
|
||||
BaseAgent: class {},
|
||||
@@ -15,25 +19,34 @@ vi.mock('ssh2', () => ({
|
||||
utils: { parseKey: vi.fn() }
|
||||
}))
|
||||
|
||||
vi.mock('./ssh-system-fallback', () => ({
|
||||
getOrcaControlSocketPath: vi.fn().mockReturnValue(null),
|
||||
spawnSystemSsh: vi.fn(),
|
||||
spawnSystemSshCommand: vi.fn(),
|
||||
vi.mock('./system-ssh-args', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SystemSshArgs>()),
|
||||
getOrcaControlSocketPath: vi.fn().mockReturnValue(null)
|
||||
}))
|
||||
vi.mock('./system-ssh-command', () => ({ spawnSystemSsh: vi.fn(), spawnSystemSshCommand: vi.fn() }))
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SystemSshFileBinaryTransfer>()),
|
||||
downloadFileViaSystemSsh: vi.fn().mockResolvedValue(undefined),
|
||||
uploadDirectoryViaSystemSsh: vi.fn().mockResolvedValue(undefined),
|
||||
uploadFileViaSystemSsh: vi.fn().mockResolvedValue(undefined),
|
||||
writeBufferViaSystemSsh: vi.fn().mockResolvedValue(undefined),
|
||||
writeBufferViaSystemSsh: vi.fn().mockResolvedValue(undefined)
|
||||
}))
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SystemSshFileTransfer>()),
|
||||
uploadDirectoryViaSystemSsh: vi.fn().mockResolvedValue(undefined),
|
||||
writeFileViaSystemSsh: vi.fn().mockResolvedValue(undefined)
|
||||
}))
|
||||
|
||||
vi.mock('./ssh-control-socket', () => ({ removeControlSocketPath: vi.fn() }))
|
||||
vi.mock('./ssh-config-parser', () => ({ resolveWithSshG: vi.fn().mockResolvedValue(null) }))
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshGConfigResolution>()),
|
||||
resolveWithSshG: vi.fn().mockResolvedValue(null)
|
||||
}))
|
||||
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import type { SftpNamespacePathMapping } from './sftp-namespace-resolution'
|
||||
import { getRemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { isSshSessionLimitError } from './ssh-session-limit-error'
|
||||
import { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './ssh-system-fallback'
|
||||
import { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
|
||||
const SHELL_HOME = '/var/services/homes/alice'
|
||||
|
||||
@@ -19,9 +19,10 @@ import {
|
||||
createSystemCommandChannel,
|
||||
createTarget
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection, shouldUseSystemSshTransport } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { writeFileViaSystemSsh } from './ssh-system-fallback'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { shouldUseSystemSshTransport } from './ssh-transport-selection'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import { writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import { CONNECT_TIMEOUT_MS } from './ssh-connection-utils'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import {
|
||||
@@ -33,8 +34,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -42,6 +56,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -2,8 +2,8 @@ import { EventEmitter } from 'node:events'
|
||||
import { vi } from 'vitest'
|
||||
import type { Mock } from 'vitest'
|
||||
import type { AnyAuthMethod, AuthenticationType } from 'ssh2'
|
||||
import type { SshConnectionCallbacks } from './ssh-connection'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshConnectionCallbacks } from './ssh-connection-utils'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
|
||||
export function createTarget(overrides?: Partial<SshTarget>): SshTarget {
|
||||
|
||||
@@ -2,9 +2,14 @@ import { vi } from 'vitest'
|
||||
import { createSystemCommandChannel, createSystemSshProcess } from './ssh-connection-test-fixtures'
|
||||
import type { SshConnection } from './ssh-connection'
|
||||
import type { MockSystemCommandChannel, MockSystemSshProcess } from './ssh-connection-test-fixtures'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import type { SystemSshBuildArgsOptions } from './system-ssh-args'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type * as SystemSshArgs from './system-ssh-args'
|
||||
import type * as SystemSshCommand from './system-ssh-command'
|
||||
import type * as SystemSshFileBinaryTransfer from './system-ssh-file-binary-transfer'
|
||||
import type * as SystemSshFileTransfer from './system-ssh-file-transfer'
|
||||
import type * as SshGConfigResolution from './ssh-g-config-resolution'
|
||||
import { resetSsh2ClientState, ssh2Mock } from './__tests__/ssh-connection-test-client'
|
||||
export {
|
||||
clientInstances,
|
||||
@@ -22,23 +27,10 @@ export type { MockSshClient, Ssh2ModuleMock } from './__tests__/ssh-connection-t
|
||||
|
||||
export type SystemSshBinaryModuleMock = { findSystemSsh: typeof findSystemSshMock }
|
||||
|
||||
export type SystemFallbackModuleMock = {
|
||||
getOrcaControlSocketPath: typeof getOrcaControlSocketPathMock
|
||||
spawnSystemSsh: typeof spawnSystemSshMock
|
||||
spawnSystemSshCommand: typeof spawnSystemSshCommandMock
|
||||
downloadFileViaSystemSsh: typeof downloadFileViaSystemSshMock
|
||||
uploadDirectoryViaSystemSsh: typeof uploadDirectoryViaSystemSshMock
|
||||
uploadFileViaSystemSsh: typeof uploadFileViaSystemSshMock
|
||||
writeBufferViaSystemSsh: typeof writeBufferViaSystemSshMock
|
||||
writeFileViaSystemSsh: typeof writeFileViaSystemSshMock
|
||||
}
|
||||
|
||||
export type ControlSocketModuleMock = {
|
||||
removeControlSocketPath: typeof removeControlSocketPathMock
|
||||
}
|
||||
|
||||
export type SshConfigParserModuleMock = { resolveWithSshG: typeof resolveWithSshGMock }
|
||||
|
||||
export const findSystemSshMock = vi.fn<() => string | null>()
|
||||
export const getOrcaControlSocketPathMock =
|
||||
vi.fn<(target: SshTarget, options?: SystemSshBuildArgsOptions) => string | null>()
|
||||
@@ -83,15 +75,32 @@ export function createSystemSshBinaryModule(): SystemSshBinaryModuleMock {
|
||||
return { findSystemSsh: findSystemSshMock }
|
||||
}
|
||||
|
||||
export function createSystemFallbackModule(): SystemFallbackModuleMock {
|
||||
// The system-ssh seams SshConnection reaches, each layered over its module's real exports.
|
||||
export function withSystemSshArgsMocks(actual: typeof SystemSshArgs) {
|
||||
return { ...actual, getOrcaControlSocketPath: getOrcaControlSocketPathMock }
|
||||
}
|
||||
|
||||
export function withSystemSshCommandMocks(actual: typeof SystemSshCommand) {
|
||||
return {
|
||||
getOrcaControlSocketPath: getOrcaControlSocketPathMock,
|
||||
...actual,
|
||||
spawnSystemSsh: spawnSystemSshMock,
|
||||
spawnSystemSshCommand: spawnSystemSshCommandMock,
|
||||
spawnSystemSshCommand: spawnSystemSshCommandMock
|
||||
}
|
||||
}
|
||||
|
||||
export function withSystemSshFileBinaryTransferMocks(actual: typeof SystemSshFileBinaryTransfer) {
|
||||
return {
|
||||
...actual,
|
||||
downloadFileViaSystemSsh: downloadFileViaSystemSshMock,
|
||||
uploadDirectoryViaSystemSsh: uploadDirectoryViaSystemSshMock,
|
||||
uploadFileViaSystemSsh: uploadFileViaSystemSshMock,
|
||||
writeBufferViaSystemSsh: writeBufferViaSystemSshMock,
|
||||
writeBufferViaSystemSsh: writeBufferViaSystemSshMock
|
||||
}
|
||||
}
|
||||
|
||||
export function withSystemSshFileTransferMocks(actual: typeof SystemSshFileTransfer) {
|
||||
return {
|
||||
...actual,
|
||||
uploadDirectoryViaSystemSsh: uploadDirectoryViaSystemSshMock,
|
||||
writeFileViaSystemSsh: writeFileViaSystemSshMock
|
||||
}
|
||||
}
|
||||
@@ -100,8 +109,13 @@ export function createControlSocketModule(): ControlSocketModuleMock {
|
||||
return { removeControlSocketPath: removeControlSocketPathMock }
|
||||
}
|
||||
|
||||
export function createSshConfigParserModule(): SshConfigParserModuleMock {
|
||||
return { resolveWithSshG: resolveWithSshGMock }
|
||||
// Why: an unreadable config keeps the developer's own ~/.ssh/config out of alias-claim verdicts.
|
||||
export function createSshConfigParserModule(): Record<string, never> {
|
||||
return {}
|
||||
}
|
||||
|
||||
export function withSshGConfigResolutionMocks(actual: typeof SshGConfigResolution) {
|
||||
return { ...actual, resolveWithSshG: resolveWithSshGMock }
|
||||
}
|
||||
|
||||
export function resetSshConnectionMocks(): void {
|
||||
|
||||
@@ -32,7 +32,7 @@ import { findDefaultKeyFile, resolveAgentSocket } from './ssh-auth-resolution'
|
||||
import { resolveEffectiveProxy } from './ssh-proxy-command'
|
||||
import { walkInitialAuthLadder } from './ssh-connection-test-fixtures'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
|
||||
// ── isTransientError ─────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ConnectConfig } from 'ssh2'
|
||||
import type { SshTarget, SshConnectionState } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import {
|
||||
findEncryptedPrivateKeyPath,
|
||||
isUnencryptedPrivateKey,
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
createTarget
|
||||
} from './ssh-connection-test-fixtures'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import { SshConnectionManager } from './ssh-connection-manager'
|
||||
import { RECONNECT_BACKOFF_MS } from './ssh-connection-utils'
|
||||
import { recordSshUserDisconnected, resetSshUserDisconnectsForTests } from './ssh-user-disconnect'
|
||||
@@ -25,8 +25,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -34,6 +47,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
function failHandshakes(): void {
|
||||
ssh2Mock.connectBehavior = 'error'
|
||||
|
||||
@@ -15,8 +15,21 @@ vi.mock('ssh2', async () => (await import('./ssh-connection-test-harness')).crea
|
||||
vi.mock('./system-ssh-binary', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemSshBinaryModule()
|
||||
)
|
||||
vi.mock('./ssh-system-fallback', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSystemFallbackModule()
|
||||
vi.mock('./system-ssh-args', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshArgsMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-command', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshCommandMocks(await importOriginal())
|
||||
)
|
||||
vi.mock('./system-ssh-file-binary-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileBinaryTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./system-ssh-file-transfer', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSystemSshFileTransferMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
vi.mock('./ssh-control-socket', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createControlSocketModule()
|
||||
@@ -24,6 +37,11 @@ vi.mock('./ssh-control-socket', async () =>
|
||||
vi.mock('./ssh-config-parser', async () =>
|
||||
(await import('./ssh-connection-test-harness')).createSshConfigParserModule()
|
||||
)
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) =>
|
||||
(await import('./ssh-connection-test-harness')).withSshGConfigResolutionMocks(
|
||||
await importOriginal()
|
||||
)
|
||||
)
|
||||
|
||||
describe('SshConnection', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -23,12 +23,11 @@ import type {
|
||||
import type { SshTarget, SshConnectionState, SshConnectionStatus } from '../../shared/ssh-types'
|
||||
import {
|
||||
getOrcaControlSocketPath,
|
||||
spawnSystemSshCommand,
|
||||
isOpenSshConfigBackedTarget,
|
||||
type SystemSshBuildArgsOptions
|
||||
} from './ssh-system-fallback'
|
||||
import { resolveWithSshG, type SshResolvedConfig } from './ssh-config-parser'
|
||||
} from './system-ssh-args'
|
||||
import { spawnSystemSshCommand } from './system-ssh-command'
|
||||
import { removeControlSocketPath } from './ssh-control-socket'
|
||||
import { isOpenSshConfigBackedTarget } from './system-ssh-args'
|
||||
import {
|
||||
INITIAL_RETRY_ATTEMPTS,
|
||||
INITIAL_RETRY_DELAY_MS,
|
||||
@@ -57,7 +56,12 @@ import {
|
||||
orderServerHostKeyAlgorithms
|
||||
} from './ssh-host-key-verifier'
|
||||
import { HostKeyVerificationError, isHostKeyVerificationError } from './ssh-host-key-decision'
|
||||
import { siteConfigMayRestrictHostKeys, sshGArgsForHost } from './ssh-g-config-resolution'
|
||||
import {
|
||||
resolveWithSshG,
|
||||
siteConfigMayRestrictHostKeys,
|
||||
sshGArgsForHost,
|
||||
type SshResolvedConfig
|
||||
} from './ssh-g-config-resolution'
|
||||
import {
|
||||
boundSshHostKeyStoreFile,
|
||||
loadTrustedHostKeys,
|
||||
@@ -95,7 +99,6 @@ import { tagSftpHandshakeCorruption } from './sftp-handshake-corruption'
|
||||
import { withTimeout } from '../../shared/promise-timeout-fallback'
|
||||
import { isEphemeralRuntimeSshOwner } from '../../shared/managed-orcad-ssh-owner'
|
||||
import { isSshUserDisconnected } from './ssh-user-disconnect'
|
||||
export type { SshConnectionCallbacks } from './ssh-connection-utils'
|
||||
|
||||
/** The sign-in a connection holds in memory, handed to the connection that replaces it. */
|
||||
export type SshCachedCredentials = { password: string | null; passphrase: string | null }
|
||||
@@ -1611,5 +1614,3 @@ export class SshConnection {
|
||||
this.callbacks.onStateChange(this.target.id, { ...this.state })
|
||||
}
|
||||
}
|
||||
|
||||
export { shouldUseSystemSshTransport } from './ssh-transport-selection'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { lstatSync, mkdirSync, rmSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { isAbsolute, join as pathJoin } from 'node:path'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
|
||||
export type SystemSshResolvedConfig = Pick<
|
||||
SshResolvedConfig,
|
||||
|
||||
@@ -7,11 +7,11 @@ import { SshConnection } from './ssh-connection'
|
||||
import { INITIAL_RETRY_DELAY_MS } from './ssh-connection-utils'
|
||||
import { createCallbacks, createResolvedConfig, createTarget } from './ssh-connection-test-fixtures'
|
||||
import { initSshHostKeyStoreFile } from './ssh-host-key-store'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import type * as SshConfigParser from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import type * as SshGConfigResolution from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('./ssh-config-parser', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshConfigParser>()),
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshGConfigResolution>()),
|
||||
resolveWithSshG: vi.fn()
|
||||
}))
|
||||
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
*/
|
||||
import { RELAY_REMOTE_DIR } from './relay-protocol'
|
||||
import { commandWithNodePath } from './ssh-remote-commands'
|
||||
import { powerShellLiteral, powerShellNativeArg } from './ssh-remote-powershell'
|
||||
import {
|
||||
quotePowerShellLiteral as powerShellLiteral,
|
||||
quotePowerShellNativeArgument as powerShellNativeArg
|
||||
} from '../../shared/powershell-native-argument'
|
||||
import { windowsRelayPipePathsForSocketName } from './ssh-relay-endpoints'
|
||||
import { RELAY_INSTALL_MODEL, remoteInstallVersionDirRegex } from './remote-install-model'
|
||||
import { joinRemotePath, type RemoteHostPlatform } from './ssh-remote-platform'
|
||||
|
||||
@@ -6,11 +6,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { createCallbacks, createResolvedConfig, createTarget } from './ssh-connection-test-fixtures'
|
||||
import { initSshHostKeyStoreFile } from './ssh-host-key-store'
|
||||
import { resolveWithSshG } from './ssh-config-parser'
|
||||
import type * as SshConfigParser from './ssh-config-parser'
|
||||
import { resolveWithSshG } from './ssh-g-config-resolution'
|
||||
import type * as SshGConfigResolution from './ssh-g-config-resolution'
|
||||
|
||||
vi.mock('./ssh-config-parser', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshConfigParser>()),
|
||||
vi.mock('./ssh-g-config-resolution', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof SshGConfigResolution>()),
|
||||
resolveWithSshG: vi.fn()
|
||||
}))
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from 'ssh2'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import { buildConnectConfig, type BuildConnectConfigOptions } from './ssh-connection-utils'
|
||||
|
||||
vi.mock('node:os', async (importOriginal) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { getPassphrasePrivateKeyPath } from './ssh-private-key-authentication'
|
||||
import { buildSshArgs } from './system-ssh-args'
|
||||
import { walkInitialAuthLadder } from './ssh-connection-test-fixtures'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
|
||||
function makeTarget(overrides: Partial<SshTarget> = {}): SshTarget {
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { spawnProcess } from '@orca/process-host'
|
||||
import { Duplex } from 'node:stream'
|
||||
import type { Socket as NetSocket } from 'node:net'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import { shellEscape } from './ssh-connection-utils'
|
||||
import { isOpenSshConfigBackedTarget } from './system-ssh-args'
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
tryStealInstallLockCommand
|
||||
} from './ssh-relay-install-lock-commands'
|
||||
import { removeRemoteTreeCommand } from './ssh-remote-commands'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import {
|
||||
getRemoteHostPlatform,
|
||||
isWindowsRemoteHost,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { shellEscape } from './ssh-connection-utils'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import { isWindowsRemoteHost, type RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import * as exitedOwnerSteal from './ssh-relay-install-lock-exited-owner'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { shellEscape } from './ssh-connection-utils'
|
||||
import type { InstallLockOwnerFile } from './ssh-relay-install-lock-commands'
|
||||
import { powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import {
|
||||
posixStateMutationGroupRecord,
|
||||
posixStateMutationPidRecord
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** How the host census reaches a running Windows relay through its own bridge. */
|
||||
import { commandWithNodePath } from './ssh-remote-commands'
|
||||
import type { RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
|
||||
export function windowsRelayConnectCommand(
|
||||
hostPlatform: RemoteHostPlatform,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { remoteInstallListingRegexSource, type RemoteInstallModel } from './remote-install-model'
|
||||
import type { RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { isWindowsRemoteHost, joinRemotePath, remoteDirname } from './ssh-remote-platform'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import { shellEscape } from './ssh-connection-utils'
|
||||
|
||||
export function readRemoteHomeCommand(host: RemoteHostPlatform): string {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { SshConnectionManager } from './ssh-connection-manager'
|
||||
import type { SshExecOptions } from './ssh-connection-utils'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import type { FilesystemPathFlavor } from '../../shared/filesystem-entry-types'
|
||||
import { sortDirEntries } from '../../shared/file-name-sort'
|
||||
import { buildPosixStdoutFence } from '../../shared/posix-stdout-fence'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { posix as posixPath } from 'node:path'
|
||||
import { shellEscape } from './ssh-connection-utils'
|
||||
import { powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
|
||||
/** The host-Node floor for the npm path. */
|
||||
export const MIN_HOST_NODE_MAJOR = 18
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { gunzipSync, gzipSync } from 'node:zlib'
|
||||
import { encodePowerShellCommand } from '../../shared/powershell-command-encoding'
|
||||
import { CMD_EXE_COMMAND_LINE_MAX_CHARS } from '../providers/windows-shell-args'
|
||||
export {
|
||||
quotePowerShellLiteral as powerShellLiteral,
|
||||
quotePowerShellNativeArgument as powerShellNativeArg
|
||||
} from '../../shared/powershell-native-argument'
|
||||
|
||||
// Why cmd.exe and not the 32767 CreateProcess cap: Windows OpenSSH runs every exec request
|
||||
// through sshd's DefaultShell, cmd.exe on a stock install. Budget under cmd.exe's own ceiling
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
export { findSystemSsh } from './system-ssh-binary'
|
||||
export {
|
||||
buildSshArgs,
|
||||
getOrcaControlSocketPath,
|
||||
type SystemSshBuildArgsOptions
|
||||
} from './system-ssh-args'
|
||||
export { spawnSystemSsh, spawnSystemSshCommand, type SystemSshProcess } from './system-ssh-command'
|
||||
export {
|
||||
downloadFileViaSystemSsh,
|
||||
uploadFileViaSystemSsh,
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
export { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
@@ -7,7 +7,7 @@ vi.mock('electron', () => ({
|
||||
}))
|
||||
|
||||
import { SshConnection } from './ssh-connection'
|
||||
import { uploadDirectoryViaSystemSsh } from './ssh-system-fallback'
|
||||
import { uploadDirectoryViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import { relayArtifactFilenames } from './relay-install-artifacts'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { constants } from 'node:fs'
|
||||
import { open, stat } from 'node:fs/promises'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SshResolvedConfig } from './ssh-config-parser'
|
||||
import type { SshResolvedConfig } from './ssh-g-config-resolution'
|
||||
import { listDefaultIdentityFilePaths, resolveIdentityFilePaths } from './ssh-auth-resolution'
|
||||
import { resolveSshConfigHomePath } from './ssh-config-path-expansion'
|
||||
import {
|
||||
|
||||
@@ -10,10 +10,7 @@ const { spawnMock, connectMock, createServerMock, waitForStopMock } = vi.hoisted
|
||||
|
||||
vi.mock('node:child_process', () => ({ spawn: spawnMock }))
|
||||
vi.mock('node:net', () => ({ connect: connectMock, createServer: createServerMock }))
|
||||
vi.mock('./ssh-system-fallback', async (importOriginal) => {
|
||||
const actual = (await importOriginal()) as Record<string, unknown>
|
||||
return { ...actual, findSystemSsh: () => '/usr/bin/ssh' }
|
||||
})
|
||||
vi.mock('./system-ssh-binary', () => ({ findSystemSsh: () => '/usr/bin/ssh' }))
|
||||
vi.mock('./system-ssh-forward-process', () => ({
|
||||
waitForSystemSshForwardStop: waitForStopMock
|
||||
}))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { spawn, type ChildProcess } from 'node:child_process'
|
||||
import { connect, createServer, type AddressInfo, type Socket } from 'node:net'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import { buildSshArgs, findSystemSsh, type SystemSshBuildArgsOptions } from './ssh-system-fallback'
|
||||
import { buildSshArgs, type SystemSshBuildArgsOptions } from './system-ssh-args'
|
||||
import { findSystemSsh } from './system-ssh-binary'
|
||||
import { waitForSystemSshForwardStop } from './system-ssh-forward-process'
|
||||
|
||||
const STARTUP_TIMEOUT_MS = 10_000
|
||||
|
||||
@@ -12,7 +12,8 @@ import {
|
||||
} from './system-ssh-args'
|
||||
import { spawnSystemSshCommand } from './system-ssh-command'
|
||||
import { isWindowsRemoteHost, type RemoteHostPlatform } from './ssh-remote-platform'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import {
|
||||
awaitWithSystemSshAbort,
|
||||
throwIfAborted,
|
||||
@@ -23,12 +24,6 @@ import {
|
||||
type WindowsWriteSource
|
||||
} from './system-ssh-windows-write-strategy'
|
||||
|
||||
export {
|
||||
WINDOWS_STDIN_WRITE_CHUNK_BYTES,
|
||||
WINDOWS_STDIN_WRITE_TIMEOUT_MS
|
||||
} from './system-ssh-windows-write-strategy'
|
||||
export { WINDOWS_STAGED_WRITE_SUFFIX } from './system-ssh-windows-file-write'
|
||||
|
||||
type SystemSshOperationOptions = SystemSshBuildArgsOptions & {
|
||||
signal?: AbortSignal
|
||||
hostPlatform?: RemoteHostPlatform
|
||||
|
||||
@@ -23,12 +23,11 @@ import {
|
||||
isHostAnsweredSystemSshExit,
|
||||
type ProcessResult
|
||||
} from './system-ssh-operation-lifecycle'
|
||||
import { uploadFileViaSystemSsh, writeBufferViaSystemSsh } from './system-ssh-file-binary-transfer'
|
||||
import {
|
||||
uploadFileViaSystemSsh,
|
||||
WINDOWS_STDIN_WRITE_CHUNK_BYTES,
|
||||
WINDOWS_STDIN_WRITE_TIMEOUT_MS,
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
WINDOWS_STDIN_WRITE_TIMEOUT_MS
|
||||
} from './system-ssh-windows-write-strategy'
|
||||
import {
|
||||
isSftpPathUnsupportedError,
|
||||
isSftpUnavailableError,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { spawn, type ChildProcess } from 'node:child_process'
|
||||
import { connect, createServer } from 'node:net'
|
||||
import { buildSshArgs, findSystemSsh, type SystemSshBuildArgsOptions } from './ssh-system-fallback'
|
||||
import { buildSshArgs, type SystemSshBuildArgsOptions } from './system-ssh-args'
|
||||
import { findSystemSsh } from './system-ssh-binary'
|
||||
import { stopOrphanedOrcaSshForward } from './system-ssh-orphaned-forward'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
|
||||
|
||||
+5
-7
@@ -22,16 +22,14 @@ vi.mock('child_process', () => ({
|
||||
spawn: spawnMock
|
||||
}))
|
||||
|
||||
import { buildSshArgs } from './system-ssh-args'
|
||||
import {
|
||||
buildSshArgs,
|
||||
downloadFileViaSystemSsh,
|
||||
spawnSystemSsh,
|
||||
spawnSystemSshCommand,
|
||||
uploadDirectoryViaSystemSsh,
|
||||
uploadFileViaSystemSsh,
|
||||
writeBufferViaSystemSsh,
|
||||
writeFileViaSystemSsh
|
||||
} from './ssh-system-fallback'
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
import { spawnSystemSsh, spawnSystemSshCommand } from './system-ssh-command'
|
||||
import { uploadDirectoryViaSystemSsh, writeFileViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import { getRemoteHostPlatform } from './ssh-remote-platform'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
import type { SystemSshResolvedConfig } from './ssh-control-socket'
|
||||
@@ -1,5 +1,6 @@
|
||||
import { randomBytes } from 'node:crypto'
|
||||
import { powerShellCommand, powerShellLiteral } from './ssh-remote-powershell'
|
||||
import { powerShellCommand } from './ssh-remote-powershell'
|
||||
import { quotePowerShellLiteral as powerShellLiteral } from '../../shared/powershell-native-argument'
|
||||
import { normalizeWindowsRemotePath } from './ssh-remote-platform'
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,13 +43,8 @@ vi.mock('./system-ssh-operation-lifecycle', async (importActual) => {
|
||||
})
|
||||
|
||||
import { uploadDirectoryViaSystemSsh } from './system-ssh-file-transfer'
|
||||
import {
|
||||
uploadFileViaSystemSsh,
|
||||
WINDOWS_STAGED_WRITE_SUFFIX,
|
||||
WINDOWS_STDIN_WRITE_CHUNK_BYTES,
|
||||
WINDOWS_STDIN_WRITE_TIMEOUT_MS,
|
||||
writeBufferViaSystemSsh
|
||||
} from './system-ssh-file-binary-transfer'
|
||||
import { uploadFileViaSystemSsh, writeBufferViaSystemSsh } from './system-ssh-file-binary-transfer'
|
||||
import { WINDOWS_STAGED_WRITE_SUFFIX } from './system-ssh-windows-file-write'
|
||||
import { waitForChannelClose } from './system-ssh-operation-lifecycle'
|
||||
import * as windowsFileWrite from './system-ssh-windows-file-write'
|
||||
import { getRemoteHostPlatform } from './ssh-remote-platform'
|
||||
@@ -59,6 +54,8 @@ import {
|
||||
} from './system-ssh-windows-write-capabilities'
|
||||
import {
|
||||
explainWindowsPowerShellStdinFailure,
|
||||
WINDOWS_STDIN_WRITE_CHUNK_BYTES,
|
||||
WINDOWS_STDIN_WRITE_TIMEOUT_MS,
|
||||
writeWindowsRemoteFile
|
||||
} from './system-ssh-windows-write-strategy'
|
||||
import type { SshTarget } from '../../shared/ssh-types'
|
||||
|
||||
Reference in New Issue
Block a user