fix: isolate trans ssh bootstrap
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
export interface RemoteCliOptions {
|
||||
host: string | null;
|
||||
user: string;
|
||||
port: number;
|
||||
projectRoot: string;
|
||||
identityFile: string | null;
|
||||
transport: "auto" | "frontend" | "ssh";
|
||||
args: string[];
|
||||
}
|
||||
|
||||
const hostOptions = new Set(["--main-server-ip", "--main-server", "--server"]);
|
||||
const userOptions = new Set(["--main-server-user", "--server-user"]);
|
||||
const portOptions = new Set(["--main-server-port", "--server-port"]);
|
||||
const rootOptions = new Set(["--main-server-root", "--server-root"]);
|
||||
const keyOptions = new Set(["--main-server-key", "--server-key"]);
|
||||
const transportOptions = new Set(["--main-server-transport", "--server-transport"]);
|
||||
|
||||
function positivePort(raw: string, option: string): number {
|
||||
const value = Number(raw);
|
||||
if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new Error(`${option} must be a TCP port from 1 to 65535`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function requiredValue(argv: string[], index: number, option: string): string {
|
||||
const value = argv[index + 1];
|
||||
if (value === undefined || value.length === 0) throw new Error(`${option} requires a non-empty value`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function transportValue(raw: string, option: string): RemoteCliOptions["transport"] {
|
||||
if (raw === "auto" || raw === "frontend" || raw === "ssh") return raw;
|
||||
throw new Error(`${option} must be one of: auto, frontend, ssh`);
|
||||
}
|
||||
|
||||
export function extractRemoteCliOptions(argv: string[]): RemoteCliOptions {
|
||||
const rest: string[] = [];
|
||||
const options: RemoteCliOptions = {
|
||||
host: null,
|
||||
user: "root",
|
||||
port: 22,
|
||||
projectRoot: "/root/unidesk",
|
||||
identityFile: null,
|
||||
transport: "auto",
|
||||
args: rest,
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index] ?? "";
|
||||
if (arg === "--") {
|
||||
if (rest.length === 0) {
|
||||
rest.push(...argv.slice(index + 1));
|
||||
break;
|
||||
}
|
||||
rest.push(arg);
|
||||
continue;
|
||||
}
|
||||
if (hostOptions.has(arg)) {
|
||||
options.host = requiredValue(argv, index, arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (userOptions.has(arg)) {
|
||||
options.user = requiredValue(argv, index, arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (portOptions.has(arg)) {
|
||||
options.port = positivePort(requiredValue(argv, index, arg), arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (rootOptions.has(arg)) {
|
||||
options.projectRoot = requiredValue(argv, index, arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (keyOptions.has(arg)) {
|
||||
options.identityFile = requiredValue(argv, index, arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (transportOptions.has(arg)) {
|
||||
options.transport = transportValue(requiredValue(argv, index, arg), arg);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
rest.push(arg);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -3180,8 +3180,8 @@ async function runSshStreamRemoteCommand(
|
||||
}
|
||||
|
||||
async function runRemoteSsh(config: UniDeskConfig, host: string, providerId: string, args: string[]): Promise<number> {
|
||||
const { runRemoteCli } = await import("./remote");
|
||||
return await runRemoteCli({
|
||||
const { runRemoteSshCli } = await import("./remote-ssh");
|
||||
return await runRemoteSshCli({
|
||||
host,
|
||||
user: "root",
|
||||
port: 22,
|
||||
@@ -3212,7 +3212,7 @@ export async function runSshCommandCapture(config: UniDeskConfig, target: string
|
||||
}
|
||||
|
||||
async function runRemoteSshCapture(config: UniDeskConfig, host: string, target: string, args: string[], input?: string): Promise<SshCaptureResult> {
|
||||
const { runRemoteSshCommandCapture } = await import("./remote");
|
||||
const { runRemoteSshCommandCapture } = await import("./remote-ssh");
|
||||
return await runRemoteSshCommandCapture(config, host, target, args, input);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { readConfig } from "./src/config";
|
||||
import { isHelpToken, sshHelp } from "./src/help";
|
||||
import { emitError, emitJson } from "./src/output";
|
||||
import { extractRemoteCliOptions } from "./src/remote-options";
|
||||
import { runRemoteSshCli } from "./src/remote-ssh";
|
||||
import { runSsh } from "./src/ssh";
|
||||
|
||||
const remoteOptions = extractRemoteCliOptions(process.argv.slice(2));
|
||||
const args = normalizeSshCommandArgs(remoteOptions.args);
|
||||
const commandName = args.join(" ") || "ssh";
|
||||
|
||||
function normalizeSshCommandArgs(rawArgs: string[]): string[] {
|
||||
if (rawArgs[0] === "ssh") return rawArgs;
|
||||
return ["ssh", ...rawArgs];
|
||||
}
|
||||
|
||||
function isGhContentRouteTarget(target: string | undefined): boolean {
|
||||
return typeof target === "string" && target.startsWith("gh:");
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const [top, sub, third] = args;
|
||||
if (top !== "ssh") throw new Error(`ssh-cli supports only the ssh command, got: ${top || "<empty>"}`);
|
||||
|
||||
if (sub === undefined || isHelpToken(sub) || (isHelpToken(third) && args.length === 3)) {
|
||||
emitJson(commandName, sshHelp());
|
||||
return;
|
||||
}
|
||||
|
||||
if (remoteOptions.host !== null) {
|
||||
process.exitCode = await runRemoteSshCli({ ...remoteOptions, args }, readConfig());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isGhContentRouteTarget(sub)) {
|
||||
const { runGhContentRoute } = await import("./src/gh-route");
|
||||
process.exitCode = await runGhContentRoute(sub, args.slice(2));
|
||||
return;
|
||||
}
|
||||
|
||||
process.exitCode = await runSsh(readConfig(), sub, args.slice(2));
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
emitError(commandName, error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
set -eu
|
||||
|
||||
repo=${UNIDESK_TRAN_REPO_ROOT:-/root/unidesk}
|
||||
if [ ! -f "$repo/scripts/cli.ts" ]; then
|
||||
if [ ! -f "$repo/scripts/ssh-cli.ts" ]; then
|
||||
self_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
repo=$(CDPATH= cd -- "$self_dir/.." && pwd)
|
||||
fi
|
||||
@@ -49,8 +49,8 @@ if [ -n "${CODE_QUEUE_SERVICE_ROLE:-}" ] || [ -n "${CODE_QUEUE_INSTANCE_ID:-}" ]
|
||||
fi
|
||||
|
||||
if [ "$runner_env" = 1 ] && [ -n "$host" ] && [ "${UNIDESK_TRAN_LOCAL:-}" != "1" ]; then
|
||||
bun "$repo/scripts/cli.ts" --main-server-ip "$host" ssh "$@"
|
||||
bun "$repo/scripts/ssh-cli.ts" --main-server-ip "$host" ssh "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
bun "$repo/scripts/cli.ts" ssh "$@"
|
||||
bun "$repo/scripts/ssh-cli.ts" ssh "$@"
|
||||
|
||||
+2
-2
@@ -2,9 +2,9 @@
|
||||
set -eu
|
||||
|
||||
repo=${UNIDESK_TRANS_REPO_ROOT:-/root/unidesk}
|
||||
if [ ! -f "$repo/scripts/cli.ts" ]; then
|
||||
if [ ! -f "$repo/scripts/ssh-cli.ts" ]; then
|
||||
self_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
repo=$(CDPATH= cd -- "$self_dir/.." && pwd)
|
||||
fi
|
||||
|
||||
exec bun "$repo/scripts/cli.ts" ssh "$@"
|
||||
exec bun "$repo/scripts/ssh-cli.ts" ssh "$@"
|
||||
|
||||
Reference in New Issue
Block a user