fix: support k3s log selector

This commit is contained in:
Codex
2026-06-01 14:42:42 +00:00
parent 0cecdd9ed3
commit 2845db3365
3 changed files with 25 additions and 4 deletions
+1
View File
@@ -322,6 +322,7 @@ bun scripts/cli.ts ssh G14:k3s kubectl get pipelineruns -n hwlab-ci
printf 'kubectl get deploy -n hwlab-dev\n' | bun scripts/cli.ts ssh D601:k3s script
bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api logs --tail 80
bun scripts/cli.ts ssh G14:k3s logs --namespace=devops-infra --deployment=git-mirror-http --tail=80
bun scripts/cli.ts ssh G14:k3s logs -n agentrun-ci -l tekton.dev/pipelineRun=agentrun-v01-ci-xxxx --tail=120
bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api node -e 'console.log(process.version)'
bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api/app pwd
printf 'printf "pod=%s\n" "$HOSTNAME"\n' | bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api script
+1
View File
@@ -185,6 +185,7 @@ export function sshHelp(): unknown {
"bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api node -e 'console.log(process.version)'",
"bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api script <<'SCRIPT'",
"bun scripts/cli.ts ssh D601:k3s:hwlab-dev:hwlab-cloud-api logs --tail 80",
"bun scripts/cli.ts ssh G14:k3s logs -n agentrun-ci -l tekton.dev/pipelineRun=<run> --tail 120",
],
notes: [
"ssh --help and ssh <route> --help print this JSON help and never open an interactive session.",
+23 -4
View File
@@ -1518,6 +1518,7 @@ function buildK3sGuardCommand(providerId: string): string {
interface K3sTargetOptions {
namespace: string | null;
resource: string | null;
selector: string | null;
container: string | null;
workspace: string | null;
stdin: boolean;
@@ -1531,11 +1532,13 @@ interface ParseK3sTargetOptionsOptions {
requireCommand: boolean;
allowCommand?: boolean;
allowShell?: boolean;
allowSelector?: boolean;
}
function buildK3sExecCommand(args: string[]): string {
const parsed = parseK3sTargetOptions(args, "ssh k3s exec", { requireCommand: true });
if (parsed.namespace === null) throw new Error("ssh k3s exec requires --namespace <name>");
if (parsed.selector !== null) throw new Error("ssh k3s exec does not support --selector");
if (parsed.resource === null) throw new Error("ssh k3s exec requires --deployment <name>, --pod <name> or --resource <type/name>");
const kubectlArgs = [
"exec",
@@ -1562,6 +1565,7 @@ function buildK3sScriptOperation(args: string[]): ParsedSshArgs {
function buildK3sStdinScriptCommand(parsed: K3sTargetOptions): string {
if (parsed.namespace === null && parsed.resource === null) return buildK3sHostScriptCommand(parsed);
if (parsed.namespace === null) throw new Error("ssh k3s script target requires --namespace <name>");
if (parsed.selector !== null) throw new Error("ssh k3s script does not support --selector");
if (parsed.resource === null) throw new Error("ssh k3s script target requires --deployment <name>, --pod <name> or --resource <type/name>");
if (parsed.tty) throw new Error("ssh k3s script does not support --tty; stdin is reserved for the script body");
const shell = parsed.shell ?? "sh";
@@ -1580,6 +1584,7 @@ function buildK3sStdinScriptCommand(parsed: K3sTargetOptions): string {
function buildK3sInlineScriptCommand(parsed: K3sTargetOptions): string {
if (parsed.command.length === 0) throw new Error("ssh k3s script -- requires a command");
if (parsed.selector !== null) throw new Error("ssh k3s script -- does not support --selector");
if (parsed.tty) throw new Error("ssh k3s script does not support --tty; stdin is reserved for the script body");
if (parsed.stdin) throw new Error("ssh k3s script -- does not accept --stdin");
const command = parsed.command.length === 1 ? ["sh", "-c", shellScriptWithCompatibility(parsed.command[0] ?? "")] : parsed.command;
@@ -1661,15 +1666,16 @@ function parseShellStringOperationArgs(args: string[], commandName: string): { s
}
function buildK3sLogsCommand(args: string[]): string {
const parsed = parseK3sTargetOptions(args, "ssh k3s logs", { requireCommand: false });
const parsed = parseK3sTargetOptions(args, "ssh k3s logs", { requireCommand: false, allowSelector: true });
if (parsed.namespace === null) throw new Error("ssh k3s logs requires --namespace <name>");
if (parsed.resource === null) throw new Error("ssh k3s logs requires --deployment <name>, --pod <name> or --resource <type/name>");
if (parsed.resource === null && parsed.selector === null) throw new Error("ssh k3s logs requires --deployment <name>, --pod <name>, --resource <type/name> or --selector <label-selector>");
if (parsed.resource !== null && parsed.selector !== null) throw new Error("ssh k3s logs accepts either a resource or --selector, not both");
if (parsed.stdin || parsed.tty) throw new Error("ssh k3s logs does not support --stdin or --tty");
if (parsed.workspace !== null) throw new Error("ssh k3s logs does not accept --workdir");
const kubectlArgs = [
"logs",
"-n", parsed.namespace,
parsed.resource,
...(parsed.selector === null ? [parsed.resource ?? ""] : ["-l", parsed.selector]),
...(parsed.container === null ? [] : ["-c", parsed.container]),
...parsed.kubectlOptions,
];
@@ -1679,6 +1685,7 @@ function buildK3sLogsCommand(args: string[]): string {
function parseK3sTargetOptions(args: string[], commandName: string, options: ParseK3sTargetOptionsOptions): K3sTargetOptions {
let namespace: string | null = null;
let resource: string | null = null;
let selector: string | null = null;
let container: string | null = null;
let workspace: string | null = null;
let stdin = false;
@@ -1738,6 +1745,18 @@ function parseK3sTargetOptions(args: string[], commandName: string, options: Par
resource = normalizeK3sResource(resourceValue);
continue;
}
if (arg === "--selector" || arg === "-l") {
if (options.allowSelector !== true) throw new Error(`${commandName} does not support ${arg}`);
selector = k3sOptionValue(args, index, `${commandName} ${arg}`);
index += 1;
continue;
}
const selectorValue = k3sEqualsOptionValue(arg, "--selector", commandName) ?? k3sEqualsOptionValue(arg, "-l", commandName);
if (selectorValue !== null) {
if (options.allowSelector !== true) throw new Error(`${commandName} does not support ${arg.split("=", 1)[0]}`);
selector = selectorValue;
continue;
}
if (arg === "--container" || arg === "-c") {
container = k3sOptionValue(args, index, `${commandName} ${arg}`);
index += 1;
@@ -1819,7 +1838,7 @@ function parseK3sTargetOptions(args: string[], commandName: string, options: Par
if (options.requireCommand && command.length === 0) throw new Error(`${commandName} requires -- <command> [args...]`);
if (!options.requireCommand && options.allowCommand !== true && command.length > 0) throw new Error(`${commandName} does not accept a command after --`);
return { namespace, resource, container, workspace, stdin, tty, shell, command, kubectlOptions };
return { namespace, resource, selector, container, workspace, stdin, tty, shell, command, kubectlOptions };
}
function k3sEqualsOptionValue(arg: string, option: string, commandName: string): string | null {