Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 15 additions & 68 deletions scripts/prepare-dual-dgx-station.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
stationKnownHostsDigest,
writeDualStationSshBinding,
} from "../src/lib/inference/vllm-station-ssh-binding.ts";
import { strictVllmSshTransportArgs } from "../src/lib/inference/serving/vllm-ssh-transport-policy.ts";
import {
type DualStationPreparationDeps,
type DualStationResumeState,
Expand Down Expand Up @@ -378,64 +379,6 @@ function runStreamingCommand(
return result.status ?? 1;
}

export function strictStationPrepSshTransportArgs(): string[] {
return [
"-T",
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=yes",
"-o",
"VerifyHostKeyDNS=no",
"-o",
"NoHostAuthenticationForLocalhost=no",
"-o",
"NumberOfPasswordPrompts=0",
"-o",
"PasswordAuthentication=no",
"-o",
"KbdInteractiveAuthentication=no",
"-o",
"PreferredAuthentications=publickey",
"-o",
"ConnectTimeout=5",
"-o",
"ConnectionAttempts=1",
"-o",
"ServerAliveInterval=5",
"-o",
"ServerAliveCountMax=1",
"-o",
"ClearAllForwardings=yes",
"-o",
"ForwardAgent=no",
"-o",
"ForwardX11=no",
"-o",
"ForwardX11Trusted=no",
"-o",
"Tunnel=no",
"-o",
"UpdateHostKeys=no",
"-o",
"ControlMaster=no",
"-o",
"ControlPath=none",
"-o",
"PermitLocalCommand=no",
"-o",
"RemoteCommand=none",
"-o",
"ProxyCommand=none",
"-o",
"ProxyJump=none",
"-o",
"KnownHostsCommand=none",
"-o",
"LogLevel=ERROR",
];
}

function parseSshConfig(stdout: string): SshConfig {
const values = new Map<string, string[]>();
for (const rawLine of stdout.split(/\r?\n/)) {
Expand Down Expand Up @@ -567,11 +510,7 @@ function knownHostEvidence(

export function inspectPretrustedSshTarget(target: string): PretrustedSshTarget | null {
validateStationPeerTarget(target);
const configResult = runCommand(
"ssh",
["-G", ...strictStationPrepSshTransportArgs(), "--", target],
"",
);
const configResult = runCommand("ssh", ["-G", ...strictVllmSshTransportArgs(), "--", target], "");
if (!commandSucceeded(configResult, true)) return null;
const config = parseSshConfig(configResult.stdout);
assertStrictSshConfig(config);
Expand Down Expand Up @@ -936,13 +875,13 @@ function assertHelperFile(helperPath: string): Buffer {
}
}

function sshArgs(
export function stationPrepSshArgs(
binding: PretrustedSshTarget,
pinnedKnownHostsPath: string,
remoteCommand: string,
): string[] {
return [
...strictStationPrepSshTransportArgs(),
...strictVllmSshTransportArgs(),
"-o",
`UserKnownHostsFile=${pinnedKnownHostsPath}`,
"-o",
Expand Down Expand Up @@ -997,7 +936,7 @@ function createRuntimeDeps(options: CliOptions): {
parseHostResult(
runCommand(
"ssh",
sshArgs(binding, pinnedKnownHosts(binding), "python3 -"),
stationPrepSshArgs(binding, pinnedKnownHosts(binding), "python3 -"),
STATION_DISCOVERY_PROBE,
),
"Peer Station identity probe",
Expand All @@ -1014,7 +953,11 @@ function createRuntimeDeps(options: CliOptions): {
return connectivityMatches(
runCommand(
"ssh",
sshArgs(binding, pinnedKnownHosts(binding), ["python3", "-", ...args].join(" ")),
stationPrepSshArgs(
binding,
pinnedKnownHosts(binding),
["python3", "-", ...args].join(" "),
),
CONNECTIVITY_PROBE,
),
requests,
Expand All @@ -1023,7 +966,11 @@ function createRuntimeDeps(options: CliOptions): {
runRemoteHelper: (binding, mode) => {
return runStreamingCommand(
"ssh",
sshArgs(binding, pinnedKnownHosts(binding), buildRemoteHelperCommand(helperSha256, mode)),
stationPrepSshArgs(
binding,
pinnedKnownHosts(binding),
buildRemoteHelperCommand(helperSha256, mode),
),
helperBytes.toString("utf8"),
);
},
Expand Down
2 changes: 1 addition & 1 deletion src/lib/inference/serving/managed-cluster-ssh-binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type {
QualifiedStationSshIdentity as QualifiedManagedVllmSshIdentity,
WriteDualStationSshBindingOptions as WriteManagedVllmSshBindingOptions,
} from "../vllm-station-ssh-binding.js";
export { strictVllmSshTransportArgs as strictManagedVllmSshTransportArgs } from "./vllm-ssh-transport-policy.js";
/**
* Cardinality-neutral names for the pinned SSH transport shared by managed
* vLLM clusters. The legacy Station implementation remains the compatibility
Expand All @@ -23,6 +24,5 @@ export {
loadDualStationSshBindingForStatePath as loadManagedVllmSshBindingForStatePath,
loadDualStationSshBindingHandoff as loadManagedVllmSshBindingHandoff,
stationKnownHostsDigest as managedVllmKnownHostsDigest,
strictStationSshTransportArgs as strictManagedVllmSshTransportArgs,
writeDualStationSshBinding as writeManagedVllmSshBinding,
} from "../vllm-station-ssh-binding.js";
66 changes: 66 additions & 0 deletions src/lib/inference/serving/vllm-ssh-transport-policy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { describe, expect, it } from "vitest";

import { strictVllmSshTransportArgs } from "./vllm-ssh-transport-policy";

describe("strict vLLM SSH transport policy", () => {
it("returns the exact noninteractive transport boundary (#9519)", () => {
expect(strictVllmSshTransportArgs()).toEqual([
"-T",
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=yes",
"-o",
"VerifyHostKeyDNS=no",
"-o",
"NoHostAuthenticationForLocalhost=no",
"-o",
"NumberOfPasswordPrompts=0",
"-o",
"PasswordAuthentication=no",
"-o",
"KbdInteractiveAuthentication=no",
"-o",
"PreferredAuthentications=publickey",
"-o",
"ConnectTimeout=5",
"-o",
"ConnectionAttempts=1",
"-o",
"ServerAliveInterval=5",
"-o",
"ServerAliveCountMax=1",
"-o",
"ClearAllForwardings=yes",
"-o",
"ForwardAgent=no",
"-o",
"ForwardX11=no",
"-o",
"ForwardX11Trusted=no",
"-o",
"Tunnel=no",
"-o",
"UpdateHostKeys=no",
"-o",
"ControlMaster=no",
"-o",
"ControlPath=none",
"-o",
"PermitLocalCommand=no",
"-o",
"RemoteCommand=none",
"-o",
"ProxyCommand=none",
"-o",
"ProxyJump=none",
"-o",
"KnownHostsCommand=none",
"-o",
"LogLevel=ERROR",
]);
});
});
60 changes: 60 additions & 0 deletions src/lib/inference/serving/vllm-ssh-transport-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

export function strictVllmSshTransportArgs(): string[] {
return [
"-T",
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=yes",
"-o",
"VerifyHostKeyDNS=no",
"-o",
"NoHostAuthenticationForLocalhost=no",
"-o",
"NumberOfPasswordPrompts=0",
"-o",
"PasswordAuthentication=no",
"-o",
"KbdInteractiveAuthentication=no",
"-o",
"PreferredAuthentications=publickey",
"-o",
"ConnectTimeout=5",
"-o",
"ConnectionAttempts=1",
"-o",
"ServerAliveInterval=5",
"-o",
"ServerAliveCountMax=1",
"-o",
"ClearAllForwardings=yes",
"-o",
"ForwardAgent=no",
"-o",
"ForwardX11=no",
"-o",
"ForwardX11Trusted=no",
"-o",
"Tunnel=no",
"-o",
"UpdateHostKeys=no",
"-o",
"ControlMaster=no",
"-o",
"ControlPath=none",
"-o",
"PermitLocalCommand=no",
"-o",
"RemoteCommand=none",
"-o",
"ProxyCommand=none",
"-o",
"ProxyJump=none",
"-o",
"KnownHostsCommand=none",
"-o",
"LogLevel=ERROR",
];
}
6 changes: 3 additions & 3 deletions src/lib/inference/vllm-station-ssh-binding.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import {
loadDualStationSshBindingHandoff,
type QualifiedStationSshIdentity,
stationKnownHostsDigest,
strictStationSshTransportArgs,
writeDualStationSshBinding,
} from "./vllm-station-ssh-binding";
import { strictVllmSshTransportArgs } from "./serving/vllm-ssh-transport-policy";

const PEER_TARGET = "station@10.10.0.2";
const PEER_HOST = "10.10.0.2";
Expand Down Expand Up @@ -162,8 +162,8 @@ exit "${"${NEMOCLAW_TEST_DOCKER_EXIT:-0}"}"
const binding = writeBinding();
const args = dualStationPinnedSshArgs(binding);

expect(args.slice(0, strictStationSshTransportArgs().length)).toEqual(
strictStationSshTransportArgs(),
expect(args.slice(0, strictVllmSshTransportArgs().length)).toEqual(
strictVllmSshTransportArgs(),
);
expect(args).toEqual(
expect.arrayContaining([
Expand Down
62 changes: 3 additions & 59 deletions src/lib/inference/vllm-station-ssh-binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import fs from "node:fs";
import net from "node:net";
import path from "node:path";

import { strictVllmSshTransportArgs } from "./serving/vllm-ssh-transport-policy.ts";

export const NEMOCLAW_DGX_STATION_SSH_BINDING_ENV = "NEMOCLAW_DGX_STATION_SSH_BINDING";

const BINDING_SCHEMA_VERSION = 2;
Expand Down Expand Up @@ -287,72 +289,14 @@ function shellQuote(value: string): string {
return `'${value.replaceAll("'", `'"'"'`)}'`;
}

export function strictStationSshTransportArgs(): string[] {
return [
"-T",
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=yes",
"-o",
"VerifyHostKeyDNS=no",
"-o",
"NoHostAuthenticationForLocalhost=no",
"-o",
"NumberOfPasswordPrompts=0",
"-o",
"PasswordAuthentication=no",
"-o",
"KbdInteractiveAuthentication=no",
"-o",
"PreferredAuthentications=publickey",
"-o",
"ConnectTimeout=5",
"-o",
"ConnectionAttempts=1",
"-o",
"ServerAliveInterval=5",
"-o",
"ServerAliveCountMax=1",
"-o",
"ClearAllForwardings=yes",
"-o",
"ForwardAgent=no",
"-o",
"ForwardX11=no",
"-o",
"ForwardX11Trusted=no",
"-o",
"Tunnel=no",
"-o",
"UpdateHostKeys=no",
"-o",
"ControlMaster=no",
"-o",
"ControlPath=none",
"-o",
"PermitLocalCommand=no",
"-o",
"RemoteCommand=none",
"-o",
"ProxyCommand=none",
"-o",
"ProxyJump=none",
"-o",
"KnownHostsCommand=none",
"-o",
"LogLevel=ERROR",
];
}

type PinnedStationEndpoint = Pick<
DualStationSshBinding,
"knownHostsFile" | "lookupHost" | "port" | "resolvedHost" | "sshUser"
>;

function pinnedOptionArgs(binding: PinnedStationEndpoint): string[] {
return [
...strictStationSshTransportArgs(),
...strictVllmSshTransportArgs(),
"-o",
`UserKnownHostsFile=${binding.knownHostsFile}`,
"-o",
Expand Down
2 changes: 1 addition & 1 deletion src/lib/onboard/dockerfile-patch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ describe("dockerfile patch helpers", () => {
{ channelId: "telegram", active: true },
],
agentRender: [
{ agent: "openclaw", channelId: "discord", target: "config", path: ["discord"] },
{ agent: "openclaw", channelId: "discord", target: "openclaw.json", path: ["discord"] },
],
});
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-dockerfile-plan-"));
Expand Down
Loading
Loading