mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Renable Strict TSLint (#5018)
* removes more builder references * remove builder from profiler * formatting * fix profiler dailog * remove builder from oatuhdialog * remove the rest of builder references * formatting * add more strict null checks to base * enable strict tslint rules * fix formatting * fix compile error * fix the rest of the hygeny issues and add pipeline step * fix pipeline files
This commit is contained in:
@@ -12,110 +12,110 @@ const KUBECONFIG_PATH_KEY = 'mssql-bdc.kubeconfig';
|
||||
const KNOWN_KUBECONFIGS_KEY = 'mssql-bdc.knownKubeconfigs';
|
||||
|
||||
export async function addPathToConfig(configKey: string, value: string): Promise<void> {
|
||||
await setConfigValue(configKey, value);
|
||||
await setConfigValue(configKey, value);
|
||||
}
|
||||
|
||||
async function setConfigValue(configKey: string, value: any): Promise<void> {
|
||||
await atAllConfigScopes(addValueToConfigAtScope, configKey, value);
|
||||
await atAllConfigScopes(addValueToConfigAtScope, configKey, value);
|
||||
}
|
||||
|
||||
async function addValueToConfigAtScope(configKey: string, value: any, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean): Promise<void> {
|
||||
if (!createIfNotExist) {
|
||||
if (!valueAtScope || !(valueAtScope[configKey])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!createIfNotExist) {
|
||||
if (!valueAtScope || !(valueAtScope[configKey])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let newValue: any = {};
|
||||
if (valueAtScope) {
|
||||
newValue = Object.assign({}, valueAtScope);
|
||||
}
|
||||
newValue[configKey] = value;
|
||||
await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
|
||||
let newValue: any = {};
|
||||
if (valueAtScope) {
|
||||
newValue = Object.assign({}, valueAtScope);
|
||||
}
|
||||
newValue[configKey] = value;
|
||||
await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
|
||||
}
|
||||
|
||||
async function addValueToConfigArray(configKey: string, value: string): Promise<void> {
|
||||
await atAllConfigScopes(addValueToConfigArrayAtScope, configKey, value);
|
||||
await atAllConfigScopes(addValueToConfigArrayAtScope, configKey, value);
|
||||
}
|
||||
|
||||
async function addValueToConfigArrayAtScope(configKey: string, value: string, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean): Promise<void> {
|
||||
if (!createIfNotExist) {
|
||||
if (!valueAtScope || !(valueAtScope[configKey])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!createIfNotExist) {
|
||||
if (!valueAtScope || !(valueAtScope[configKey])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let newValue: any = {};
|
||||
if (valueAtScope) {
|
||||
newValue = Object.assign({}, valueAtScope);
|
||||
}
|
||||
const arrayEntry: string[] = newValue[configKey] || [];
|
||||
arrayEntry.push(value);
|
||||
newValue[configKey] = arrayEntry;
|
||||
await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
|
||||
let newValue: any = {};
|
||||
if (valueAtScope) {
|
||||
newValue = Object.assign({}, valueAtScope);
|
||||
}
|
||||
const arrayEntry: string[] = newValue[configKey] || [];
|
||||
arrayEntry.push(value);
|
||||
newValue[configKey] = arrayEntry;
|
||||
await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
|
||||
}
|
||||
|
||||
type ConfigUpdater<T> = (configKey: string, value: T, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean) => Promise<void>;
|
||||
|
||||
async function atAllConfigScopes<T>(fn: ConfigUpdater<T>, configKey: string, value: T): Promise<void> {
|
||||
const config = vscode.workspace.getConfiguration().inspect(EXTENSION_CONFIG_KEY)!;
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.Global, config.globalValue, true);
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.Workspace, config.workspaceValue, false);
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.WorkspaceFolder, config.workspaceFolderValue, false);
|
||||
const config = vscode.workspace.getConfiguration().inspect(EXTENSION_CONFIG_KEY)!;
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.Global, config.globalValue, true);
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.Workspace, config.workspaceValue, false);
|
||||
await fn(configKey, value, vscode.ConfigurationTarget.WorkspaceFolder, config.workspaceFolderValue, false);
|
||||
}
|
||||
|
||||
// Functions for working with the list of known kubeconfigs
|
||||
|
||||
export function getKnownKubeconfigs(): string[] {
|
||||
const kkcConfig = vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KNOWN_KUBECONFIGS_KEY];
|
||||
if (!kkcConfig || !kkcConfig.length) {
|
||||
return [];
|
||||
}
|
||||
return kkcConfig as string[];
|
||||
const kkcConfig = vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KNOWN_KUBECONFIGS_KEY];
|
||||
if (!kkcConfig || !kkcConfig.length) {
|
||||
return [];
|
||||
}
|
||||
return kkcConfig as string[];
|
||||
}
|
||||
|
||||
export async function addKnownKubeconfig(kubeconfigPath: string) {
|
||||
await addValueToConfigArray(KNOWN_KUBECONFIGS_KEY, kubeconfigPath);
|
||||
await addValueToConfigArray(KNOWN_KUBECONFIGS_KEY, kubeconfigPath);
|
||||
}
|
||||
|
||||
// Functions for working with the active kubeconfig setting
|
||||
|
||||
export async function setActiveKubeconfig(kubeconfig: string): Promise<void> {
|
||||
await addPathToConfig(KUBECONFIG_PATH_KEY, kubeconfig);
|
||||
await addPathToConfig(KUBECONFIG_PATH_KEY, kubeconfig);
|
||||
}
|
||||
|
||||
export function getActiveKubeconfig(): string {
|
||||
return vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KUBECONFIG_PATH_KEY];
|
||||
return vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KUBECONFIG_PATH_KEY];
|
||||
}
|
||||
|
||||
// Functions for working with tool paths
|
||||
|
||||
export function getToolPath(host: Host, shell: Shell, tool: string): string | undefined {
|
||||
const baseKey = toolPathBaseKey(tool);
|
||||
return getPathSetting(host, shell, baseKey);
|
||||
const baseKey = toolPathBaseKey(tool);
|
||||
return getPathSetting(host, shell, baseKey);
|
||||
}
|
||||
|
||||
function getPathSetting(host: Host, shell: Shell, baseKey: string): string | undefined {
|
||||
const os = shell.platform();
|
||||
const osOverridePath = host.getConfiguration(EXTENSION_CONFIG_KEY)[osOverrideKey(os, baseKey)];
|
||||
return osOverridePath || host.getConfiguration(EXTENSION_CONFIG_KEY)[baseKey];
|
||||
const os = shell.platform();
|
||||
const osOverridePath = host.getConfiguration(EXTENSION_CONFIG_KEY)[osOverrideKey(os, baseKey)];
|
||||
return osOverridePath || host.getConfiguration(EXTENSION_CONFIG_KEY)[baseKey];
|
||||
}
|
||||
|
||||
export function toolPathBaseKey(tool: string): string {
|
||||
return `mssql-bdc.${tool}-path`;
|
||||
return `mssql-bdc.${tool}-path`;
|
||||
}
|
||||
|
||||
function osOverrideKey(os: Platform, baseKey: string): string {
|
||||
const osKey = osKeyString(os);
|
||||
return osKey ? `${baseKey}.${osKey}` : baseKey; // The 'else' clause should never happen so don't worry that this would result in double-checking a missing base key
|
||||
const osKey = osKeyString(os);
|
||||
return osKey ? `${baseKey}.${osKey}` : baseKey; // The 'else' clause should never happen so don't worry that this would result in double-checking a missing base key
|
||||
}
|
||||
|
||||
function osKeyString(os: Platform): string | null {
|
||||
switch (os) {
|
||||
case Platform.Windows: return 'windows';
|
||||
case Platform.MacOS: return 'mac';
|
||||
case Platform.Linux: return 'linux';
|
||||
default: return null;
|
||||
}
|
||||
switch (os) {
|
||||
case Platform.Windows: return 'windows';
|
||||
case Platform.MacOS: return 'mac';
|
||||
case Platform.Linux: return 'linux';
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,36 +10,36 @@ import * as tmp from 'tmp';
|
||||
import { succeeded, Errorable } from '../interfaces';
|
||||
|
||||
type DownloadFunc =
|
||||
(url: string, destination?: string, options?: any)
|
||||
=> Promise<Buffer> & stream.Duplex; // Stream has additional events - see https://www.npmjs.com/package/download
|
||||
(url: string, destination?: string, options?: any)
|
||||
=> Promise<Buffer> & stream.Duplex; // Stream has additional events - see https://www.npmjs.com/package/download
|
||||
|
||||
let download: DownloadFunc;
|
||||
|
||||
function ensureDownloadFunc() {
|
||||
if (!download) {
|
||||
const home = process.env['HOME'];
|
||||
download = require('download');
|
||||
if (home) {
|
||||
process.env['HOME'] = home;
|
||||
}
|
||||
}
|
||||
if (!download) {
|
||||
const home = process.env['HOME'];
|
||||
download = require('download');
|
||||
if (home) {
|
||||
process.env['HOME'] = home;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function toTempFile(sourceUrl: string): Promise<Errorable<string>> {
|
||||
const tempFileObj = tmp.fileSync({ prefix: 'mssql-bdc-autoinstall-' });
|
||||
const downloadResult = await to(sourceUrl, tempFileObj.name);
|
||||
if (succeeded(downloadResult)) {
|
||||
return { succeeded: true, result: tempFileObj.name };
|
||||
}
|
||||
return { succeeded: false, error: downloadResult.error };
|
||||
const tempFileObj = tmp.fileSync({ prefix: 'mssql-bdc-autoinstall-' });
|
||||
const downloadResult = await to(sourceUrl, tempFileObj.name);
|
||||
if (succeeded(downloadResult)) {
|
||||
return { succeeded: true, result: tempFileObj.name };
|
||||
}
|
||||
return { succeeded: false, error: downloadResult.error };
|
||||
}
|
||||
|
||||
export async function to(sourceUrl: string, destinationFile: string): Promise<Errorable<null>> {
|
||||
ensureDownloadFunc();
|
||||
try {
|
||||
await download(sourceUrl, path.dirname(destinationFile), { filename: path.basename(destinationFile) });
|
||||
return { succeeded: true, result: null };
|
||||
} catch (e) {
|
||||
return { succeeded: false, error: [e.message] };
|
||||
}
|
||||
ensureDownloadFunc();
|
||||
try {
|
||||
await download(sourceUrl, path.dirname(destinationFile), { filename: path.basename(destinationFile) });
|
||||
return { succeeded: true, result: null };
|
||||
} catch (e) {
|
||||
return { succeeded: false, error: [e.message] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,57 +16,57 @@ import { Errorable, failed } from '../interfaces';
|
||||
import { addPathToConfig, toolPathBaseKey } from '../config/config';
|
||||
|
||||
export async function installKubectl(shell: Shell): Promise<Errorable<null>> {
|
||||
const tool = 'kubectl';
|
||||
const binFile = (shell.isUnix()) ? 'kubectl' : 'kubectl.exe';
|
||||
const os = platformUrlString(shell.platform());
|
||||
const tool = 'kubectl';
|
||||
const binFile = (shell.isUnix()) ? 'kubectl' : 'kubectl.exe';
|
||||
const os = platformUrlString(shell.platform());
|
||||
|
||||
const version = await getStableKubectlVersion();
|
||||
if (failed(version)) {
|
||||
return { succeeded: false, error: version.error };
|
||||
}
|
||||
const version = await getStableKubectlVersion();
|
||||
if (failed(version)) {
|
||||
return { succeeded: false, error: version.error };
|
||||
}
|
||||
|
||||
const installFolder = getInstallFolder(shell, tool);
|
||||
mkdirp.sync(installFolder);
|
||||
const installFolder = getInstallFolder(shell, tool);
|
||||
mkdirp.sync(installFolder);
|
||||
|
||||
const kubectlUrl = `https://storage.googleapis.com/kubernetes-release/release/${version.result.trim()}/bin/${os}/amd64/${binFile}`;
|
||||
const downloadFile = path.join(installFolder, binFile);
|
||||
const downloadResult = await download.to(kubectlUrl, downloadFile);
|
||||
if (failed(downloadResult)) {
|
||||
return { succeeded: false, error: [localize('downloadKubectlFailed', 'Failed to download kubectl: {0}', downloadResult.error[0])] };
|
||||
}
|
||||
const kubectlUrl = `https://storage.googleapis.com/kubernetes-release/release/${version.result.trim()}/bin/${os}/amd64/${binFile}`;
|
||||
const downloadFile = path.join(installFolder, binFile);
|
||||
const downloadResult = await download.to(kubectlUrl, downloadFile);
|
||||
if (failed(downloadResult)) {
|
||||
return { succeeded: false, error: [localize('downloadKubectlFailed', 'Failed to download kubectl: {0}', downloadResult.error[0])] };
|
||||
}
|
||||
|
||||
if (shell.isUnix()) {
|
||||
fs.chmodSync(downloadFile, '0777');
|
||||
}
|
||||
if (shell.isUnix()) {
|
||||
fs.chmodSync(downloadFile, '0777');
|
||||
}
|
||||
|
||||
await addPathToConfig(toolPathBaseKey(tool), downloadFile);
|
||||
return { succeeded: true, result: null };
|
||||
await addPathToConfig(toolPathBaseKey(tool), downloadFile);
|
||||
return { succeeded: true, result: null };
|
||||
}
|
||||
|
||||
async function getStableKubectlVersion(): Promise<Errorable<string>> {
|
||||
const downloadResult = await download.toTempFile('https://storage.googleapis.com/kubernetes-release/release/stable.txt');
|
||||
if (failed(downloadResult)) {
|
||||
return { succeeded: false, error: [localize('kubectlVersionCheckFailed', 'Failed to establish kubectl stable version: {0}', downloadResult.error[0])] };
|
||||
}
|
||||
const version = fs.readFileSync(downloadResult.result, 'utf-8');
|
||||
fs.unlinkSync(downloadResult.result);
|
||||
return { succeeded: true, result: version };
|
||||
const downloadResult = await download.toTempFile('https://storage.googleapis.com/kubernetes-release/release/stable.txt');
|
||||
if (failed(downloadResult)) {
|
||||
return { succeeded: false, error: [localize('kubectlVersionCheckFailed', 'Failed to establish kubectl stable version: {0}', downloadResult.error[0])] };
|
||||
}
|
||||
const version = fs.readFileSync(downloadResult.result, 'utf-8');
|
||||
fs.unlinkSync(downloadResult.result);
|
||||
return { succeeded: true, result: version };
|
||||
}
|
||||
|
||||
export function getInstallFolder(shell: Shell, tool: string): string {
|
||||
return path.join(shell.home(), `.mssql-bdc/tools/${tool}`);
|
||||
return path.join(shell.home(), `.mssql-bdc/tools/${tool}`);
|
||||
}
|
||||
|
||||
function platformUrlString(platform: Platform, supported?: Platform[]): string | null {
|
||||
if (supported && supported.indexOf(platform) < 0) {
|
||||
return null;
|
||||
}
|
||||
switch (platform) {
|
||||
case Platform.Windows: return 'windows';
|
||||
case Platform.MacOS: return 'darwin';
|
||||
case Platform.Linux: return 'linux';
|
||||
default: return null;
|
||||
}
|
||||
if (supported && supported.indexOf(platform) < 0) {
|
||||
return null;
|
||||
}
|
||||
switch (platform) {
|
||||
case Platform.Windows: return 'windows';
|
||||
case Platform.MacOS: return 'darwin';
|
||||
case Platform.Linux: return 'linux';
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { Shell } from '../utility/shell';
|
||||
@@ -11,111 +11,111 @@ import { Host } from './host';
|
||||
import { FS } from '../utility/fs';
|
||||
|
||||
export interface BinCheckContext {
|
||||
readonly host: Host;
|
||||
readonly fs: FS;
|
||||
readonly shell: Shell;
|
||||
readonly installDependenciesCallback: () => void;
|
||||
binFound: boolean;
|
||||
binPath: string;
|
||||
readonly host: Host;
|
||||
readonly fs: FS;
|
||||
readonly shell: Shell;
|
||||
readonly installDependenciesCallback: () => void;
|
||||
binFound: boolean;
|
||||
binPath: string;
|
||||
}
|
||||
|
||||
interface FindBinaryResult {
|
||||
err: number | null;
|
||||
output: string;
|
||||
err: number | null;
|
||||
output: string;
|
||||
}
|
||||
|
||||
async function findBinary(shell: Shell, binName: string): Promise<FindBinaryResult> {
|
||||
let cmd = `which ${binName}`;
|
||||
let cmd = `which ${binName}`;
|
||||
|
||||
if (shell.isWindows()) {
|
||||
cmd = `where.exe ${binName}.exe`;
|
||||
}
|
||||
if (shell.isWindows()) {
|
||||
cmd = `where.exe ${binName}.exe`;
|
||||
}
|
||||
|
||||
const opts = {
|
||||
async: true,
|
||||
env: {
|
||||
HOME: process.env.HOME,
|
||||
PATH: process.env.PATH
|
||||
}
|
||||
};
|
||||
const opts = {
|
||||
async: true,
|
||||
env: {
|
||||
HOME: process.env.HOME,
|
||||
PATH: process.env.PATH
|
||||
}
|
||||
};
|
||||
|
||||
const execResult = await shell.execCore(cmd, opts);
|
||||
if (execResult.code) {
|
||||
return { err: execResult.code, output: execResult.stderr };
|
||||
}
|
||||
const execResult = await shell.execCore(cmd, opts);
|
||||
if (execResult.code) {
|
||||
return { err: execResult.code, output: execResult.stderr };
|
||||
}
|
||||
|
||||
return { err: null, output: execResult.stdout };
|
||||
return { err: null, output: execResult.stdout };
|
||||
}
|
||||
|
||||
export function execPath(shell: Shell, basePath: string): string {
|
||||
let bin = basePath;
|
||||
if (shell.isWindows() && bin && !(bin.endsWith('.exe'))) {
|
||||
bin = bin + '.exe';
|
||||
}
|
||||
return bin;
|
||||
let bin = basePath;
|
||||
if (shell.isWindows() && bin && !(bin.endsWith('.exe'))) {
|
||||
bin = bin + '.exe';
|
||||
}
|
||||
return bin;
|
||||
}
|
||||
|
||||
type CheckPresentFailureReason = 'inferFailed' | 'configuredFileMissing';
|
||||
const installDependenciesAction = localize('installDependenciesAction','Install dependencies');
|
||||
const learnMoreAction = localize('learnMoreAction','Learn more');
|
||||
const installDependenciesAction = localize('installDependenciesAction', 'Install dependencies');
|
||||
const learnMoreAction = localize('learnMoreAction', 'Learn more');
|
||||
function alertNoBin(host: Host, binName: string, failureReason: CheckPresentFailureReason, message: string, installDependencies: () => void): void {
|
||||
switch (failureReason) {
|
||||
case 'inferFailed':
|
||||
host.showErrorMessage(message, installDependenciesAction, learnMoreAction).then(
|
||||
(str) => {
|
||||
switch (str) {
|
||||
case learnMoreAction:
|
||||
host.showInformationMessage(localize('moreInfoMsg', 'Add {0} directory to path, or set "mssql-bdc.{0}-path" config to {0} binary.', binName));
|
||||
break;
|
||||
case installDependenciesAction:
|
||||
installDependencies();
|
||||
break;
|
||||
}
|
||||
switch (failureReason) {
|
||||
case 'inferFailed':
|
||||
host.showErrorMessage(message, installDependenciesAction, learnMoreAction).then(
|
||||
(str) => {
|
||||
switch (str) {
|
||||
case learnMoreAction:
|
||||
host.showInformationMessage(localize('moreInfoMsg', 'Add {0} directory to path, or set "mssql-bdc.{0}-path" config to {0} binary.', binName));
|
||||
break;
|
||||
case installDependenciesAction:
|
||||
installDependencies();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
break;
|
||||
case 'configuredFileMissing':
|
||||
host.showErrorMessage(message, installDependenciesAction).then(
|
||||
(str) => {
|
||||
if (str === installDependenciesAction) {
|
||||
installDependencies();
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case 'configuredFileMissing':
|
||||
host.showErrorMessage(message, installDependenciesAction).then(
|
||||
(str) => {
|
||||
if (str === installDependenciesAction) {
|
||||
installDependencies();
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkForBinary(context: BinCheckContext, bin: string | undefined, binName: string, inferFailedMessage: string, configuredFileMissingMessage: string, alertOnFail: boolean): Promise<boolean> {
|
||||
if (!bin) {
|
||||
const fb = await findBinary(context.shell, binName);
|
||||
if (!bin) {
|
||||
const fb = await findBinary(context.shell, binName);
|
||||
|
||||
if (fb.err || fb.output.length === 0) {
|
||||
if (alertOnFail) {
|
||||
alertNoBin(context.host, binName, 'inferFailed', inferFailedMessage, context.installDependenciesCallback);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (fb.err || fb.output.length === 0) {
|
||||
if (alertOnFail) {
|
||||
alertNoBin(context.host, binName, 'inferFailed', inferFailedMessage, context.installDependenciesCallback);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
context.binFound = true;
|
||||
context.binFound = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (context.shell.isWindows) {
|
||||
context.binFound = context.fs.existsSync(bin);
|
||||
} else {
|
||||
const sr = await context.shell.exec(`ls ${bin}`);
|
||||
context.binFound = (!!sr && sr.code === 0);
|
||||
}
|
||||
if (context.binFound) {
|
||||
context.binPath = bin;
|
||||
} else {
|
||||
if (alertOnFail) {
|
||||
alertNoBin(context.host, binName, 'configuredFileMissing', configuredFileMissingMessage, context.installDependenciesCallback);
|
||||
}
|
||||
}
|
||||
if (context.shell.isWindows) {
|
||||
context.binFound = context.fs.existsSync(bin);
|
||||
} else {
|
||||
const sr = await context.shell.exec(`ls ${bin}`);
|
||||
context.binFound = (!!sr && sr.code === 0);
|
||||
}
|
||||
if (context.binFound) {
|
||||
context.binPath = bin;
|
||||
} else {
|
||||
if (alertOnFail) {
|
||||
alertNoBin(context.host, binName, 'configuredFileMissing', configuredFileMissingMessage, context.installDependenciesCallback);
|
||||
}
|
||||
}
|
||||
|
||||
return context.binFound;
|
||||
return context.binFound;
|
||||
}
|
||||
|
||||
@@ -6,61 +6,61 @@
|
||||
import { Errorable, failed } from '../interfaces';
|
||||
|
||||
interface CompatibilityGuaranteed {
|
||||
readonly guaranteed: true;
|
||||
readonly guaranteed: true;
|
||||
}
|
||||
|
||||
interface CompatibilityNotGuaranteed {
|
||||
readonly guaranteed: false;
|
||||
readonly didCheck: boolean;
|
||||
readonly clientVersion: string;
|
||||
readonly serverVersion: string;
|
||||
readonly guaranteed: false;
|
||||
readonly didCheck: boolean;
|
||||
readonly clientVersion: string;
|
||||
readonly serverVersion: string;
|
||||
}
|
||||
|
||||
export type Compatibility = CompatibilityGuaranteed | CompatibilityNotGuaranteed;
|
||||
|
||||
export function isGuaranteedCompatible(c: Compatibility): c is CompatibilityGuaranteed {
|
||||
return c.guaranteed;
|
||||
return c.guaranteed;
|
||||
}
|
||||
|
||||
export interface Version {
|
||||
readonly major: string;
|
||||
readonly minor: string;
|
||||
readonly gitVersion: string;
|
||||
readonly major: string;
|
||||
readonly minor: string;
|
||||
readonly gitVersion: string;
|
||||
}
|
||||
|
||||
export async function check(kubectlLoadJSON: (cmd: string) => Promise<Errorable<any>>): Promise<Compatibility> {
|
||||
const version = await kubectlLoadJSON('version -o json');
|
||||
if (failed(version)) {
|
||||
return {
|
||||
guaranteed: false,
|
||||
didCheck: false,
|
||||
clientVersion: '',
|
||||
serverVersion: ''
|
||||
};
|
||||
}
|
||||
const version = await kubectlLoadJSON('version -o json');
|
||||
if (failed(version)) {
|
||||
return {
|
||||
guaranteed: false,
|
||||
didCheck: false,
|
||||
clientVersion: '',
|
||||
serverVersion: ''
|
||||
};
|
||||
}
|
||||
|
||||
const clientVersion: Version = version.result.clientVersion;
|
||||
const serverVersion: Version = version.result.serverVersion;
|
||||
const clientVersion: Version = version.result.clientVersion;
|
||||
const serverVersion: Version = version.result.serverVersion;
|
||||
|
||||
if (isCompatible(clientVersion, serverVersion)) {
|
||||
return { guaranteed: true };
|
||||
}
|
||||
if (isCompatible(clientVersion, serverVersion)) {
|
||||
return { guaranteed: true };
|
||||
}
|
||||
|
||||
return {
|
||||
guaranteed: false,
|
||||
didCheck: true,
|
||||
clientVersion: clientVersion.gitVersion,
|
||||
serverVersion: serverVersion.gitVersion
|
||||
};
|
||||
return {
|
||||
guaranteed: false,
|
||||
didCheck: true,
|
||||
clientVersion: clientVersion.gitVersion,
|
||||
serverVersion: serverVersion.gitVersion
|
||||
};
|
||||
}
|
||||
|
||||
function isCompatible(clientVersion: Version, serverVersion: Version): boolean {
|
||||
if (clientVersion.major === serverVersion.major) {
|
||||
const clientMinor = Number.parseInt(clientVersion.minor);
|
||||
const serverMinor = Number.parseInt(serverVersion.minor);
|
||||
if (Number.isInteger(clientMinor) && Number.isInteger(serverMinor) && Math.abs(clientMinor - serverMinor) <= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (clientVersion.major === serverVersion.major) {
|
||||
const clientMinor = Number.parseInt(clientVersion.minor);
|
||||
const serverMinor = Number.parseInt(serverVersion.minor);
|
||||
if (Number.isInteger(clientMinor) && Number.isInteger(serverMinor) && Math.abs(clientMinor - serverMinor) <= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,37 +6,37 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export interface Host {
|
||||
showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
showWarningMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
getConfiguration(key: string): any;
|
||||
onDidChangeConfiguration(listener: (ch: vscode.ConfigurationChangeEvent) => any): vscode.Disposable;
|
||||
showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
showWarningMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined>;
|
||||
getConfiguration(key: string): any;
|
||||
onDidChangeConfiguration(listener: (ch: vscode.ConfigurationChangeEvent) => any): vscode.Disposable;
|
||||
}
|
||||
|
||||
export const host: Host = {
|
||||
showErrorMessage : showErrorMessage,
|
||||
showWarningMessage : showWarningMessage,
|
||||
showInformationMessage : showInformationMessage,
|
||||
getConfiguration : getConfiguration,
|
||||
onDidChangeConfiguration : onDidChangeConfiguration,
|
||||
showErrorMessage: showErrorMessage,
|
||||
showWarningMessage: showWarningMessage,
|
||||
showInformationMessage: showInformationMessage,
|
||||
getConfiguration: getConfiguration,
|
||||
onDidChangeConfiguration: onDidChangeConfiguration,
|
||||
};
|
||||
|
||||
function showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
||||
return vscode.window.showErrorMessage(message, ...items);
|
||||
return vscode.window.showErrorMessage(message, ...items);
|
||||
}
|
||||
|
||||
function showWarningMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
||||
return vscode.window.showWarningMessage(message, ...items);
|
||||
return vscode.window.showWarningMessage(message, ...items);
|
||||
}
|
||||
|
||||
function showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
||||
return vscode.window.showInformationMessage(message, ...items);
|
||||
return vscode.window.showInformationMessage(message, ...items);
|
||||
}
|
||||
|
||||
function getConfiguration(key: string): any {
|
||||
return vscode.workspace.getConfiguration(key);
|
||||
return vscode.workspace.getConfiguration(key);
|
||||
}
|
||||
|
||||
function onDidChangeConfiguration(listener: (e: vscode.ConfigurationChangeEvent) => any): vscode.Disposable {
|
||||
return vscode.workspace.onDidChangeConfiguration(listener);
|
||||
return vscode.workspace.onDidChangeConfiguration(listener);
|
||||
}
|
||||
|
||||
@@ -15,128 +15,128 @@ import * as compatibility from './compatibility';
|
||||
import { getToolPath } from '../config/config';
|
||||
|
||||
export interface Kubectl {
|
||||
checkPresent(errorMessageMode: CheckPresentMessageMode): Promise<boolean>;
|
||||
asJson<T>(command: string): Promise<Errorable<T>>;
|
||||
invokeAsync(command: string, stdin?: string): Promise<ShellResult | undefined>;
|
||||
getContext(): Context;
|
||||
checkPresent(errorMessageMode: CheckPresentMessageMode): Promise<boolean>;
|
||||
asJson<T>(command: string): Promise<Errorable<T>>;
|
||||
invokeAsync(command: string, stdin?: string): Promise<ShellResult | undefined>;
|
||||
getContext(): Context;
|
||||
}
|
||||
|
||||
interface Context {
|
||||
readonly host: Host;
|
||||
readonly fs: FS;
|
||||
readonly shell: Shell;
|
||||
readonly installDependenciesCallback: () => void;
|
||||
binFound: boolean;
|
||||
binPath: string;
|
||||
readonly host: Host;
|
||||
readonly fs: FS;
|
||||
readonly shell: Shell;
|
||||
readonly installDependenciesCallback: () => void;
|
||||
binFound: boolean;
|
||||
binPath: string;
|
||||
}
|
||||
|
||||
class KubectlImpl implements Kubectl {
|
||||
constructor(host: Host, fs: FS, shell: Shell, installDependenciesCallback: () => void, kubectlFound: boolean) {
|
||||
this.context = { host : host, fs : fs, shell : shell, installDependenciesCallback : installDependenciesCallback, binFound : kubectlFound, binPath : 'kubectl' };
|
||||
}
|
||||
constructor(host: Host, fs: FS, shell: Shell, installDependenciesCallback: () => void, kubectlFound: boolean) {
|
||||
this.context = { host: host, fs: fs, shell: shell, installDependenciesCallback: installDependenciesCallback, binFound: kubectlFound, binPath: 'kubectl' };
|
||||
}
|
||||
|
||||
readonly context: Context;
|
||||
readonly context: Context;
|
||||
|
||||
checkPresent(errorMessageMode: CheckPresentMessageMode): Promise<boolean> {
|
||||
return checkPresent(this.context, errorMessageMode);
|
||||
}
|
||||
asJson<T>(command: string): Promise<Errorable<T>> {
|
||||
return asJson(this.context, command);
|
||||
}
|
||||
invokeAsync(command: string, stdin?: string): Promise<ShellResult | undefined> {
|
||||
return invokeAsync(this.context, command, stdin);
|
||||
}
|
||||
checkPresent(errorMessageMode: CheckPresentMessageMode): Promise<boolean> {
|
||||
return checkPresent(this.context, errorMessageMode);
|
||||
}
|
||||
asJson<T>(command: string): Promise<Errorable<T>> {
|
||||
return asJson(this.context, command);
|
||||
}
|
||||
invokeAsync(command: string, stdin?: string): Promise<ShellResult | undefined> {
|
||||
return invokeAsync(this.context, command, stdin);
|
||||
}
|
||||
|
||||
getContext(): Context {
|
||||
return this.context;
|
||||
}
|
||||
getContext(): Context {
|
||||
return this.context;
|
||||
}
|
||||
}
|
||||
|
||||
export function create(host: Host, fs: FS, shell: Shell, installDependenciesCallback: () => void): Kubectl {
|
||||
return new KubectlImpl(host, fs, shell, installDependenciesCallback, false);
|
||||
return new KubectlImpl(host, fs, shell, installDependenciesCallback, false);
|
||||
}
|
||||
|
||||
export enum CheckPresentMessageMode {
|
||||
Command,
|
||||
Activation,
|
||||
Silent,
|
||||
Command,
|
||||
Activation,
|
||||
Silent,
|
||||
}
|
||||
|
||||
async function checkPresent(context: Context, errorMessageMode: CheckPresentMessageMode): Promise<boolean> {
|
||||
if (context.binFound) {
|
||||
return true;
|
||||
}
|
||||
if (context.binFound) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return await checkForKubectlInternal(context, errorMessageMode);
|
||||
return await checkForKubectlInternal(context, errorMessageMode);
|
||||
}
|
||||
|
||||
async function checkForKubectlInternal(context: Context, errorMessageMode: CheckPresentMessageMode): Promise<boolean> {
|
||||
const binName = 'kubectl';
|
||||
const bin = getToolPath(context.host, context.shell, binName);
|
||||
const binName = 'kubectl';
|
||||
const bin = getToolPath(context.host, context.shell, binName);
|
||||
|
||||
const contextMessage = getCheckKubectlContextMessage(errorMessageMode);
|
||||
const inferFailedMessage = localize('binaryNotFound', 'Could not find {0} binary. {1}', binName, contextMessage);
|
||||
const configuredFileMissingMessage = localize('binaryNotInstalled', '{0} is not installed. {1}', bin, contextMessage);
|
||||
const contextMessage = getCheckKubectlContextMessage(errorMessageMode);
|
||||
const inferFailedMessage = localize('binaryNotFound', 'Could not find {0} binary. {1}', binName, contextMessage);
|
||||
const configuredFileMissingMessage = localize('binaryNotInstalled', '{0} is not installed. {1}', bin, contextMessage);
|
||||
|
||||
return await binutil.checkForBinary(context, bin, binName, inferFailedMessage, configuredFileMissingMessage, errorMessageMode !== CheckPresentMessageMode.Silent);
|
||||
return await binutil.checkForBinary(context, bin, binName, inferFailedMessage, configuredFileMissingMessage, errorMessageMode !== CheckPresentMessageMode.Silent);
|
||||
}
|
||||
|
||||
function getCheckKubectlContextMessage(errorMessageMode: CheckPresentMessageMode): string {
|
||||
if (errorMessageMode === CheckPresentMessageMode.Activation) {
|
||||
return localize('kubernetesRequired',' SQL Server Big data cluster requires kubernetes.');
|
||||
} else if (errorMessageMode === CheckPresentMessageMode.Command) {
|
||||
return localize('cannotExecuteCmd', ' Cannot execute command.');
|
||||
}
|
||||
return '';
|
||||
if (errorMessageMode === CheckPresentMessageMode.Activation) {
|
||||
return localize('kubernetesRequired', ' SQL Server Big data cluster requires kubernetes.');
|
||||
} else if (errorMessageMode === CheckPresentMessageMode.Command) {
|
||||
return localize('cannotExecuteCmd', ' Cannot execute command.');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
async function invokeAsync(context: Context, command: string, stdin?: string): Promise<ShellResult | undefined> {
|
||||
if (await checkPresent(context, CheckPresentMessageMode.Command)) {
|
||||
const bin = baseKubectlPath(context);
|
||||
const cmd = `${bin} ${command}`;
|
||||
const sr = await context.shell.exec(cmd, stdin);
|
||||
if (sr && sr.code !== 0) {
|
||||
checkPossibleIncompatibility(context);
|
||||
}
|
||||
return sr;
|
||||
} else {
|
||||
return { code: -1, stdout: '', stderr: '' };
|
||||
}
|
||||
if (await checkPresent(context, CheckPresentMessageMode.Command)) {
|
||||
const bin = baseKubectlPath(context);
|
||||
const cmd = `${bin} ${command}`;
|
||||
const sr = await context.shell.exec(cmd, stdin);
|
||||
if (sr && sr.code !== 0) {
|
||||
checkPossibleIncompatibility(context);
|
||||
}
|
||||
return sr;
|
||||
} else {
|
||||
return { code: -1, stdout: '', stderr: '' };
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: invalidate this when the context changes or if we know kubectl has changed (e.g. config)
|
||||
let checkedCompatibility = false; // We don't want to spam the user (or CPU!) repeatedly running the version check
|
||||
|
||||
async function checkPossibleIncompatibility(context: Context): Promise<void> {
|
||||
if (checkedCompatibility) {
|
||||
return;
|
||||
}
|
||||
checkedCompatibility = true;
|
||||
const compat = await compatibility.check((cmd) => asJson<compatibility.Version>(context, cmd));
|
||||
if (!compatibility.isGuaranteedCompatible(compat) && compat.didCheck) {
|
||||
const versionAlert = localize('kubectlVersionIncompatible', 'kubectl version ${0} may be incompatible with cluster Kubernetes version {1}', compat.clientVersion, compat.serverVersion);
|
||||
context.host.showWarningMessage(versionAlert);
|
||||
}
|
||||
if (checkedCompatibility) {
|
||||
return;
|
||||
}
|
||||
checkedCompatibility = true;
|
||||
const compat = await compatibility.check((cmd) => asJson<compatibility.Version>(context, cmd));
|
||||
if (!compatibility.isGuaranteedCompatible(compat) && compat.didCheck) {
|
||||
const versionAlert = localize('kubectlVersionIncompatible', 'kubectl version ${0} may be incompatible with cluster Kubernetes version {1}', compat.clientVersion, compat.serverVersion);
|
||||
context.host.showWarningMessage(versionAlert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function baseKubectlPath(context: Context): string {
|
||||
let bin = getToolPath(context.host, context.shell, 'kubectl');
|
||||
if (!bin) {
|
||||
bin = 'kubectl';
|
||||
}
|
||||
return bin;
|
||||
let bin = getToolPath(context.host, context.shell, 'kubectl');
|
||||
if (!bin) {
|
||||
bin = 'kubectl';
|
||||
}
|
||||
return bin;
|
||||
}
|
||||
|
||||
async function asJson<T>(context: Context, command: string): Promise<Errorable<T>> {
|
||||
const shellResult = await invokeAsync(context, command);
|
||||
if (!shellResult) {
|
||||
return { succeeded: false, error: [localize('cannotRunCommand', 'Unable to run command ({0})', command)] };
|
||||
}
|
||||
const shellResult = await invokeAsync(context, command);
|
||||
if (!shellResult) {
|
||||
return { succeeded: false, error: [localize('cannotRunCommand', 'Unable to run command ({0})', command)] };
|
||||
}
|
||||
|
||||
if (shellResult.code === 0) {
|
||||
return { succeeded: true, result: JSON.parse(shellResult.stdout.trim()) as T };
|
||||
if (shellResult.code === 0) {
|
||||
return { succeeded: true, result: JSON.parse(shellResult.stdout.trim()) as T };
|
||||
|
||||
}
|
||||
return { succeeded: false, error: [ shellResult.stderr ] };
|
||||
}
|
||||
return { succeeded: false, error: [shellResult.stderr] };
|
||||
}
|
||||
@@ -11,126 +11,126 @@ import { Kubectl } from './kubectl';
|
||||
import { failed, ClusterType } from '../interfaces';
|
||||
|
||||
export interface KubectlContext {
|
||||
readonly clusterName: string;
|
||||
readonly contextName: string;
|
||||
readonly userName: string;
|
||||
readonly active: boolean;
|
||||
readonly clusterName: string;
|
||||
readonly contextName: string;
|
||||
readonly userName: string;
|
||||
readonly active: boolean;
|
||||
}
|
||||
|
||||
interface Kubeconfig {
|
||||
readonly apiVersion: string;
|
||||
readonly 'current-context': string;
|
||||
readonly clusters: {
|
||||
readonly name: string;
|
||||
readonly cluster: {
|
||||
readonly server: string;
|
||||
readonly 'certificate-authority'?: string;
|
||||
readonly 'certificate-authority-data'?: string;
|
||||
};
|
||||
}[] | undefined;
|
||||
readonly contexts: {
|
||||
readonly name: string;
|
||||
readonly context: {
|
||||
readonly cluster: string;
|
||||
readonly user: string;
|
||||
readonly namespace?: string;
|
||||
};
|
||||
}[] | undefined;
|
||||
readonly users: {
|
||||
readonly name: string;
|
||||
readonly user: {};
|
||||
}[] | undefined;
|
||||
readonly apiVersion: string;
|
||||
readonly 'current-context': string;
|
||||
readonly clusters: {
|
||||
readonly name: string;
|
||||
readonly cluster: {
|
||||
readonly server: string;
|
||||
readonly 'certificate-authority'?: string;
|
||||
readonly 'certificate-authority-data'?: string;
|
||||
};
|
||||
}[] | undefined;
|
||||
readonly contexts: {
|
||||
readonly name: string;
|
||||
readonly context: {
|
||||
readonly cluster: string;
|
||||
readonly user: string;
|
||||
readonly namespace?: string;
|
||||
};
|
||||
}[] | undefined;
|
||||
readonly users: {
|
||||
readonly name: string;
|
||||
readonly user: {};
|
||||
}[] | undefined;
|
||||
}
|
||||
|
||||
export interface ClusterConfig {
|
||||
readonly server: string;
|
||||
readonly certificateAuthority: string | undefined;
|
||||
readonly server: string;
|
||||
readonly certificateAuthority: string | undefined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function getKubeconfig(kubectl: Kubectl): Promise<Kubeconfig | null> {
|
||||
const shellResult = await kubectl.asJson<any>('config view -o json');
|
||||
if (failed(shellResult)) {
|
||||
vscode.window.showErrorMessage(shellResult.error[0]);
|
||||
return null;
|
||||
}
|
||||
return shellResult.result;
|
||||
const shellResult = await kubectl.asJson<any>('config view -o json');
|
||||
if (failed(shellResult)) {
|
||||
vscode.window.showErrorMessage(shellResult.error[0]);
|
||||
return null;
|
||||
}
|
||||
return shellResult.result;
|
||||
}
|
||||
|
||||
export async function getCurrentClusterConfig(kubectl: Kubectl): Promise<ClusterConfig | undefined> {
|
||||
const kubeConfig = await getKubeconfig(kubectl);
|
||||
if (!kubeConfig || !kubeConfig.clusters || !kubeConfig.contexts) {
|
||||
return undefined;
|
||||
}
|
||||
const contextConfig = kubeConfig.contexts.find((context) => context.name === kubeConfig['current-context'])!;
|
||||
const clusterConfig = kubeConfig.clusters.find((cluster) => cluster.name === contextConfig.context.cluster)!;
|
||||
return {
|
||||
server: clusterConfig.cluster.server,
|
||||
certificateAuthority: clusterConfig.cluster['certificate-authority']
|
||||
};
|
||||
const kubeConfig = await getKubeconfig(kubectl);
|
||||
if (!kubeConfig || !kubeConfig.clusters || !kubeConfig.contexts) {
|
||||
return undefined;
|
||||
}
|
||||
const contextConfig = kubeConfig.contexts.find((context) => context.name === kubeConfig['current-context'])!;
|
||||
const clusterConfig = kubeConfig.clusters.find((cluster) => cluster.name === contextConfig.context.cluster)!;
|
||||
return {
|
||||
server: clusterConfig.cluster.server,
|
||||
certificateAuthority: clusterConfig.cluster['certificate-authority']
|
||||
};
|
||||
}
|
||||
|
||||
export async function getContexts(kubectl: Kubectl): Promise<KubectlContext[]> {
|
||||
const kubectlConfig = await getKubeconfig(kubectl);
|
||||
if (!kubectlConfig) {
|
||||
return [];
|
||||
}
|
||||
const currentContext = kubectlConfig['current-context'];
|
||||
const contexts = kubectlConfig.contexts || [];
|
||||
return contexts.map((c) => {
|
||||
return {
|
||||
clusterName: c.context.cluster,
|
||||
contextName: c.name,
|
||||
userName: c.context.user,
|
||||
active: c.name === currentContext
|
||||
};
|
||||
});
|
||||
const kubectlConfig = await getKubeconfig(kubectl);
|
||||
if (!kubectlConfig) {
|
||||
return [];
|
||||
}
|
||||
const currentContext = kubectlConfig['current-context'];
|
||||
const contexts = kubectlConfig.contexts || [];
|
||||
return contexts.map((c) => {
|
||||
return {
|
||||
clusterName: c.context.cluster,
|
||||
contextName: c.name,
|
||||
userName: c.context.user,
|
||||
active: c.name === currentContext
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export async function setContext(kubectl: Kubectl, targetContext: string): Promise<void> {
|
||||
const shellResult = await kubectl.invokeAsync(`config use-context ${targetContext}`);
|
||||
if (!shellResult || shellResult.code !== 0) {
|
||||
// TODO: Update error handling for now.
|
||||
let errMsg = shellResult ? shellResult.stderr : localize('runKubectlFailed', 'Unable to run kubectl');
|
||||
vscode.window.showErrorMessage(localize('setClusterFailed', 'Failed to set \'{0}\' as current cluster: {1}', targetContext, errMsg));
|
||||
}
|
||||
const shellResult = await kubectl.invokeAsync(`config use-context ${targetContext}`);
|
||||
if (!shellResult || shellResult.code !== 0) {
|
||||
// TODO: Update error handling for now.
|
||||
let errMsg = shellResult ? shellResult.stderr : localize('runKubectlFailed', 'Unable to run kubectl');
|
||||
vscode.window.showErrorMessage(localize('setClusterFailed', 'Failed to set \'{0}\' as current cluster: {1}', targetContext, errMsg));
|
||||
}
|
||||
}
|
||||
|
||||
export async function inferCurrentClusterType(kubectl: Kubectl): Promise<ClusterType> {
|
||||
let latestContextName = '';
|
||||
let latestContextName = '';
|
||||
|
||||
const ctxsr = await kubectl.invokeAsync('config current-context');
|
||||
if (ctxsr && ctxsr.code === 0) {
|
||||
latestContextName = ctxsr.stdout.trim();
|
||||
} else {
|
||||
return ClusterType.Other;
|
||||
}
|
||||
const ctxsr = await kubectl.invokeAsync('config current-context');
|
||||
if (ctxsr && ctxsr.code === 0) {
|
||||
latestContextName = ctxsr.stdout.trim();
|
||||
} else {
|
||||
return ClusterType.Other;
|
||||
}
|
||||
|
||||
const cisr = await kubectl.invokeAsync('cluster-info');
|
||||
if (!cisr || cisr.code !== 0) {
|
||||
return ClusterType.Unknown;
|
||||
}
|
||||
const masterInfos = cisr.stdout.split('\n')
|
||||
.filter((s) => s.indexOf('master is running at') >= 0);
|
||||
const cisr = await kubectl.invokeAsync('cluster-info');
|
||||
if (!cisr || cisr.code !== 0) {
|
||||
return ClusterType.Unknown;
|
||||
}
|
||||
const masterInfos = cisr.stdout.split('\n')
|
||||
.filter((s) => s.indexOf('master is running at') >= 0);
|
||||
|
||||
if (masterInfos.length === 0) {
|
||||
return ClusterType.Other;
|
||||
}
|
||||
if (masterInfos.length === 0) {
|
||||
return ClusterType.Other;
|
||||
}
|
||||
|
||||
const masterInfo = masterInfos[0];
|
||||
if (masterInfo.indexOf('azmk8s.io') >= 0 || masterInfo.indexOf('azure.com') >= 0) {
|
||||
return ClusterType.AKS;
|
||||
}
|
||||
const masterInfo = masterInfos[0];
|
||||
if (masterInfo.indexOf('azmk8s.io') >= 0 || masterInfo.indexOf('azure.com') >= 0) {
|
||||
return ClusterType.AKS;
|
||||
}
|
||||
|
||||
if (latestContextName) {
|
||||
const gcsr = await kubectl.invokeAsync(`config get-contexts ${latestContextName}`);
|
||||
if (gcsr && gcsr.code === 0) {
|
||||
if (gcsr.stdout.indexOf('minikube') >= 0) {
|
||||
return ClusterType.Minikube;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latestContextName) {
|
||||
const gcsr = await kubectl.invokeAsync(`config get-contexts ${latestContextName}`);
|
||||
if (gcsr && gcsr.code === 0) {
|
||||
if (gcsr.stdout.indexOf('minikube') >= 0) {
|
||||
return ClusterType.Minikube;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ClusterType.Other;
|
||||
return ClusterType.Other;
|
||||
}
|
||||
@@ -8,22 +8,22 @@ import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export interface ISqlServerBigDataClusterChannel {
|
||||
showOutput(message: any, title?: string): void;
|
||||
showOutput(message: any, title?: string): void;
|
||||
}
|
||||
|
||||
const outputChannelName = localize('bigDataClusterOutputChannel', 'SQL Server big data cluster');
|
||||
class SqlServerBigDataCluster implements ISqlServerBigDataClusterChannel {
|
||||
private readonly channel: vscode.OutputChannel = vscode.window.createOutputChannel(outputChannelName);
|
||||
private readonly channel: vscode.OutputChannel = vscode.window.createOutputChannel(outputChannelName);
|
||||
|
||||
showOutput(message: any, title?: string): void {
|
||||
if (title) {
|
||||
const simplifiedTime = (new Date()).toISOString().replace(/z|t/gi, ' ').trim(); // YYYY-MM-DD HH:mm:ss.sss
|
||||
const hightlightingTitle = `[${title} ${simplifiedTime}]`;
|
||||
this.channel.appendLine(hightlightingTitle);
|
||||
}
|
||||
this.channel.appendLine(message);
|
||||
this.channel.show();
|
||||
}
|
||||
showOutput(message: any, title?: string): void {
|
||||
if (title) {
|
||||
const simplifiedTime = (new Date()).toISOString().replace(/z|t/gi, ' ').trim(); // YYYY-MM-DD HH:mm:ss.sss
|
||||
const hightlightingTitle = `[${title} ${simplifiedTime}]`;
|
||||
this.channel.appendLine(hightlightingTitle);
|
||||
}
|
||||
this.channel.appendLine(message);
|
||||
this.channel.show();
|
||||
}
|
||||
}
|
||||
|
||||
export const sqlserverbigdataclusterchannel: ISqlServerBigDataClusterChannel = new SqlServerBigDataCluster();
|
||||
@@ -35,26 +35,26 @@ export function deactivate(): void {
|
||||
}
|
||||
|
||||
export async function installDependencies() {
|
||||
const gotKubectl = await kubectl.checkPresent(CheckPresentMessageMode.Silent);
|
||||
const gotKubectl = await kubectl.checkPresent(CheckPresentMessageMode.Silent);
|
||||
|
||||
|
||||
const installPromises = [
|
||||
installDependency('kubectl', gotKubectl, installKubectl)
|
||||
];
|
||||
const installPromises = [
|
||||
installDependency('kubectl', gotKubectl, installKubectl)
|
||||
];
|
||||
|
||||
await Promise.all(installPromises);
|
||||
await Promise.all(installPromises);
|
||||
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('done', 'Done'));
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('done', 'Done'));
|
||||
}
|
||||
|
||||
async function installDependency(name: string, alreadyGot: boolean, installFunc: (shell: Shell) => Promise<Errorable<null>>): Promise<void> {
|
||||
if (alreadyGot) {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('dependencyInstalled', '{0} already installed...', name));
|
||||
} else {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('installingDependency', 'Installing {0}...', name));
|
||||
const result = await installFunc(shell);
|
||||
if (failed(result)) {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('installingDependencyFailed', 'Unable to install {0}: {1}', name, result.error[0]));
|
||||
}
|
||||
}
|
||||
if (alreadyGot) {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('dependencyInstalled', '{0} already installed...', name));
|
||||
} else {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('installingDependency', 'Installing {0}...', name));
|
||||
const result = await installFunc(shell);
|
||||
if (failed(result)) {
|
||||
sqlserverbigdataclusterchannel.showOutput(localize('installingDependencyFailed', 'Unable to install {0}: {1}', name, result.error[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import { Kubectl } from './kubectl/kubectl';
|
||||
*/
|
||||
export class MainController {
|
||||
protected _context: vscode.ExtensionContext;
|
||||
protected _kubectl : Kubectl;
|
||||
protected _kubectl: Kubectl;
|
||||
|
||||
public constructor(context: vscode.ExtensionContext, kubectl: Kubectl) {
|
||||
this._context = context;
|
||||
|
||||
@@ -11,16 +11,16 @@ import mkdirp = require('mkdirp');
|
||||
import { Kubectl, baseKubectlPath } from '../kubectl/kubectl';
|
||||
import { KubectlContext } from '../kubectl/kubectlUtils';
|
||||
|
||||
export interface Scriptable {
|
||||
getScriptProperties(): Promise<ScriptingDictionary<string>>;
|
||||
getTargetKubectlContext() : KubectlContext;
|
||||
}
|
||||
export interface Scriptable {
|
||||
getScriptProperties(): Promise<ScriptingDictionary<string>>;
|
||||
getTargetKubectlContext(): KubectlContext;
|
||||
}
|
||||
|
||||
export interface ScriptingDictionary<V> {
|
||||
export interface ScriptingDictionary<V> {
|
||||
[name: string]: V;
|
||||
}
|
||||
|
||||
const deployFilePrefix : string = 'mssql-bdc-deploy';
|
||||
const deployFilePrefix: string = 'mssql-bdc-deploy';
|
||||
export class ScriptGenerator {
|
||||
|
||||
private _shell: Shell;
|
||||
@@ -33,7 +33,7 @@ export class ScriptGenerator {
|
||||
this._kubectlPath = baseKubectlPath(this._kubectl.getContext());
|
||||
}
|
||||
|
||||
public async generateDeploymentScript(scriptable: Scriptable) : Promise<void> {
|
||||
public async generateDeploymentScript(scriptable: Scriptable): Promise<void> {
|
||||
let targetClusterName = scriptable.getTargetKubectlContext().clusterName;
|
||||
let targetContextName = scriptable.getTargetKubectlContext().contextName;
|
||||
|
||||
@@ -67,7 +67,7 @@ export class ScriptGenerator {
|
||||
}
|
||||
|
||||
const handleError = (err: NodeJS.ErrnoException) => {
|
||||
if (err) {
|
||||
vscode.window.showErrorMessage(err.message);
|
||||
}
|
||||
if (err) {
|
||||
vscode.window.showErrorMessage(err.message);
|
||||
}
|
||||
};
|
||||
@@ -5,61 +5,61 @@
|
||||
import * as sysfs from 'fs';
|
||||
|
||||
export interface FS {
|
||||
existsSync(path: string): boolean;
|
||||
readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
|
||||
readFileSync(filename: string, encoding: string): string;
|
||||
readFileToBufferSync(filename: string): Buffer;
|
||||
writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
|
||||
writeFileSync(filename: string, data: any): void;
|
||||
dirSync(path: string): string[];
|
||||
unlinkAsync(path: string): Promise<void>;
|
||||
existsAsync(path: string): Promise<boolean>;
|
||||
openAsync(path: string, flags: string): Promise<void>;
|
||||
statSync(path: string): sysfs.Stats;
|
||||
existsSync(path: string): boolean;
|
||||
readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
|
||||
readFileSync(filename: string, encoding: string): string;
|
||||
readFileToBufferSync(filename: string): Buffer;
|
||||
writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
|
||||
writeFileSync(filename: string, data: any): void;
|
||||
dirSync(path: string): string[];
|
||||
unlinkAsync(path: string): Promise<void>;
|
||||
existsAsync(path: string): Promise<boolean>;
|
||||
openAsync(path: string, flags: string): Promise<void>;
|
||||
statSync(path: string): sysfs.Stats;
|
||||
}
|
||||
|
||||
export const fs: FS = {
|
||||
existsSync: (path) => sysfs.existsSync(path),
|
||||
readFile: (filename, encoding, callback) => sysfs.readFile(filename, encoding, callback),
|
||||
readFileSync: (filename, encoding) => sysfs.readFileSync(filename, encoding),
|
||||
readFileToBufferSync: (filename) => sysfs.readFileSync(filename),
|
||||
writeFile: (filename, data, callback) => sysfs.writeFile(filename, data, callback),
|
||||
writeFileSync: (filename, data) => sysfs.writeFileSync(filename, data),
|
||||
dirSync: (path) => sysfs.readdirSync(path),
|
||||
existsSync: (path) => sysfs.existsSync(path),
|
||||
readFile: (filename, encoding, callback) => sysfs.readFile(filename, encoding, callback),
|
||||
readFileSync: (filename, encoding) => sysfs.readFileSync(filename, encoding),
|
||||
readFileToBufferSync: (filename) => sysfs.readFileSync(filename),
|
||||
writeFile: (filename, data, callback) => sysfs.writeFile(filename, data, callback),
|
||||
writeFileSync: (filename, data) => sysfs.writeFileSync(filename, data),
|
||||
dirSync: (path) => sysfs.readdirSync(path),
|
||||
|
||||
unlinkAsync: (path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
sysfs.unlink(path, (error) => {
|
||||
if (error) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
unlinkAsync: (path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
sysfs.unlink(path, (error) => {
|
||||
if (error) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
existsAsync: (path) => {
|
||||
return new Promise((resolve) => {
|
||||
sysfs.exists(path, (exists) => {
|
||||
resolve(exists);
|
||||
});
|
||||
});
|
||||
},
|
||||
existsAsync: (path) => {
|
||||
return new Promise((resolve) => {
|
||||
sysfs.exists(path, (exists) => {
|
||||
resolve(exists);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
openAsync: (path, flags) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
sysfs.open(path, flags, (error, _fd) => {
|
||||
if (error) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
openAsync: (path, flags) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
sysfs.open(path, flags, (error, _fd) => {
|
||||
if (error) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
statSync: (path) => sysfs.statSync(path)
|
||||
statSync: (path) => sysfs.statSync(path)
|
||||
};
|
||||
|
||||
@@ -12,193 +12,193 @@ import { getActiveKubeconfig, getToolPath } from '../config/config';
|
||||
import { host } from '../kubectl/host';
|
||||
|
||||
export enum Platform {
|
||||
Windows,
|
||||
MacOS,
|
||||
Linux,
|
||||
Unsupported,
|
||||
Windows,
|
||||
MacOS,
|
||||
Linux,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
export interface ExecCallback extends shelljs.ExecCallback {}
|
||||
export interface ExecCallback extends shelljs.ExecCallback { }
|
||||
|
||||
export interface Shell {
|
||||
isWindows(): boolean;
|
||||
isUnix(): boolean;
|
||||
platform(): Platform;
|
||||
home(): string;
|
||||
combinePath(basePath: string, relativePath: string): string;
|
||||
fileUri(filePath: string): vscode.Uri;
|
||||
execOpts(): any;
|
||||
exec(cmd: string, stdin?: string): Promise<ShellResult | undefined>;
|
||||
execCore(cmd: string, opts: any, stdin?: string): Promise<ShellResult>;
|
||||
unquotedPath(path: string): string;
|
||||
which(bin: string): string | null;
|
||||
cat(path: string): string;
|
||||
ls(path: string): string[];
|
||||
isWindows(): boolean;
|
||||
isUnix(): boolean;
|
||||
platform(): Platform;
|
||||
home(): string;
|
||||
combinePath(basePath: string, relativePath: string): string;
|
||||
fileUri(filePath: string): vscode.Uri;
|
||||
execOpts(): any;
|
||||
exec(cmd: string, stdin?: string): Promise<ShellResult | undefined>;
|
||||
execCore(cmd: string, opts: any, stdin?: string): Promise<ShellResult>;
|
||||
unquotedPath(path: string): string;
|
||||
which(bin: string): string | null;
|
||||
cat(path: string): string;
|
||||
ls(path: string): string[];
|
||||
}
|
||||
|
||||
export const shell: Shell = {
|
||||
isWindows : isWindows,
|
||||
isUnix : isUnix,
|
||||
platform : platform,
|
||||
home : home,
|
||||
combinePath : combinePath,
|
||||
fileUri : fileUri,
|
||||
execOpts : execOpts,
|
||||
exec : exec,
|
||||
execCore : execCore,
|
||||
unquotedPath : unquotedPath,
|
||||
which: which,
|
||||
cat: cat,
|
||||
ls: ls,
|
||||
isWindows: isWindows,
|
||||
isUnix: isUnix,
|
||||
platform: platform,
|
||||
home: home,
|
||||
combinePath: combinePath,
|
||||
fileUri: fileUri,
|
||||
execOpts: execOpts,
|
||||
exec: exec,
|
||||
execCore: execCore,
|
||||
unquotedPath: unquotedPath,
|
||||
which: which,
|
||||
cat: cat,
|
||||
ls: ls,
|
||||
};
|
||||
|
||||
const WINDOWS: string = 'win32';
|
||||
|
||||
export interface ShellResult {
|
||||
readonly code: number;
|
||||
readonly stdout: string;
|
||||
readonly stderr: string;
|
||||
readonly code: number;
|
||||
readonly stdout: string;
|
||||
readonly stderr: string;
|
||||
}
|
||||
|
||||
export type ShellHandler = (code: number, stdout: string, stderr: string) => void;
|
||||
|
||||
function isWindows(): boolean {
|
||||
return (process.platform === WINDOWS);
|
||||
return (process.platform === WINDOWS);
|
||||
}
|
||||
|
||||
function isUnix(): boolean {
|
||||
return !isWindows();
|
||||
return !isWindows();
|
||||
}
|
||||
|
||||
function platform(): Platform {
|
||||
switch (process.platform) {
|
||||
case 'win32': return Platform.Windows;
|
||||
case 'darwin': return Platform.MacOS;
|
||||
case 'linux': return Platform.Linux;
|
||||
default: return Platform.Unsupported;
|
||||
}
|
||||
switch (process.platform) {
|
||||
case 'win32': return Platform.Windows;
|
||||
case 'darwin': return Platform.MacOS;
|
||||
case 'linux': return Platform.Linux;
|
||||
default: return Platform.Unsupported;
|
||||
}
|
||||
}
|
||||
|
||||
function concatIfBoth(s1: string | undefined, s2: string | undefined): string | undefined {
|
||||
return s1 && s2 ? s1.concat(s2) : undefined;
|
||||
return s1 && s2 ? s1.concat(s2) : undefined;
|
||||
}
|
||||
|
||||
function home(): string {
|
||||
return process.env['HOME'] ||
|
||||
concatIfBoth(process.env['HOMEDRIVE'], process.env['HOMEPATH']) ||
|
||||
process.env['USERPROFILE'] ||
|
||||
'';
|
||||
return process.env['HOME'] ||
|
||||
concatIfBoth(process.env['HOMEDRIVE'], process.env['HOMEPATH']) ||
|
||||
process.env['USERPROFILE'] ||
|
||||
'';
|
||||
}
|
||||
|
||||
function combinePath(basePath: string, relativePath: string) {
|
||||
let separator = '/';
|
||||
if (isWindows()) {
|
||||
relativePath = relativePath.replace(/\//g, '\\');
|
||||
separator = '\\';
|
||||
}
|
||||
return basePath + separator + relativePath;
|
||||
let separator = '/';
|
||||
if (isWindows()) {
|
||||
relativePath = relativePath.replace(/\//g, '\\');
|
||||
separator = '\\';
|
||||
}
|
||||
return basePath + separator + relativePath;
|
||||
}
|
||||
|
||||
function isWindowsFilePath(filePath: string) {
|
||||
return filePath[1] === ':' && filePath[2] === '\\';
|
||||
return filePath[1] === ':' && filePath[2] === '\\';
|
||||
}
|
||||
|
||||
function fileUri(filePath: string): vscode.Uri {
|
||||
if (isWindowsFilePath(filePath)) {
|
||||
return vscode.Uri.parse('file:///' + filePath.replace(/\\/g, '/'));
|
||||
}
|
||||
return vscode.Uri.parse('file://' + filePath);
|
||||
if (isWindowsFilePath(filePath)) {
|
||||
return vscode.Uri.parse('file:///' + filePath.replace(/\\/g, '/'));
|
||||
}
|
||||
return vscode.Uri.parse('file://' + filePath);
|
||||
}
|
||||
|
||||
function execOpts(): any {
|
||||
let env = process.env;
|
||||
if (isWindows()) {
|
||||
env = Object.assign({ }, env, { HOME: home() });
|
||||
}
|
||||
env = shellEnvironment(env);
|
||||
const opts = {
|
||||
cwd: vscode.workspace.rootPath,
|
||||
env: env,
|
||||
async: true
|
||||
};
|
||||
return opts;
|
||||
let env = process.env;
|
||||
if (isWindows()) {
|
||||
env = Object.assign({}, env, { HOME: home() });
|
||||
}
|
||||
env = shellEnvironment(env);
|
||||
const opts = {
|
||||
cwd: vscode.workspace.rootPath,
|
||||
env: env,
|
||||
async: true
|
||||
};
|
||||
return opts;
|
||||
}
|
||||
|
||||
async function exec(cmd: string, stdin?: string): Promise<ShellResult | undefined> {
|
||||
try {
|
||||
return await execCore(cmd, execOpts(), stdin);
|
||||
} catch (ex) {
|
||||
vscode.window.showErrorMessage(ex);
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
return await execCore(cmd, execOpts(), stdin);
|
||||
} catch (ex) {
|
||||
vscode.window.showErrorMessage(ex);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function execCore(cmd: string, opts: any, stdin?: string): Promise<ShellResult> {
|
||||
return new Promise<ShellResult>((resolve) => {
|
||||
const proc = shelljs.exec(cmd, opts, (code, stdout, stderr) => resolve({code : code, stdout : stdout, stderr : stderr}));
|
||||
if (stdin) {
|
||||
proc.stdin.end(stdin);
|
||||
}
|
||||
});
|
||||
return new Promise<ShellResult>((resolve) => {
|
||||
const proc = shelljs.exec(cmd, opts, (code, stdout, stderr) => resolve({ code: code, stdout: stdout, stderr: stderr }));
|
||||
if (stdin) {
|
||||
proc.stdin.end(stdin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unquotedPath(path: string): string {
|
||||
if (isWindows() && path && path.length > 1 && path.startsWith('"') && path.endsWith('"')) {
|
||||
return path.substring(1, path.length - 1);
|
||||
}
|
||||
return path;
|
||||
if (isWindows() && path && path.length > 1 && path.startsWith('"') && path.endsWith('"')) {
|
||||
return path.substring(1, path.length - 1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export function shellEnvironment(baseEnvironment: any): any {
|
||||
const env = Object.assign({}, baseEnvironment);
|
||||
const pathVariable = pathVariableName(env);
|
||||
for (const tool of ['kubectl']) {
|
||||
const toolPath = getToolPath(host, shell, tool);
|
||||
if (toolPath) {
|
||||
const toolDirectory = path.dirname(toolPath);
|
||||
const currentPath = env[pathVariable];
|
||||
env[pathVariable] = toolDirectory + (currentPath ? `${pathEntrySeparator()}${currentPath}` : '');
|
||||
}
|
||||
}
|
||||
const env = Object.assign({}, baseEnvironment);
|
||||
const pathVariable = pathVariableName(env);
|
||||
for (const tool of ['kubectl']) {
|
||||
const toolPath = getToolPath(host, shell, tool);
|
||||
if (toolPath) {
|
||||
const toolDirectory = path.dirname(toolPath);
|
||||
const currentPath = env[pathVariable];
|
||||
env[pathVariable] = toolDirectory + (currentPath ? `${pathEntrySeparator()}${currentPath}` : '');
|
||||
}
|
||||
}
|
||||
|
||||
const kubeconfig = getActiveKubeconfig();
|
||||
if (kubeconfig) {
|
||||
env['KUBECONFIG'] = kubeconfig;
|
||||
}
|
||||
const kubeconfig = getActiveKubeconfig();
|
||||
if (kubeconfig) {
|
||||
env['KUBECONFIG'] = kubeconfig;
|
||||
}
|
||||
|
||||
return env;
|
||||
return env;
|
||||
}
|
||||
|
||||
function pathVariableName(env: any): string {
|
||||
if (isWindows()) {
|
||||
for (const v of Object.keys(env)) {
|
||||
if (v.toLowerCase() === 'path') {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'PATH';
|
||||
if (isWindows()) {
|
||||
for (const v of Object.keys(env)) {
|
||||
if (v.toLowerCase() === 'path') {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'PATH';
|
||||
}
|
||||
|
||||
function pathEntrySeparator() {
|
||||
return isWindows() ? ';' : ':';
|
||||
return isWindows() ? ';' : ':';
|
||||
}
|
||||
|
||||
function which(bin: string): string | null {
|
||||
return shelljs.which(bin);
|
||||
return shelljs.which(bin);
|
||||
}
|
||||
|
||||
function cat(path: string): string {
|
||||
return shelljs.cat(path);
|
||||
return shelljs.cat(path);
|
||||
}
|
||||
|
||||
function ls(path: string): string[] {
|
||||
return shelljs.ls(path);
|
||||
return shelljs.ls(path);
|
||||
}
|
||||
|
||||
export function shellMessage(sr: ShellResult | undefined, invocationFailureMessage: string): string {
|
||||
if (!sr) {
|
||||
return invocationFailureMessage;
|
||||
}
|
||||
return sr.code === 0 ? sr.stdout : sr.stderr;
|
||||
if (!sr) {
|
||||
return invocationFailureMessage;
|
||||
}
|
||||
return sr.code === 0 ? sr.stdout : sr.stderr;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
import { CreateClusterWizard } from '../createClusterWizard';
|
||||
import * as nls from 'vscode-nls';
|
||||
@@ -347,7 +345,7 @@ export class ClusterProfilePage extends WizardPageBase<CreateClusterWizard> {
|
||||
case ClusterPoolType.Spark:
|
||||
return localize('bdc-create.SparkPoolDisplayName', 'Spark pool');
|
||||
default:
|
||||
throw 'unknown pool type';
|
||||
throw new Error('unknown pool type');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +362,7 @@ export class ClusterProfilePage extends WizardPageBase<CreateClusterWizard> {
|
||||
case ClusterPoolType.Spark:
|
||||
return localize('bdc-create.SparkPoolDescription', 'TODO: Add description');
|
||||
default:
|
||||
throw 'unknown pool type';
|
||||
throw new Error('unknown pool type');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { WizardPageBase } from '../../wizardPageBase';
|
||||
|
||||
Reference in New Issue
Block a user