mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-10 18:33:52 +01:00
parent
f9b0abdd14
commit
ea6f3d1579
@ -55,20 +55,16 @@ export const startCloudShellTerminal = async (terminal: Terminal, shellType: Ter
|
|||||||
TelemetryProcessor.trace(
|
TelemetryProcessor.trace(
|
||||||
Action.CloudShellUserConsent,
|
Action.CloudShellUserConsent,
|
||||||
consentGranted ? ActionModifiers.Success : ActionModifiers.Cancel,
|
consentGranted ? ActionModifiers.Success : ActionModifiers.Cancel,
|
||||||
{ dataExplorerArea: Areas.CloudShell },
|
{
|
||||||
|
dataExplorerArea: Areas.CloudShell,
|
||||||
|
shellType: TerminalKind[shellType],
|
||||||
|
isConsent: consentGranted,
|
||||||
|
region: resolvedRegion,
|
||||||
|
},
|
||||||
|
startKey,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!consentGranted) {
|
if (!consentGranted) {
|
||||||
TelemetryProcessor.traceCancel(
|
|
||||||
Action.CloudShellTerminalSession,
|
|
||||||
{
|
|
||||||
shellType: TerminalKind[shellType],
|
|
||||||
dataExplorerArea: Areas.CloudShell,
|
|
||||||
region: resolvedRegion,
|
|
||||||
isConsent: false,
|
|
||||||
},
|
|
||||||
startKey,
|
|
||||||
);
|
|
||||||
terminal.writeln(
|
terminal.writeln(
|
||||||
formatErrorMessage("Session ended. Please close this tab and initiate a new shell session if needed."),
|
formatErrorMessage("Session ended. Please close this tab and initiate a new shell session if needed."),
|
||||||
);
|
);
|
||||||
@ -262,28 +258,27 @@ export const configureSocketConnection = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sendTerminalStartupCommands = (socket: WebSocket, initCommands: string): void => {
|
export const sendTerminalStartupCommands = (socket: WebSocket, initCommands: string): void => {
|
||||||
|
// ensures connections don't remain open indefinitely by implementing an automatic timeout after 120 minutes.
|
||||||
|
const keepSocketAlive = (socket: WebSocket) => {
|
||||||
|
if (socket.readyState === WebSocket.OPEN) {
|
||||||
|
if (pingCount >= MAX_PING_COUNT) {
|
||||||
|
socket.close();
|
||||||
|
} else {
|
||||||
|
pingCount++;
|
||||||
|
// The code uses a recursive setTimeout pattern rather than setInterval,
|
||||||
|
// which ensures each new ping only happens after the previous one completes
|
||||||
|
// and naturally stops if the socket closes.
|
||||||
|
keepAliveID = setTimeout(() => keepSocketAlive(socket), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
if (socket && socket.readyState === WebSocket.OPEN) {
|
||||||
socket.send(initCommands);
|
socket.send(initCommands);
|
||||||
|
keepSocketAlive(socket);
|
||||||
} else {
|
} else {
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
socket.send(initCommands);
|
socket.send(initCommands);
|
||||||
|
|
||||||
// ensures connections don't remain open indefinitely by implementing an automatic timeout after 20 minutes.
|
|
||||||
const keepSocketAlive = (socket: WebSocket) => {
|
|
||||||
if (socket.readyState === WebSocket.OPEN) {
|
|
||||||
if (pingCount >= MAX_PING_COUNT) {
|
|
||||||
socket.close();
|
|
||||||
} else {
|
|
||||||
socket.send("");
|
|
||||||
pingCount++;
|
|
||||||
// The code uses a recursive setTimeout pattern rather than setInterval,
|
|
||||||
// which ensures each new ping only happens after the previous one completes
|
|
||||||
// and naturally stops if the socket closes.
|
|
||||||
keepAliveID = setTimeout(() => keepSocketAlive(socket), 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
keepSocketAlive(socket);
|
keepSocketAlive(socket);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,30 @@ export abstract class AbstractShellHandler {
|
|||||||
|
|
||||||
return allCommands.join("\n").concat("\n");
|
return allCommands.join("\n").concat("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup commands for MongoDB shell:
|
||||||
|
*
|
||||||
|
* 1. Check if mongosh is already installed
|
||||||
|
* 2. Download mongosh package if not installed
|
||||||
|
* 3. Extract the package to access mongosh binaries
|
||||||
|
* 4. Move extracted files to ~/mongosh directory
|
||||||
|
* 5. Add mongosh binary path to system PATH
|
||||||
|
* 6. Apply PATH changes by sourcing .bashrc
|
||||||
|
*
|
||||||
|
* Each command runs conditionally only if mongosh
|
||||||
|
* is not already present in the environment.
|
||||||
|
*/
|
||||||
|
protected mongoShellSetupCommands(): string[] {
|
||||||
|
const PACKAGE_VERSION: string = "2.5.0";
|
||||||
|
return [
|
||||||
|
"if ! command -v mongosh &> /dev/null; then echo '⚠️ mongosh not found. Installing...'; fi",
|
||||||
|
`if ! command -v mongosh &> /dev/null; then curl -LO https://downloads.mongodb.com/compass/mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
||||||
|
`if ! command -v mongosh &> /dev/null; then tar -xvzf mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
||||||
|
`if ! command -v mongosh &> /dev/null; then mkdir -p ~/mongosh/bin && mv mongosh-${PACKAGE_VERSION}-linux-x64/bin/mongosh ~/mongosh/bin/ && chmod +x ~/mongosh/bin/mongosh; fi`,
|
||||||
|
`if ! command -v mongosh &> /dev/null; then rm -rf mongosh-${PACKAGE_VERSION}-linux-x64 mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
||||||
|
"if ! command -v mongosh &> /dev/null; then echo 'export PATH=$HOME/mongosh/bin:$PATH' >> ~/.bashrc; fi",
|
||||||
|
"source ~/.bashrc",
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ describe("MongoShellHandler", () => {
|
|||||||
const commands = mongoShellHandler.getSetUpCommands();
|
const commands = mongoShellHandler.getSetUpCommands();
|
||||||
|
|
||||||
expect(Array.isArray(commands)).toBe(true);
|
expect(Array.isArray(commands)).toBe(true);
|
||||||
expect(commands.length).toBe(6);
|
expect(commands.length).toBe(7);
|
||||||
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz");
|
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,8 +2,6 @@ import { userContext } from "../../../../UserContext";
|
|||||||
import { getHostFromUrl } from "../Utils/CommonUtils";
|
import { getHostFromUrl } from "../Utils/CommonUtils";
|
||||||
import { AbstractShellHandler } from "./AbstractShellHandler";
|
import { AbstractShellHandler } from "./AbstractShellHandler";
|
||||||
|
|
||||||
const PACKAGE_VERSION: string = "2.5.0";
|
|
||||||
|
|
||||||
export class MongoShellHandler extends AbstractShellHandler {
|
export class MongoShellHandler extends AbstractShellHandler {
|
||||||
private _key: string;
|
private _key: string;
|
||||||
private _endpoint: string | undefined;
|
private _endpoint: string | undefined;
|
||||||
@ -18,14 +16,7 @@ export class MongoShellHandler extends AbstractShellHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getSetUpCommands(): string[] {
|
public getSetUpCommands(): string[] {
|
||||||
return [
|
return this.mongoShellSetupCommands();
|
||||||
"if ! command -v mongosh &> /dev/null; then echo '⚠️ mongosh not found. Installing...'; fi",
|
|
||||||
`if ! command -v mongosh &> /dev/null; then curl -LO https://downloads.mongodb.com/compass/mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
|
||||||
`if ! command -v mongosh &> /dev/null; then tar -xvzf mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
|
||||||
`if ! command -v mongosh &> /dev/null; then mkdir -p ~/mongosh && mv mongosh-${PACKAGE_VERSION}-linux-x64/* ~/mongosh/; fi`,
|
|
||||||
"if ! command -v mongosh &> /dev/null; then echo 'export PATH=$HOME/mongosh/bin:$PATH' >> ~/.bashrc; fi",
|
|
||||||
"source ~/.bashrc",
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConnectionCommand(): string {
|
public getConnectionCommand(): string {
|
||||||
|
@ -44,7 +44,7 @@ describe("VCoreMongoShellHandler", () => {
|
|||||||
const commands = vcoreMongoShellHandler.getSetUpCommands();
|
const commands = vcoreMongoShellHandler.getSetUpCommands();
|
||||||
|
|
||||||
expect(Array.isArray(commands)).toBe(true);
|
expect(Array.isArray(commands)).toBe(true);
|
||||||
expect(commands.length).toBe(6);
|
expect(commands.length).toBe(7);
|
||||||
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz");
|
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz");
|
||||||
expect(commands[0]).toContain("mongosh not found");
|
expect(commands[0]).toContain("mongosh not found");
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { userContext } from "../../../../UserContext";
|
import { userContext } from "../../../../UserContext";
|
||||||
import { AbstractShellHandler } from "./AbstractShellHandler";
|
import { AbstractShellHandler } from "./AbstractShellHandler";
|
||||||
|
|
||||||
const PACKAGE_VERSION: string = "2.5.0";
|
|
||||||
|
|
||||||
export class VCoreMongoShellHandler extends AbstractShellHandler {
|
export class VCoreMongoShellHandler extends AbstractShellHandler {
|
||||||
private _endpoint: string | undefined;
|
private _endpoint: string | undefined;
|
||||||
|
|
||||||
@ -15,28 +13,8 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
|
|||||||
return "MongoDB VCore";
|
return "MongoDB VCore";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup commands for MongoDB VCore shell:
|
|
||||||
*
|
|
||||||
* 1. Check if mongosh is already installed
|
|
||||||
* 2. Download mongosh package if not installed
|
|
||||||
* 3. Extract the package to access mongosh binaries
|
|
||||||
* 4. Move extracted files to ~/mongosh directory
|
|
||||||
* 5. Add mongosh binary path to system PATH
|
|
||||||
* 6. Apply PATH changes by sourcing .bashrc
|
|
||||||
*
|
|
||||||
* Each command runs conditionally only if mongosh
|
|
||||||
* is not already present in the environment.
|
|
||||||
*/
|
|
||||||
public getSetUpCommands(): string[] {
|
public getSetUpCommands(): string[] {
|
||||||
return [
|
return this.mongoShellSetupCommands();
|
||||||
"if ! command -v mongosh &> /dev/null; then echo '⚠️ mongosh not found. Installing...'; fi",
|
|
||||||
`if ! command -v mongosh &> /dev/null; then curl -LO https://downloads.mongodb.com/compass/mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
|
||||||
`if ! command -v mongosh &> /dev/null; then tar -xvzf mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
|
|
||||||
`if ! command -v mongosh &> /dev/null; then mkdir -p ~/mongosh && mv mongosh-${PACKAGE_VERSION}-linux-x64/* ~/mongosh/; fi`,
|
|
||||||
"if ! command -v mongosh &> /dev/null; then echo 'export PATH=$HOME/mongosh/bin:$PATH' >> ~/.bashrc; fi",
|
|
||||||
"source ~/.bashrc",
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConnectionCommand(): string {
|
public getConnectionCommand(): string {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { AbstractShellHandler } from "Explorer/Tabs/CloudShellTab/ShellTypes/AbstractShellHandler";
|
|
||||||
import { IDisposable, ITerminalAddon, Terminal } from "@xterm/xterm";
|
import { IDisposable, ITerminalAddon, Terminal } from "@xterm/xterm";
|
||||||
|
import { AbstractShellHandler } from "../ShellTypes/AbstractShellHandler";
|
||||||
|
import { formatErrorMessage } from "./TerminalLogFormats";
|
||||||
|
|
||||||
interface IAttachOptions {
|
interface IAttachOptions {
|
||||||
bidirectional?: boolean;
|
bidirectional?: boolean;
|
||||||
@ -56,8 +57,27 @@ export class AttachAddon implements ITerminalAddon {
|
|||||||
this._disposables.push(terminal.onBinary((data) => this._sendBinary(data)));
|
this._disposables.push(terminal.onBinary((data) => this._sendBinary(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._disposables.push(addSocketListener(this._socket, "close", () => this.dispose()));
|
this._disposables.push(addSocketListener(this._socket, "close", () => this._handleSocketClose(terminal)));
|
||||||
this._disposables.push(addSocketListener(this._socket, "error", () => this.dispose()));
|
this._disposables.push(addSocketListener(this._socket, "error", () => this._handleSocketClose(terminal)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles socket close events by terminating processes and showing a message
|
||||||
|
*/
|
||||||
|
private _handleSocketClose(terminal: Terminal): void {
|
||||||
|
if (terminal) {
|
||||||
|
terminal.writeln(
|
||||||
|
formatErrorMessage("Session ended. Please close this tab and initiate a new shell session if needed."),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send exit command to terminal
|
||||||
|
if (this._bidirectional) {
|
||||||
|
terminal.write(formatErrorMessage("exit\r\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up resources
|
||||||
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user