Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DA-597 add sdk doctor to vs code extension #430

Merged
merged 12 commits into from
Oct 25, 2024
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
"version": "2.1.6",
"version": "2.1.7",
"engines": {
"vscode": "^1.63.1"
},
Expand Down Expand Up @@ -1323,5 +1323,4 @@
}
]
}
}

}
3 changes: 3 additions & 0 deletions src/handlers/dependenciesUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class DependenciesUtil {
public static readonly CBIMPORT_EXPORT_VERSION =
config.CBIMPORT_EXPORT_VERSION;

public static readonly SDK_DOCTOR_VERSION = config.SDK_DOCTOR_VERSION;
public static readonly SDK_DOCTOR_KEY = config.SDK_DOCTOR_KEY;

public static createVersioningFile(directoryPath: string): void {
const filePath = path.join(
directoryPath,
Expand Down
79 changes: 76 additions & 3 deletions src/handlers/handleCLIDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class DependenciesDownloader {
private readonly TOOL_IMPORT_EXPORT = "import_export";
private readonly ALL_TOOLS = "all_tools";
private readonly TOOL_MDB_MIGRATE = "cb_migrate";
private readonly SDK_DOCTOR = "sdk-doctor";

private getToolInstallPath(toolKey: string): string {
if (toolKey === this.TOOL_SHELL) {
Expand All @@ -31,14 +32,18 @@ class DependenciesDownloader {
return "cbmigrate";
} else if (toolKey === this.ALL_TOOLS) {
return "cbtools";
} else {
} else if(toolKey === this.SDK_DOCTOR) {
return "sdk-doctor";
}
else {
throw new Error("Not Implemented yet");
}
}

private getToolsMap(toolKey: string, os: string): Map<CBToolsType, string> {
const suffix = os.includes("mac") || os.includes("linux") ? "" : ".exe";
const pathPrefix = "bin" + path.sep;
console.log(toolKey);

const map = new Map<CBToolsType, string>();

Expand All @@ -64,6 +69,8 @@ class DependenciesDownloader {
CBToolsType.MCTIMINGS,
path.join(pathPrefix, "mctimings" + suffix)
);
} else if (toolKey === this.SDK_DOCTOR) {
map.set(CBToolsType.SDK_DOCTOR, 'sdk-doctor'+ suffix);
} else {
throw new Error("Not implemented yet");
}
Expand All @@ -80,6 +87,38 @@ class DependenciesDownloader {
}
public getDownloadList(os: string): Map<string, ToolSpec> {
const map = new Map<string, ToolSpec>();
// SDK Doctor Download configuration
if (os === OSUtil.MACOS_64 || os === OSUtil.MACOS_ARM) {
map.set(
this.SDK_DOCTOR,
this.getToolSpec(
"https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/sdkdoctor/1.0.8-sdk-doctor-macos.zip",
this.SDK_DOCTOR,
os
)
);
} else if (os === OSUtil.WINDOWS_64 || os === OSUtil.WINDOWS_ARM) {
map.set(
this.SDK_DOCTOR,
this.getToolSpec(
"https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/sdkdoctor/1.0.8-sdk-doctor-windows.zip",
this.SDK_DOCTOR,
os
)
);
} else if (os === OSUtil.LINUX_64 || os === OSUtil.LINUX_ARM) {
map.set(
this.SDK_DOCTOR,
this.getToolSpec(
"https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/sdkdoctor/1.0.8-sdk-doctor-linux.zip",
this.SDK_DOCTOR,
os
)
);
} else {
throw new Error("OS not supported.");
}
// CB Tools Download configuration
if (os === OSUtil.MACOS_64) {
map.set(
this.TOOL_SHELL,
Expand Down Expand Up @@ -283,7 +322,7 @@ class DependenciesDownloader {
) {
logger.info("Cleaning up older tools versions if update required");
const shell: ToolSpec | undefined = downloads.get(this.TOOL_SHELL);
if (shell == undefined) {
if (shell === undefined) {
return;
}
// Checks if CB shell is installed and requires update by comparing current version of tool with version config value
Expand All @@ -307,7 +346,7 @@ class DependenciesDownloader {

}
const cbimport_export: ToolSpec | undefined = downloads.get(this.TOOL_IMPORT_EXPORT);
if (cbimport_export == undefined) {
if (cbimport_export === undefined) {
return;
}
// Checks if CB Import/Export is installed and requires update by comparing current version of tool with version config value
Expand Down Expand Up @@ -347,6 +386,7 @@ class DependenciesDownloader {
this.manageShellInstallation(downloads, toolsPath, extensionPath);
this.manageCbMigrateInstallation(downloads, toolsPath, extensionPath);
this.manageDataImportExportInstallation(downloads, toolsPath, extensionPath);
this.manageSdkDoctorInstallation(downloads, toolsPath, extensionPath);
};

private setToolActive(
Expand Down Expand Up @@ -524,6 +564,39 @@ class DependenciesDownloader {
}
}

public manageSdkDoctorInstallation(
downloads: Map<string, ToolSpec>,
toolsPath: string,
extensionPath: string
): void {
const sdkDoctor = downloads.get(this.SDK_DOCTOR);
if (sdkDoctor === undefined) {
return;
}
const sdkDoctorPath = path.join(toolsPath, sdkDoctor.getInstallationPath());
const sdkDoctorTool = CBTools.getTool(CBToolsType.SDK_DOCTOR);
const sdkDoctorStatus = sdkDoctorTool.status;
const sdkDoctorDownloadsMap = downloads.get(this.SDK_DOCTOR);
if (sdkDoctorDownloadsMap === undefined) {
return;
}
if (
sdkDoctorStatus === ToolStatus.NOT_AVAILABLE &&
!this.isInstalled(
toolsPath,
sdkDoctorDownloadsMap,
CBToolsType.SDK_DOCTOR
)
) {
logger.info("Downloading SDK Doctor.");
sdkDoctorTool.status = ToolStatus.DOWNLOADING;
this.downloadAndUnzip(sdkDoctorPath, sdkDoctor, extensionPath, DependenciesUtil.SDK_DOCTOR_KEY, DependenciesUtil.SDK_DOCTOR_VERSION);
} else {
logger.debug("SDK Doctor is already installed");
this.setToolActive(ToolStatus.AVAILABLE, sdkDoctorPath, sdkDoctor);
}
}

// This is a test function, keeping this here to check for any specific downloaded CLI tool
/* public runFile(targetDir:string) {
const scriptPath = path.join(targetDir, 'cbsh');
Expand Down
2 changes: 2 additions & 0 deletions src/handlers/versionConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ export const config = {
CBMIGRATE_VERSION: "2",
SHELL_VERSION: "1.0.0",
CBIMPORT_EXPORT_VERSION: "7.6",
SDK_DOCTOR_VERSION: "1.0.8",
SDK_DOCTOR_KEY: "sdk-doctor",
};
67 changes: 67 additions & 0 deletions src/tools/SDKDocterRunner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as childProcess from 'child_process';
import { CBTools, ToolStatus, Type } from '../util/DependencyDownloaderUtils/CBTool';

export class SdkDoctorRunner {
static async run(
host: string,
ssl: boolean,
bucket: string,
username: string,
password: string,
outputCallback: (line: string) => void
): Promise<void> {
try {
const sdkDoctorTool = CBTools.getTool(Type.SDK_DOCTOR);
if (sdkDoctorTool.status !== ToolStatus.AVAILABLE) {
throw new Error('SDK Doctor is not available. Please ensure it is installed.');
}

const sdkDoctorExecutable = sdkDoctorTool.path;
const clusterUrl = SdkDoctorRunner.adjustClusterProtocol(host, ssl);
const args = [
'diagnose',
`${clusterUrl}/${bucket}`,
'-u', username,
'-p', password
];

const process = childProcess.spawn(sdkDoctorExecutable, args);

process.stdout.on('data', (data) => {
const lines = data.toString().split('\n');
lines.forEach((line: string) => {
if (line.trim()) {
outputCallback(line.trim());
}
});
});

process.stderr.on('data', (data) => {
console.error(`SDK Doctor error: ${data}`);
});

await new Promise<void>((resolve, reject) => {
process.on('close', (code) => {
if (code !== 0) {
console.warn(`SDK Doctor exited with code ${code}`);
}
resolve();
});

process.on('error', (err) => {
reject(err);
});
});

} catch (error) {
console.error('Error while running the SDK Doctor', error);
}
}

private static adjustClusterProtocol(host: string, ssl: boolean): string {
const protocol = ssl ? 'couchbases://' : 'couchbase://';
return host.startsWith('couchbase://') || host.startsWith('couchbases://')
? host
: `${protocol}${host}`;
}
}
3 changes: 2 additions & 1 deletion src/util/DependencyDownloaderUtils/CBTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export enum Type {
CB_EXPORT = "CB_EXPORT",
CBC_PILLOW_FIGHT = "CBC_PILLOW_FIGHT",
MCTIMINGS = "MCTIMINGS",
CB_MIGRATE = "CB_MIGRATE"
CB_MIGRATE = "CB_MIGRATE",
SDK_DOCTOR = "SDK_DOCTOR"
}


Expand Down
43 changes: 41 additions & 2 deletions src/util/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { CouchbaseRestAPI } from "./apis/CouchbaseRestAPI";
import { hasQueryService, hasSearchService } from "./common";
import { SecretService } from "./secretService";
import ConnectionEvents from "./events/connectionEvents";
import { SdkDoctorRunner } from "../tools/SDKDocterRunner";

export function getConnectionId(connection: IConnection) {
const { url, username } = connection;
Expand Down Expand Up @@ -151,6 +152,43 @@ export async function addConnection(clusterConnectionTreeProvider: ClusterConnec
currentPanel.dispose();
break;

case 'testConnection':
const { connectionUrl, username, password, bucketName, isSecure } = message;
if(bucketName === "") {
try {
await connect(connectionUrl, { username: username, password: password, configProfile: 'wanDevelopment' });
currentPanel.webview.postMessage({
command: 'testConnectionResult',
result: 'Connection was successfull!'
});
}
catch (err) {
currentPanel.webview.postMessage({
command: 'testConnectionResult',
result: '[ERRO]: Connection Failed ' + err
});
}
return;
}
const results: string[] = [];

await SdkDoctorRunner.run(
connectionUrl,
isSecure,
bucketName,
username,
password,
(line) => {
results.push(line);
}
);

currentPanel.webview.postMessage({
command: 'testConnectionResult',
result: results.join('\n')
});
break;

default:
console.error('Unrecognized command');
}
Expand All @@ -163,10 +201,11 @@ async function handleConnectionError(err: any) {
if (err instanceof AuthenticationFailureError) {
answer = await vscode.window.showErrorMessage(`
Authentication Failed: Please check your credentials and try again \n
If you're still having difficulty, please check out this helpful troubleshooting link`, { modal: true }, "Troubleshoot Link");
or inform a Bucket on Troubleshooting to inspect your connection \n
or check out this helpful troubleshooting link`, { modal: true }, "Troubleshoot Link");
}
else {
answer = await vscode.window.showErrorMessage(`Could not establish a connection \n ${err} \n If you're having difficulty, please check out this helpful troubleshooting link`, { modal: true }, "Troubleshoot Link");
answer = await vscode.window.showErrorMessage(`Could not establish a connection \n ${err} \n Inform a Bucket on Troubleshooting to inspect your connection \n or check out this helpful troubleshooting link`, { modal: true }, "Troubleshoot Link");
}

if (answer === "Troubleshoot Link") {
Expand Down
Loading
Loading