mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 16:02:29 +00:00
* Revert "feat(orcad): source-side dormant export of a relay-hosted SSH target (#16741 T6-8) (#24519)" This reverts commit783101b304. * Revert "feat(ssh): update, roll back, recover and stop a managed orcad server (#16741 T6-5 follow-up) (#24463)" This reverts commit38c2d1dcb9. * Revert "feat(ssh): deploy and pair an empty managed orcad server over SSH (#16741 T6-5) (#24453)" This reverts commit8b76683b40. * Revert "fix(ssh): orcad GC honors the activation journal; readiness requires proven daemon coverage (#16741 T6 follow-up) (#24451)" This reverts commitd3f8c5063b. * Revert "feat(ssh): remote orcad stop by request file and journaled decommission (#16741 T6-4) (#24449)" This reverts commit43d9b43d3f. * Revert "feat(orcad): supervisable server: stop requests, managed stop receipts and a lifetime that keeps its lock on failed teardown (#16741 T6-3) (#24433)" This reverts commitb093d3ab20. * Revert "feat(ssh): crash-safe orcad activation, rollback and recovery (#16741 T6-2) (#24423)" This reverts commit1a9ac0e955. * Revert "feat(runtime): SSH access links for paired servers in a downgrade-safe sidecar (#16741 T5-1+T5-2) (#24420)" This reverts commit99db2bfae4. * Revert "feat(relay): capability-gated owner reset with a durable preparation journal (#16741 T3 R1) (#24418)" This reverts commit34a582bd39. * Revert "feat(ssh): track connection-manager drains, test probes and provider continuations (#16741 T2 P3+P8a) (#24407)" This reverts commitd53063d2b1. * Revert "feat(daemon): idle retirement, session census and recovery-only provider (#16741 T2 P4b) (#24409)" This reverts commitff212dbbef. * Revert "feat(ssh): add pty.resumeClient and split SSH PTY process listing (#16741 T2 P5+P6) (#24414)" This reverts commit92cb71765e. * Revert "feat(relay): await owned watcher and agent children on shutdown (#16741 T2 P1) (#24400)" This reverts commit6b36e4f85b. * Revert "feat(session): retry failed renderer session writes and verify local folder PTYs (#16741 T2 P9) (#24406)" This reverts commitd23ecef301. * Revert "feat(ssh): remote orcad primitives on the pinned Node runtime (#16741 T6-1) (#24419)" This reverts commitdd87ae578d. * Revert "fix(runtime): fence runtime-environment subscriptions and status probes by identity (#16741 T5-3) (#24421)" This reverts commitece9e4d2e3. * Revert "feat(orcad): migration manifest and dormant-state contracts (#16741 T6-7) (#24422)" This reverts commit3fbdaba262. * Revert "feat(ssh): wire SshConnection through the work and transport close ledgers (#16741 T2 P2) (#24401)" This reverts commit4e8edc8872. * Revert "feat(profiles): carry markdown frontmatter visibility in project transfers (#16741 T2 P7) (#24405)" This reverts commit60c93263cc. * Revert "fix(runtime): project the PTY incarnation onto mobile session tabs (#24413)" This reverts commit99e0303572. * Revert "feat(daemon): tag daemon stream data with the PTY incarnation id (#16741 T2 P4a) (#24402)" This reverts commit817af768b0. * Revert "feat(ssh): port the SSH connection work ledger and transport close ledger (#16741 T2) (#24210)" This reverts commitc9918931c8. * Revert "feat(relay): fence and drain file and git response streams on shutdown (#24185)" This reverts commitdc08ffeba9. * Revert "refactor(runtime-rpc): extract the Node WebSocket lifecycle; opt-in pinned port (#24186)" This reverts commita789233bbb. * Revert "feat(relay): route relay handlers through work admission; producer publication drain (#24181)" This reverts commit0b812bd698. * Revert "feat(relay): land the #16741 T1 seam (work drain, publication drain, release gate) (#24156)" This reverts commit3aa2d3af7c. --------- Co-authored-by: m4air <m4air@Mac.localdomain>
270 lines
8.3 KiB
TypeScript
270 lines
8.3 KiB
TypeScript
import { mkdtempSync, writeFileSync, mkdirSync, chmodSync, rmSync, readFileSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
vi.mock('electron', () => ({
|
|
app: { getAppPath: () => '/mock/app' }
|
|
}))
|
|
|
|
import { SshConnection } from './ssh-connection'
|
|
import { deployAndLaunchRelay } from './ssh-relay-deploy'
|
|
import { SshChannelMultiplexer } from './ssh-channel-multiplexer'
|
|
import { uploadDirectoryViaSystemSsh } from './ssh-system-fallback'
|
|
import type { SshTarget } from '../../shared/ssh-types'
|
|
import { relayArtifactFilenames } from '../../shared/relay-artifacts'
|
|
|
|
const RELAY_VERSION = '0.1.0+systemtransport'
|
|
|
|
function makeTarget(): SshTarget {
|
|
return {
|
|
id: 'system-transport-target',
|
|
label: 'System Transport Target',
|
|
configHost: 'fdpass-host',
|
|
host: 'ignored.example.com',
|
|
port: 22,
|
|
username: ''
|
|
}
|
|
}
|
|
|
|
function writeFakeSsh(dir: string): string {
|
|
const path = join(dir, 'fake-ssh')
|
|
writeFileSync(
|
|
path,
|
|
`#!/bin/sh
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
-o|-p|-i|-J|-S) shift 2 ;;
|
|
-T) shift ;;
|
|
--) shift; break ;;
|
|
-*) shift ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
if [ "$#" -gt 0 ]; then
|
|
shift
|
|
fi
|
|
cmd="$1"
|
|
if [ -z "$cmd" ]; then
|
|
exit 0
|
|
fi
|
|
exec /bin/sh -c "$cmd"
|
|
`
|
|
)
|
|
chmodSync(path, 0o755)
|
|
return path
|
|
}
|
|
|
|
function writeFakeRelay(dir: string): void {
|
|
// Stage every companion the manifest declares — relay.js gets real content
|
|
// below — so adding one cannot silently fail the completeness probe here.
|
|
for (const filename of relayArtifactFilenames(false)) {
|
|
if (filename !== 'relay.js') {
|
|
writeFileSync(join(dir, filename), '')
|
|
}
|
|
}
|
|
writeFileSync(
|
|
join(dir, 'relay.js'),
|
|
`
|
|
const fs = require('fs');
|
|
const net = require('net');
|
|
const sentinel = 'ORCA-RELAY v0.1.0 READY\\n';
|
|
const sockPath = process.argv[process.argv.indexOf('--sock-path') + 1];
|
|
|
|
function encode(msg) {
|
|
const payload = Buffer.from(JSON.stringify(msg), 'utf8');
|
|
const header = Buffer.alloc(13);
|
|
header[0] = 1;
|
|
header.writeUInt32BE(1, 1);
|
|
header.writeUInt32BE(0, 5);
|
|
header.writeUInt32BE(payload.length, 9);
|
|
return Buffer.concat([header, payload]);
|
|
}
|
|
|
|
function serve(socket, onResolved) {
|
|
socket.on('error', () => {});
|
|
socket.write(sentinel);
|
|
let buffer = Buffer.alloc(0);
|
|
socket.on('data', (chunk) => {
|
|
buffer = Buffer.concat([buffer, chunk]);
|
|
while (buffer.length >= 13) {
|
|
const type = buffer[0];
|
|
const length = buffer.readUInt32BE(9);
|
|
if (buffer.length < 13 + length) return;
|
|
const payload = buffer.subarray(13, 13 + length);
|
|
buffer = buffer.subarray(13 + length);
|
|
if (type !== 1) continue;
|
|
const message = JSON.parse(payload.toString('utf8'));
|
|
if (message.method === 'session.resolveHome') {
|
|
socket.write(
|
|
encode({ jsonrpc: '2.0', id: message.id, result: process.env.HOME }),
|
|
onResolved
|
|
);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if (process.argv.includes('--detached')) {
|
|
try { fs.unlinkSync(sockPath); } catch {}
|
|
const server = net.createServer((socket) => {
|
|
serve(socket, () => server.close());
|
|
});
|
|
server.listen(sockPath);
|
|
} else if (process.argv.includes('--connect')) {
|
|
const socket = net.createConnection(sockPath);
|
|
socket.on('error', (error) => {
|
|
process.stderr.write(error.message);
|
|
process.exit(1);
|
|
});
|
|
process.stdin.pipe(socket);
|
|
socket.pipe(process.stdout);
|
|
}
|
|
`
|
|
)
|
|
}
|
|
|
|
function createRelayTree(root: string, remoteHome: string): void {
|
|
const platforms = [
|
|
'linux-x64',
|
|
'linux-arm64',
|
|
'darwin-x64',
|
|
'darwin-arm64',
|
|
'win32-x64',
|
|
'win32-arm64'
|
|
]
|
|
for (const platform of platforms) {
|
|
const localDir = join(root, platform)
|
|
mkdirSync(localDir, { recursive: true })
|
|
writeFileSync(join(localDir, '.version'), RELAY_VERSION)
|
|
writeFakeRelay(localDir)
|
|
}
|
|
|
|
const remoteDir = join(remoteHome, '.orca-remote', `relay-${RELAY_VERSION}`)
|
|
mkdirSync(join(remoteDir, 'node_modules', 'node-pty', 'lib'), { recursive: true })
|
|
mkdirSync(join(remoteDir, 'node_modules', '@parcel', 'watcher'), { recursive: true })
|
|
writeFileSync(join(remoteDir, 'node_modules', 'node-pty', 'index.js'), '')
|
|
writeFileSync(
|
|
join(remoteDir, 'node_modules', 'node-pty', 'lib', 'utils.js'),
|
|
'exports.loadNativeModule = () => ({})\n'
|
|
)
|
|
writeFileSync(join(remoteDir, 'node_modules', '@parcel', 'watcher', 'index.js'), '')
|
|
writeFileSync(join(remoteDir, '.install-complete'), '')
|
|
writeFakeRelay(remoteDir)
|
|
}
|
|
|
|
describe('system SSH transport integration', () => {
|
|
let tempDir: string
|
|
let oldHome: string | undefined
|
|
let oldRelayPath: string | undefined
|
|
let oldSystemSshPath: string | undefined
|
|
let oldForceSystemTransport: string | undefined
|
|
|
|
beforeEach(() => {
|
|
if (process.platform === 'win32') {
|
|
return
|
|
}
|
|
tempDir = mkdtempSync(join('/tmp', 'orca-ssh-'))
|
|
oldHome = process.env.HOME
|
|
oldRelayPath = process.env.ORCA_RELAY_PATH
|
|
oldSystemSshPath = process.env.ORCA_SYSTEM_SSH_PATH
|
|
oldForceSystemTransport = process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
|
|
const remoteHome = join(tempDir, 'remote-home')
|
|
const relayRoot = join(tempDir, 'relay')
|
|
mkdirSync(remoteHome, { recursive: true })
|
|
createRelayTree(relayRoot, remoteHome)
|
|
process.env.HOME = remoteHome
|
|
process.env.ORCA_RELAY_PATH = relayRoot
|
|
process.env.ORCA_SYSTEM_SSH_PATH = writeFakeSsh(tempDir)
|
|
process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT = '1'
|
|
})
|
|
|
|
afterEach(() => {
|
|
if (process.platform === 'win32') {
|
|
return
|
|
}
|
|
if (oldHome === undefined) {
|
|
delete process.env.HOME
|
|
} else {
|
|
process.env.HOME = oldHome
|
|
}
|
|
if (oldRelayPath === undefined) {
|
|
delete process.env.ORCA_RELAY_PATH
|
|
} else {
|
|
process.env.ORCA_RELAY_PATH = oldRelayPath
|
|
}
|
|
if (oldSystemSshPath === undefined) {
|
|
delete process.env.ORCA_SYSTEM_SSH_PATH
|
|
} else {
|
|
process.env.ORCA_SYSTEM_SSH_PATH = oldSystemSshPath
|
|
}
|
|
if (oldForceSystemTransport === undefined) {
|
|
delete process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
|
|
} else {
|
|
process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT = oldForceSystemTransport
|
|
}
|
|
rmSync(tempDir, { recursive: true, force: true })
|
|
})
|
|
|
|
// Why: this fixture writes a POSIX fake ssh script to exercise stdin/stdout
|
|
// transport semantics; Windows coverage stays in argument/unit tests.
|
|
it.skipIf(process.platform === 'win32')(
|
|
'deploys and speaks relay RPC over a system ssh process for ProxyUseFdpass targets',
|
|
async () => {
|
|
const conn = new SshConnection(makeTarget(), { onStateChange: vi.fn() })
|
|
const onProgress = vi.fn()
|
|
await conn.connect()
|
|
expect(conn.usesSystemSshTransport()).toBe(true)
|
|
|
|
const result = await deployAndLaunchRelay(conn, onProgress, 60, makeTarget().id)
|
|
expect(onProgress).toHaveBeenCalledWith('Starting relay...')
|
|
expect(onProgress).not.toHaveBeenCalledWith('Uploading relay...')
|
|
expect(onProgress).not.toHaveBeenCalledWith('Installing native dependencies...')
|
|
const mux = new SshChannelMultiplexer(result.transport)
|
|
try {
|
|
await expect(mux.request('session.resolveHome', { path: '~' })).resolves.toBe(
|
|
join(tempDir, 'remote-home')
|
|
)
|
|
} finally {
|
|
mux.dispose()
|
|
await conn.disconnect()
|
|
}
|
|
},
|
|
20_000
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'connects GSSAPI-flagged targets through system ssh without the force override',
|
|
async () => {
|
|
delete process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
|
|
const conn = new SshConnection(
|
|
{ ...makeTarget(), source: 'manual', gssapiAuthentication: true },
|
|
{ onStateChange: vi.fn() }
|
|
)
|
|
await conn.connect()
|
|
try {
|
|
expect(conn.usesSystemSshTransport()).toBe(true)
|
|
expect(conn.getState().status).toBe('connected')
|
|
} finally {
|
|
await conn.disconnect()
|
|
}
|
|
},
|
|
20_000
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'uploads a directory through the system ssh stdin/stdout path',
|
|
async () => {
|
|
const source = join(tempDir, 'source')
|
|
const destination = join(tempDir, 'uploaded')
|
|
mkdirSync(source, { recursive: true })
|
|
writeFileSync(join(source, 'payload.txt'), 'uploaded over system ssh')
|
|
|
|
await uploadDirectoryViaSystemSsh(makeTarget(), source, destination)
|
|
|
|
expect(readFileSync(join(destination, 'payload.txt'), 'utf8')).toBe(
|
|
'uploaded over system ssh'
|
|
)
|
|
}
|
|
)
|
|
})
|