mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix failing to start shell being hidden from user
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
8f9dd11420
commit
ed6f5226bd
@ -10,6 +10,7 @@ export enum TerminalChannels {
|
|||||||
CONNECTED = "connected",
|
CONNECTED = "connected",
|
||||||
RESIZE = "resize",
|
RESIZE = "resize",
|
||||||
PING = "ping",
|
PING = "ping",
|
||||||
|
ERROR = "error",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TerminalMessage = {
|
export type TerminalMessage = {
|
||||||
@ -28,4 +29,7 @@ export type TerminalMessage = {
|
|||||||
};
|
};
|
||||||
} | {
|
} | {
|
||||||
type: TerminalChannels.PING;
|
type: TerminalChannels.PING;
|
||||||
|
} | {
|
||||||
|
type: TerminalChannels.ERROR;
|
||||||
|
data: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import type { ModifyTerminalShellEnv } from "../shell-env-modifier/modify-termin
|
|||||||
import type { JoinPaths } from "../../../common/path/join-paths.injectable";
|
import type { JoinPaths } from "../../../common/path/join-paths.injectable";
|
||||||
import type { GetDirnameOfPath } from "../../../common/path/get-dirname.injectable";
|
import type { GetDirnameOfPath } from "../../../common/path/get-dirname.injectable";
|
||||||
import type { GetBasenameOfPath } from "../../../common/path/get-basename.injectable";
|
import type { GetBasenameOfPath } from "../../../common/path/get-basename.injectable";
|
||||||
|
import { TerminalChannels } from "../../../common/terminal/channels";
|
||||||
|
|
||||||
export interface LocalShellSessionDependencies extends ShellSessionDependencies {
|
export interface LocalShellSessionDependencies extends ShellSessionDependencies {
|
||||||
readonly directoryForBinaries: string;
|
readonly directoryForBinaries: string;
|
||||||
@ -41,7 +42,13 @@ export class LocalShellSession extends ShellSession {
|
|||||||
const shell = env.PTYSHELL;
|
const shell = env.PTYSHELL;
|
||||||
|
|
||||||
if (!shell) {
|
if (!shell) {
|
||||||
throw new Error("PTYSHELL is not defined with the environment");
|
this.send({
|
||||||
|
type: TerminalChannels.ERROR,
|
||||||
|
data: "PTYSHELL is not defined with the environment",
|
||||||
|
});
|
||||||
|
this.dependencies.logger.warn(`[LOCAL-SHELL-SESSION]: PTYSHELL env var is not defined for ${this.terminalId}`);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = await this.getShellArgs(shell);
|
const args = await this.getShellArgs(shell);
|
||||||
|
|||||||
@ -156,23 +156,34 @@ export abstract class ShellSession {
|
|||||||
|
|
||||||
protected abstract get cwd(): string | undefined;
|
protected abstract get cwd(): string | undefined;
|
||||||
|
|
||||||
protected ensureShellProcess(shell: string, args: string[], env: Partial<Record<string, string>>, cwd: string): { shellProcess: pty.IPty; resume: boolean } {
|
protected ensureShellProcess(shell: string, args: string[], env: Partial<Record<string, string>>, cwd: string): { shellProcess: pty.IPty; resume: boolean } | null {
|
||||||
const resume = ShellSession.processes.has(this.terminalId);
|
try {
|
||||||
const shellProcess = getOrInsertWith(ShellSession.processes, this.terminalId, () => (
|
const resume = ShellSession.processes.has(this.terminalId);
|
||||||
this.dependencies.spawnPty(shell, args, {
|
|
||||||
rows: 30,
|
|
||||||
cols: 80,
|
|
||||||
cwd,
|
|
||||||
env,
|
|
||||||
name: "xterm-256color",
|
|
||||||
// TODO: Something else is broken here so we need to force the use of winPty on windows
|
|
||||||
useConpty: false,
|
|
||||||
})
|
|
||||||
));
|
|
||||||
|
|
||||||
this.dependencies.logger.info(`[SHELL-SESSION]: PTY for ${this.terminalId} is ${resume ? "resumed" : "started"} with PID=${shellProcess.pid}`);
|
const shellProcess = getOrInsertWith(ShellSession.processes, this.terminalId, () => (
|
||||||
|
this.dependencies.spawnPty(shell, args, {
|
||||||
|
rows: 30,
|
||||||
|
cols: 80,
|
||||||
|
cwd,
|
||||||
|
env,
|
||||||
|
name: "xterm-256color",
|
||||||
|
// TODO: Something else is broken here so we need to force the use of winPty on windows
|
||||||
|
useConpty: false,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
|
||||||
return { shellProcess, resume };
|
this.dependencies.logger.info(`[SHELL-SESSION]: PTY for ${this.terminalId} is ${resume ? "resumed" : "started"} with PID=${shellProcess.pid}`);
|
||||||
|
|
||||||
|
return { shellProcess, resume };
|
||||||
|
} catch (error) {
|
||||||
|
this.send({
|
||||||
|
type: TerminalChannels.ERROR,
|
||||||
|
data: `Failed to start shell (${shell}): ${error}`,
|
||||||
|
});
|
||||||
|
this.dependencies.logger.warn(`[SHELL-SESSION]: Failed to start PTY for ${this.terminalId}: ${error}`, { shell });
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(protected readonly dependencies: ShellSessionDependencies, { kubectl, websocket, cluster, tabId: terminalId }: ShellSessionArgs) {
|
constructor(protected readonly dependencies: ShellSessionDependencies, { kubectl, websocket, cluster, tabId: terminalId }: ShellSessionArgs) {
|
||||||
@ -231,7 +242,13 @@ export abstract class ShellSession {
|
|||||||
|
|
||||||
protected async openShellProcess(shell: string, args: string[], env: Record<string, string | undefined>) {
|
protected async openShellProcess(shell: string, args: string[], env: Record<string, string | undefined>) {
|
||||||
const cwd = await this.getCwd(env);
|
const cwd = await this.getCwd(env);
|
||||||
const { shellProcess, resume } = this.ensureShellProcess(shell, args, env, cwd);
|
const ensured = this.ensureShellProcess(shell, args, env, cwd);
|
||||||
|
|
||||||
|
if (!ensured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { shellProcess, resume } = ensured;
|
||||||
|
|
||||||
if (resume) {
|
if (resume) {
|
||||||
this.send({ type: TerminalChannels.CONNECTED });
|
this.send({ type: TerminalChannels.CONNECTED });
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export interface TerminalApiQuery extends Record<string, string | undefined> {
|
|||||||
export interface TerminalEvents extends WebSocketEvents {
|
export interface TerminalEvents extends WebSocketEvents {
|
||||||
ready: () => void;
|
ready: () => void;
|
||||||
connected: () => void;
|
connected: () => void;
|
||||||
|
error: (error: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TerminalApiDependencies extends WebSocketApiDependencies {
|
export interface TerminalApiDependencies extends WebSocketApiDependencies {
|
||||||
@ -145,6 +146,9 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
|||||||
case TerminalChannels.CONNECTED:
|
case TerminalChannels.CONNECTED:
|
||||||
this.emit("connected");
|
this.emit("connected");
|
||||||
break;
|
break;
|
||||||
|
case TerminalChannels.ERROR:
|
||||||
|
this.emit("error", message.data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this.dependencies.logger.warn(`[TERMINAL-API]: unknown or unhandleable message type`, message);
|
this.dependencies.logger.warn(`[TERMINAL-API]: unknown or unhandleable message type`, message);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -104,6 +104,7 @@ export class Terminal {
|
|||||||
this.api.once("ready", clearOnce);
|
this.api.once("ready", clearOnce);
|
||||||
this.api.once("connected", clearOnce);
|
this.api.once("connected", clearOnce);
|
||||||
this.api.on("data", this.onApiData);
|
this.api.on("data", this.onApiData);
|
||||||
|
this.api.on("error", this.onApiError);
|
||||||
window.addEventListener("resize", this.onResize);
|
window.addEventListener("resize", this.onResize);
|
||||||
|
|
||||||
const linkProvider = new LinkProvider(
|
const linkProvider = new LinkProvider(
|
||||||
@ -152,6 +153,10 @@ export class Terminal {
|
|||||||
this.xterm.write(data);
|
this.xterm.write(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onApiError = (data: string) => {
|
||||||
|
this.xterm.writeln(data);
|
||||||
|
};
|
||||||
|
|
||||||
onData = (data: string) => {
|
onData = (data: string) => {
|
||||||
if (!this.api.isReady) return;
|
if (!this.api.isReady) return;
|
||||||
this.api.sendMessage({
|
this.api.sendMessage({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user