mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Add STS root folder override (#16927)
* Add STS root folder override * Display message to user * Show once for any service
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlOpsDataClient, ClientOptions, SqlOpsFeature } from 'dataprotocol-client';
|
||||
import { IConfig, ServerProvider } from '@microsoft/ads-service-downloader';
|
||||
import { IConfig } from '@microsoft/ads-service-downloader';
|
||||
import { ServerOptions, RPCMessageType, ClientCapabilities, ServerCapabilities, TransportKind } from 'vscode-languageclient';
|
||||
import { Disposable } from 'vscode';
|
||||
import * as UUID from 'vscode-languageclient/lib/utils/uuid';
|
||||
@@ -77,17 +77,15 @@ export class CredentialStore {
|
||||
}
|
||||
}
|
||||
|
||||
public start() {
|
||||
let serverdownloader = new ServerProvider(this._config);
|
||||
public async start(): Promise<void> {
|
||||
let clientOptions: ClientOptions = {
|
||||
providerId: Constants.providerId,
|
||||
features: [CredentialsFeature]
|
||||
};
|
||||
return serverdownloader.getOrDownloadServer().then(e => {
|
||||
let serverOptions = this.generateServerOptions(e);
|
||||
this._client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions);
|
||||
this._client.start();
|
||||
});
|
||||
const serverPath = await Utils.getOrDownloadServer(this._config);
|
||||
const serverOptions = this.generateServerOptions(serverPath);
|
||||
this._client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions);
|
||||
this._client.start();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { IConfig, ServerProvider } from '@microsoft/ads-service-downloader';
|
||||
import { IConfig } from '@microsoft/ads-service-downloader';
|
||||
import { SqlOpsDataClient, SqlOpsFeature, ClientOptions } from 'dataprotocol-client';
|
||||
import { ServerCapabilities, ClientCapabilities, RPCMessageType, ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
import * as UUID from 'vscode-languageclient/lib/utils/uuid';
|
||||
@@ -81,17 +81,15 @@ export class AzureResourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public start() {
|
||||
let serverdownloader = new ServerProvider(this._config);
|
||||
public async start(): Promise<void> {
|
||||
let clientOptions: ClientOptions = {
|
||||
providerId: Constants.providerId,
|
||||
features: [FireWallFeature]
|
||||
};
|
||||
return serverdownloader.getOrDownloadServer().then(e => {
|
||||
let serverOptions = this.generateServerOptions(e);
|
||||
this._client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions);
|
||||
this._client.start();
|
||||
});
|
||||
const serverPath = await Utils.getOrDownloadServer(this._config);
|
||||
let serverOptions = this.generateServerOptions(serverPath);
|
||||
this._client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions);
|
||||
this._client.start();
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ServerProvider, IConfig, Events } from '@microsoft/ads-service-downloader';
|
||||
import { IConfig, Events } from '@microsoft/ads-service-downloader';
|
||||
import { ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
import * as Constants from './constants';
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { getCommonLaunchArgsAndCleanupOldLogFiles } from './utils';
|
||||
import { getCommonLaunchArgsAndCleanupOldLogFiles, getOrDownloadServer } from './utils';
|
||||
import { Telemetry, LanguageClientErrorHandler } from './telemetry';
|
||||
import { SqlOpsDataClient, ClientOptions } from 'dataprotocol-client';
|
||||
import { TelemetryFeature, AgentServicesFeature, SerializationFeature, AccountFeature, SqlAssessmentServicesFeature, ProfilerFeature } from './features';
|
||||
@@ -82,10 +82,7 @@ export class SqlToolsServer {
|
||||
this.config.installDirectory = path.join(configDir, this.config.installDirectory);
|
||||
this.config.proxy = vscode.workspace.getConfiguration('http').get('proxy');
|
||||
this.config.strictSSL = vscode.workspace.getConfiguration('http').get('proxyStrictSSL') || true;
|
||||
|
||||
const serverdownloader = new ServerProvider(this.config);
|
||||
serverdownloader.eventEmitter.onAny(generateHandleServerProviderEvent());
|
||||
return serverdownloader.getOrDownloadServer();
|
||||
return getOrDownloadServer(this.config, handleServerProviderEvent);
|
||||
}
|
||||
|
||||
private activateFeatures(context: AppContext): Promise<void> {
|
||||
@@ -109,39 +106,37 @@ function generateServerOptions(logPath: string, executablePath: string): ServerO
|
||||
return { command: executablePath, args: launchArgs, transport: TransportKind.stdio };
|
||||
}
|
||||
|
||||
function generateHandleServerProviderEvent() {
|
||||
function handleServerProviderEvent(e: string, ...args: any[]): void {
|
||||
let dots = 0;
|
||||
return (e: string, ...args: any[]) => {
|
||||
switch (e) {
|
||||
case Events.INSTALL_START:
|
||||
outputChannel.show(true);
|
||||
statusView.show();
|
||||
outputChannel.appendLine(localize('installingServiceChannelMsg', "Installing {0} to {1}", Constants.serviceName, args[0]));
|
||||
statusView.text = localize('installingServiceStatusMsg', "Installing {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.INSTALL_END:
|
||||
outputChannel.appendLine(localize('installedServiceChannelMsg', "Installed {0}", Constants.serviceName));
|
||||
break;
|
||||
case Events.DOWNLOAD_START:
|
||||
outputChannel.appendLine(localize('downloadingServiceChannelMsg', "Downloading {0}", args[0]));
|
||||
outputChannel.append(localize('downloadingServiceSizeChannelMsg', "({0} KB)", Math.ceil(args[1] / 1024).toLocaleString(vscode.env.language)));
|
||||
statusView.text = localize('downloadingServiceStatusMsg', "Downloading {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.DOWNLOAD_PROGRESS:
|
||||
let newDots = Math.ceil(args[0] / 5);
|
||||
if (newDots > dots) {
|
||||
outputChannel.append('.'.repeat(newDots - dots));
|
||||
dots = newDots;
|
||||
}
|
||||
break;
|
||||
case Events.DOWNLOAD_END:
|
||||
outputChannel.appendLine(localize('downloadServiceDoneChannelMsg', "Done installing {0}", Constants.serviceName));
|
||||
break;
|
||||
case Events.ENTRY_EXTRACTED:
|
||||
outputChannel.appendLine(localize('entryExtractedChannelMsg', "Extracted {0} ({1}/{2})", args[0], args[1], args[2]));
|
||||
break;
|
||||
}
|
||||
};
|
||||
switch (e) {
|
||||
case Events.INSTALL_START:
|
||||
outputChannel.show(true);
|
||||
statusView.show();
|
||||
outputChannel.appendLine(localize('installingServiceChannelMsg', "Installing {0} to {1}", Constants.serviceName, args[0]));
|
||||
statusView.text = localize('installingServiceStatusMsg', "Installing {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.INSTALL_END:
|
||||
outputChannel.appendLine(localize('installedServiceChannelMsg', "Installed {0}", Constants.serviceName));
|
||||
break;
|
||||
case Events.DOWNLOAD_START:
|
||||
outputChannel.appendLine(localize('downloadingServiceChannelMsg', "Downloading {0}", args[0]));
|
||||
outputChannel.append(localize('downloadingServiceSizeChannelMsg', "({0} KB)", Math.ceil(args[1] / 1024).toLocaleString(vscode.env.language)));
|
||||
statusView.text = localize('downloadingServiceStatusMsg', "Downloading {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.DOWNLOAD_PROGRESS:
|
||||
let newDots = Math.ceil(args[0] / 5);
|
||||
if (newDots > dots) {
|
||||
outputChannel.append('.'.repeat(newDots - dots));
|
||||
dots = newDots;
|
||||
}
|
||||
break;
|
||||
case Events.DOWNLOAD_END:
|
||||
outputChannel.appendLine(localize('downloadServiceDoneChannelMsg', "Done installing {0}", Constants.serviceName));
|
||||
break;
|
||||
case Events.ENTRY_EXTRACTED:
|
||||
outputChannel.appendLine(localize('entryExtractedChannelMsg', "Extracted {0} ({1}/{2})", args[0], args[1], args[2]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function getClientOptions(context: AppContext): ClientOptions {
|
||||
|
||||
@@ -12,6 +12,8 @@ import * as os from 'os';
|
||||
import * as findRemoveSync from 'find-remove';
|
||||
import * as constants from './constants';
|
||||
import { promises as fs } from 'fs';
|
||||
import { IConfig, ServerProvider } from '@microsoft/ads-service-downloader';
|
||||
import { env } from 'process';
|
||||
|
||||
const configTracingLevel = 'tracingLevel';
|
||||
const configLogRetentionMinutes = 'logRetentionMinutes';
|
||||
@@ -304,3 +306,45 @@ export async function exists(path: string): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const STS_OVERRIDE_ENV_VAR = 'ADS_SQLTOOLSSERVICE';
|
||||
let overrideMessageDisplayed = false;
|
||||
/**
|
||||
* Gets the full path to the EXE for the specified tools service, downloading it in the process if necessary. The location
|
||||
* for this can be overridden with an environment variable for debugging or other purposes.
|
||||
* @param config The configuration values of the server to get/download
|
||||
* @param handleServerEvent A callback for handling events from the server downloader
|
||||
* @returns The path to the server exe
|
||||
*/
|
||||
export async function getOrDownloadServer(config: IConfig, handleServerEvent?: (e: string, ...args: any[]) => void): Promise<string> {
|
||||
// This env var is used to override the base install location of STS - primarily to be used for debugging scenarios.
|
||||
try {
|
||||
const stsRootPath = env[STS_OVERRIDE_ENV_VAR];
|
||||
if (stsRootPath) {
|
||||
for (const exeFile of config.executableFiles) {
|
||||
const serverFullPath = path.join(stsRootPath, exeFile);
|
||||
if (await exists(serverFullPath)) {
|
||||
const overrideMessage = `Using ${exeFile} from ${stsRootPath}`;
|
||||
// Display message to the user so they know the override is active, but only once so we don't show too many
|
||||
if (!overrideMessageDisplayed) {
|
||||
overrideMessageDisplayed = true;
|
||||
vscode.window.showInformationMessage(overrideMessage);
|
||||
}
|
||||
console.log(overrideMessage);
|
||||
return serverFullPath;
|
||||
}
|
||||
}
|
||||
console.warn(`Could not find valid SQL Tools Service EXE from ${JSON.stringify(config.executableFiles)} at ${stsRootPath}, falling back to config`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Unexpected error getting override path for SQL Tools Service client ', err);
|
||||
// Fall back to config if something unexpected happens here
|
||||
}
|
||||
|
||||
const serverdownloader = new ServerProvider(config);
|
||||
if (handleServerEvent) {
|
||||
serverdownloader.eventEmitter.onAny(handleServerEvent);
|
||||
}
|
||||
|
||||
return serverdownloader.getOrDownloadServer();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user