diff --git a/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-aks.ipynb b/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-aks.ipynb deleted file mode 100644 index 5ae0b48f5c..0000000000 --- a/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-aks.ipynb +++ /dev/null @@ -1,29 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python", - "version": "3.6.6", - "mimetype": "text/x-python", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "file_extension": ".py" - } - }, - "nbformat_minor": 2, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "TODO", - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-existing-cluster.ipynb b/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-existing-cluster.ipynb deleted file mode 100644 index 5ae0b48f5c..0000000000 --- a/extensions/resource-deployment/notebooks/sql2019-ctp25-bdc-existing-cluster.ipynb +++ /dev/null @@ -1,29 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python", - "version": "3.6.6", - "mimetype": "text/x-python", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "file_extension": ".py" - } - }, - "nbformat_minor": 2, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "TODO", - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/extensions/resource-deployment/package.json b/extensions/resource-deployment/package.json index 61a4c555fd..97fdfaaa63 100644 --- a/extensions/resource-deployment/package.json +++ b/extensions/resource-deployment/package.json @@ -13,8 +13,7 @@ "azdata": "^1.6.0" }, "activationEvents": [ - "onCommand:azdata.resource.sql-image.deploy", - "onCommand:azdata.resource.sql-bdc.deploy" + "*" ], "main": "./out/main", "repository": { @@ -22,7 +21,8 @@ "url": "https://github.com/Microsoft/azuredatastudio.git" }, "extensionDependencies": [ - "Microsoft.mssql" + "microsoft.mssql", + "microsoft.notebook" ], "contributes": { "commands": [ @@ -35,6 +35,11 @@ "command": "azdata.resource.sql-bdc.deploy", "title": "%deploy-sql-bdc-command-name%", "category": "%deploy-resource-command-category%" + }, + { + "command": "azdata.resource.deploy", + "title": "%deploy-resource-command-name%", + "category": "%deploy-resource-command-category%" } ], "menus": { @@ -119,10 +124,6 @@ "name": "version", "displayName": "%version-display-name%", "values": [ - { - "name": "ctp2.5", - "displayName": "%sql-2019ctp25-display-name%" - }, { "name": "ctp3.0", "displayName": "%sql-2019ctp30-display-name%" @@ -145,33 +146,6 @@ } ], "providers": [ - { - "notebook": "%bdc-ctp25-aks-notebook%", - "requiredTools": [ - { - "name": "kubectl" - }, - { - "name": "azcli" - }, - { - "name": "mssqlctl" - } - ], - "when": "target=aks&&version=ctp2.5" - }, - { - "notebook": "%bdc-ctp25-existing-cluster-notebook%", - "requiredTools": [ - { - "name": "kubectl" - }, - { - "name": "mssqlctl" - } - ], - "when": "target=existingCluster&&version=ctp2.5" - }, { "notebook": "%bdc-ctp30-aks-notebook%", "requiredTools": [ diff --git a/extensions/resource-deployment/package.nls.json b/extensions/resource-deployment/package.nls.json index 8bdd24ffd3..2328dabbde 100644 --- a/extensions/resource-deployment/package.nls.json +++ b/extensions/resource-deployment/package.nls.json @@ -3,6 +3,7 @@ "extension-description": "Provides a notebook-based experience to deploy SQL Server and other Azure Data Services", "deploy-sql-image-command-name": "Deploy SQL Server on Docker…", "deploy-sql-bdc-command-name": "Deploy SQL Server Big Data Cluster…", + "deploy-resource-command-name": "Deploy SQL Server…", "deploy-resource-command-category": "Resource Deployment", "resource-type-sql-image-display-name": "Container Image", "resource-type-sql-image-description": "SQL Server container image on Docker", @@ -13,13 +14,10 @@ "sql-2019-display-name": "SQL Server 2019", "sql-2017-docker-notebook": "./notebooks/sql2017-image-docker.ipynb", "sql-2019-docker-notebook": "./notebooks/sql2019-image-docker.ipynb", - "sql-2019ctp25-display-name": "SQL Server 2019 Big Data Cluster CTP 2.5", "sql-2019ctp30-display-name": "SQL Server 2019 Big Data Cluster CTP 3.0", "bdc-deployment-target": "Deployment target", "bdc-deployment-target-aks": "New Azure Kubernetes Service Cluster", "bdc-deployment-target-existing-cluster": "Existing Kubernetes Cluster", - "bdc-ctp25-aks-notebook": "./notebooks/sql2019-ctp25-bdc-aks.ipynb", - "bdc-ctp25-existing-cluster-notebook": "./notebooks/sql2019-ctp25-bdc-existing-cluster.ipynb", "bdc-ctp30-aks-notebook": "./notebooks/sql2019-ctp30-bdc-aks.ipynb", "bdc-ctp30-existing-cluster-notebook": "./notebooks/sql2019-ctp30-bdc-existing-cluster.ipynb" } \ No newline at end of file diff --git a/extensions/resource-deployment/src/interfaces.ts b/extensions/resource-deployment/src/interfaces.ts index be4f53d1da..bae922cbfa 100644 --- a/extensions/resource-deployment/src/interfaces.ts +++ b/extensions/resource-deployment/src/interfaces.ts @@ -51,28 +51,9 @@ export enum ToolType { MSSQLCtl } -export interface ToolStatusInfo { - type: ToolType; - name: string; - description: string; - version: string; - status: ToolInstallationStatus; -} - export interface ITool { readonly name: string; readonly displayName: string; readonly description: string; readonly type: ToolType; - readonly supportAutoInstall: boolean; - - getInstallationStatus(versionExpression: string): Thenable; - install(version: string): Thenable; -} - -export enum ToolInstallationStatus { - NotInstalled, - Installed, - Installing, - FailedToInstall } \ No newline at end of file diff --git a/extensions/resource-deployment/src/main.ts b/extensions/resource-deployment/src/main.ts index 2e0fe06c91..8de49da3b6 100644 --- a/extensions/resource-deployment/src/main.ts +++ b/extensions/resource-deployment/src/main.ts @@ -28,14 +28,12 @@ export function activate(context: vscode.ExtensionContext) { validationFailures.forEach(message => console.error(message)); return; } - const openDialog = (resourceTypeName: string) => { const filtered = resourceTypes.filter(resourceType => resourceType.name === resourceTypeName); if (filtered.length !== 1) { vscode.window.showErrorMessage(localize('resourceDeployment.UnknownResourceType', 'The resource type: {0} is not defined', resourceTypeName)); - } - else { - let dialog = new ResourceDeploymentDialog(context, notebookService, toolsService, resourceTypeService, filtered[0]); + } else { + const dialog = new ResourceDeploymentDialog(context, notebookService, toolsService, resourceTypeService, filtered[0]); dialog.open(); } }; @@ -46,6 +44,9 @@ export function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand('azdata.resource.sql-bdc.deploy', () => { openDialog('sql-bdc'); }); + vscode.commands.registerCommand('azdata.resource.deploy', () => { + openDialog('sql-image'); + }); } // this method is called when your extension is deactivated diff --git a/extensions/resource-deployment/src/services/tools/azCLITool.ts b/extensions/resource-deployment/src/services/tools/azCLITool.ts index 99cc4383c3..8218269158 100644 --- a/extensions/resource-deployment/src/services/tools/azCLITool.ts +++ b/extensions/resource-deployment/src/services/tools/azCLITool.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolType, ITool, ToolInstallationStatus } from '../../interfaces'; +import { ToolType, ITool } from '../../interfaces'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); @@ -23,21 +23,4 @@ export class AzCliTool implements ITool { get displayName(): string { return localize('resourceDeployment.AzCLIDisplayName', 'Azure CLI'); } - - get supportAutoInstall(): boolean { - return true; - } - - install(version: string): Thenable { - throw new Error('Method not implemented.'); - } - - getInstallationStatus(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(ToolInstallationStatus.Installed); - }, 500); - }); - return promise; - } } \ No newline at end of file diff --git a/extensions/resource-deployment/src/services/tools/dockerTool.ts b/extensions/resource-deployment/src/services/tools/dockerTool.ts index d9000920aa..4406fe5780 100644 --- a/extensions/resource-deployment/src/services/tools/dockerTool.ts +++ b/extensions/resource-deployment/src/services/tools/dockerTool.ts @@ -3,11 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolType, ITool, ToolInstallationStatus } from '../../interfaces'; +import { ToolType, ITool } from '../../interfaces'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); - export class DockerTool implements ITool { get name(): string { return 'docker'; @@ -24,21 +23,4 @@ export class DockerTool implements ITool { get displayName(): string { return localize('resourceDeployment.DockerDisplayName', 'Docker'); } - - get supportAutoInstall(): boolean { - return true; - } - - install(version: string): Thenable { - throw new Error('Method not implemented.'); - } - - getInstallationStatus(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(ToolInstallationStatus.Installed); - }, 500); - }); - return promise; - } } \ No newline at end of file diff --git a/extensions/resource-deployment/src/services/tools/kubectlTool.ts b/extensions/resource-deployment/src/services/tools/kubectlTool.ts index 35b333f45c..d4aa9f3627 100644 --- a/extensions/resource-deployment/src/services/tools/kubectlTool.ts +++ b/extensions/resource-deployment/src/services/tools/kubectlTool.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolType, ITool, ToolInstallationStatus } from '../../interfaces'; +import { ToolType, ITool } from '../../interfaces'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); @@ -13,7 +13,7 @@ export class KubeCtlTool implements ITool { } get description(): string { - return localize('resourceDeployment.KUBECTLDescription', 'Tool used for managing the Kubernetes cluster'); + return localize('resourceDeployment.KubeCtlDescription', 'Tool used for managing the Kubernetes cluster'); } get type(): ToolType { @@ -21,23 +21,6 @@ export class KubeCtlTool implements ITool { } get displayName(): string { - return localize('resourceDeployment.KUBECTLDisplayName', 'kubectl'); - } - - get supportAutoInstall(): boolean { - return true; - } - - install(version: string): Thenable { - throw new Error('Method not implemented.'); - } - - getInstallationStatus(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(ToolInstallationStatus.Installed); - }, 500); - }); - return promise; + return localize('resourceDeployment.KubeCtlDisplayName', 'kubectl'); } } \ No newline at end of file diff --git a/extensions/resource-deployment/src/services/tools/mssqlctlTool.ts b/extensions/resource-deployment/src/services/tools/mssqlctlTool.ts index 6fb45289cf..70d5728941 100644 --- a/extensions/resource-deployment/src/services/tools/mssqlctlTool.ts +++ b/extensions/resource-deployment/src/services/tools/mssqlctlTool.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolType, ITool, ToolInstallationStatus } from '../../interfaces'; +import { ToolType, ITool } from '../../interfaces'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); @@ -13,7 +13,7 @@ export class MSSQLCtlTool implements ITool { } get description(): string { - return localize('resourceDeployment.MSSQLCTLDescription', 'Command-line tool for installing and managing the SQL Server big data cluster'); + return localize('resourceDeployment.MssqlCtlDescription', 'Command-line tool for installing and managing the SQL Server big data cluster'); } get type(): ToolType { @@ -21,32 +21,6 @@ export class MSSQLCtlTool implements ITool { } get displayName(): string { - return localize('resourceDeployment.MSSQLCTLDisplayName', 'mssqlctl'); - } - - isInstalled(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(true); - }, 500); - }); - return promise; - } - - get supportAutoInstall(): boolean { - return true; - } - - install(version: string): Thenable { - throw new Error('Method not implemented.'); - } - - getInstallationStatus(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(ToolInstallationStatus.Installed); - }, 500); - }); - return promise; + return localize('resourceDeployment.MssqlCtlDisplayName', 'mssqlctl'); } } \ No newline at end of file diff --git a/extensions/resource-deployment/src/services/tools/pythonTool.ts b/extensions/resource-deployment/src/services/tools/pythonTool.ts index 4ff698f839..08de51d0f3 100644 --- a/extensions/resource-deployment/src/services/tools/pythonTool.ts +++ b/extensions/resource-deployment/src/services/tools/pythonTool.ts @@ -3,11 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolType, ITool, ToolInstallationStatus } from '../../interfaces'; +import { ToolType, ITool } from '../../interfaces'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); - export class PythonTool implements ITool { get name(): string { return 'python'; @@ -24,21 +23,4 @@ export class PythonTool implements ITool { get displayName(): string { return localize('resourceDeployment.PythonDisplayName', 'Python'); } - - get supportAutoInstall(): boolean { - return true; - } - - install(version: string): Thenable { - throw new Error('Method not implemented.'); - } - - getInstallationStatus(versionExpression: string): Thenable { - let promise = new Promise(resolve => { - setTimeout(() => { - resolve(ToolInstallationStatus.Installed); - }, 500); - }); - return promise; - } } \ No newline at end of file diff --git a/extensions/resource-deployment/src/services/toolsService.ts b/extensions/resource-deployment/src/services/toolsService.ts index c440893154..507e634cd4 100644 --- a/extensions/resource-deployment/src/services/toolsService.ts +++ b/extensions/resource-deployment/src/services/toolsService.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ToolRequirementInfo, ToolStatusInfo, ITool } from '../interfaces'; +import { ITool } from '../interfaces'; import { PythonTool } from './tools/pythonTool'; import { DockerTool } from './tools/dockerTool'; import { AzCliTool } from './tools/azCliTool'; @@ -11,42 +11,17 @@ import { MSSQLCtlTool } from './tools/mssqlCtlTool'; import { KubeCtlTool } from './tools/kubeCtlTool'; export interface IToolsService { - getToolStatus(toolRequirements: ToolRequirementInfo[]): Thenable; getToolByName(toolName: string): ITool | undefined; } export class ToolsService implements IToolsService { - private static readonly SupportedTools: ITool[] = [new PythonTool(), new DockerTool(), new AzCliTool(), new MSSQLCtlTool(), new KubeCtlTool()]; - - getToolStatus(toolRequirements: ToolRequirementInfo[]): Thenable { - const toolStatusList: ToolStatusInfo[] = []; - let promises = []; - for (let i = 0; i < toolRequirements.length; i++) { - const toolRequirement = toolRequirements[i]; - const tool = this.getToolByName(toolRequirement.name); - if (tool !== undefined) { - promises.push(tool.getInstallationStatus(toolRequirement.version).then(installStatus => { - toolStatusList.push({ - name: tool.displayName, - description: tool.description, - status: installStatus, - version: toolRequirement.version - }); - })); - } - } - return Promise.all(promises).then(() => { return toolStatusList; }); + constructor() { + this.SupportedTools = [new PythonTool(), new DockerTool(), new AzCliTool(), new MSSQLCtlTool(), new KubeCtlTool()]; } + private SupportedTools: ITool[]; + getToolByName(toolName: string): ITool | undefined { - if (toolName) { - for (let i = 0; i < ToolsService.SupportedTools.length; i++) { - if (toolName === ToolsService.SupportedTools[i].name) { - return ToolsService.SupportedTools[i]; - } - } - } - return undefined; + return this.SupportedTools.find(t => t.name === toolName); } - } \ No newline at end of file diff --git a/extensions/resource-deployment/src/ui/resourceDeploymentDialog.ts b/extensions/resource-deployment/src/ui/resourceDeploymentDialog.ts index 282ae9b040..02aff36a6c 100644 --- a/extensions/resource-deployment/src/ui/resourceDeploymentDialog.ts +++ b/extensions/resource-deployment/src/ui/resourceDeploymentDialog.ts @@ -8,7 +8,7 @@ import * as azdata from 'azdata'; import * as nls from 'vscode-nls'; import { IResourceTypeService } from '../services/resourceTypeService'; import * as vscode from 'vscode'; -import { ResourceType, DeploymentProvider, ToolInstallationStatus } from '../interfaces'; +import { ResourceType, DeploymentProvider } from '../interfaces'; import { IToolsService } from '../services/toolsService'; import { INotebookService } from '../services/notebookService'; @@ -41,6 +41,7 @@ export class ResourceDeploymentDialog { private initializeDialog() { let tab = azdata.window.createTab(''); tab.registerContent((view: azdata.ModelView) => { + const tableWidth = 1126; this._view = view; this.resourceTypeService.getResourceTypes().forEach(resourceType => this.addCard(resourceType)); const cardsContainer = view.modelBuilder.flexContainer().withItems(this._resourceTypeCards, { flex: '0 0 auto', CSSStyles: { 'margin-bottom': '10px' } }).withLayout({ flexFlow: 'row', alignItems: 'left' }).component(); @@ -49,28 +50,22 @@ export class ResourceDeploymentDialog { const toolColumn: azdata.TableColumn = { value: localize('deploymentDialog.toolNameColumnHeader', 'Tool'), - width: 100 + width: 150 }; const descriptionColumn: azdata.TableColumn = { value: localize('deploymentDialog.toolDescriptionColumnHeader', 'Description'), - width: 500 - }; - const versionColumn: azdata.TableColumn = { - value: localize('deploymentDialog.toolVersionColumnHeader', 'Version'), - width: 200 - }; - const statusColumn: azdata.TableColumn = { - value: localize('deploymentDialog.toolStatusColumnHeader', 'Status'), - width: 200 + width: 850 }; this._toolsTable = view.modelBuilder.table().withProperties({ - height: 150, data: [], - columns: [toolColumn, descriptionColumn, versionColumn, statusColumn], - width: 1000 + columns: [toolColumn, descriptionColumn], + width: tableWidth }).component(); + const toolsTableWrapper = view.modelBuilder.divContainer().withLayout({ width: tableWidth }).component(); + toolsTableWrapper.addItem(this._toolsTable, { CSSStyles: { 'border-left': '1px solid silver', 'border-top': '1px solid silver' } }); + const formBuilder = view.modelBuilder.formContainer().withFormItems( [ { @@ -83,7 +78,7 @@ export class ResourceDeploymentDialog { component: this._optionsContainer, title: localize('deploymentDialog.OptionsTitle', 'Options') }, { - component: this._toolsTable, + component: toolsTableWrapper, title: localize('deploymentDialog.RequiredToolsTitle', 'Required tools') } ], @@ -165,27 +160,18 @@ export class ResourceDeploymentDialog { } private updateTools(): void { - this.toolsService.getToolStatus(this.getCurrentProvider().requiredTools).then(toolStatus => { - let tableData = toolStatus.map(tool => { - return [tool.name, tool.description, tool.version, this.getToolStatusText(tool.status)]; + // do a 10 ms delay to workaround the issue of first time load: + // during initialization this update to table will be processed prior to the table initialization update + // as a result the data will be overwritten, introduce a short delay so that the order of updates can be maintained. + setTimeout(() => { + const tools = this.getCurrentProvider().requiredTools; + const headerRowHeight = 28; + this._toolsTable.height = 25 * tools.length + headerRowHeight; + this._toolsTable.data = tools.map(toolRef => { + const tool = this.toolsService.getToolByName(toolRef.name)!; + return [tool.displayName, tool.description]; }); - this._toolsTable.data = tableData; - }); - } - - private getToolStatusText(status: ToolInstallationStatus): string { - switch (status) { - case ToolInstallationStatus.Installed: - return '✔️ ' + localize('deploymentDialog.InstalledText', 'Installed'); - case ToolInstallationStatus.NotInstalled: - return '❌ ' + localize('deploymentDialog.NotInstalledText', 'Not Installed'); - case ToolInstallationStatus.Installing: - return '⌛ ' + localize('deploymentDialog.InstallingText', 'Installing…'); - case ToolInstallationStatus.FailedToInstall: - return '❌ ' + localize('deploymentDialog.FailedToInstallText', 'Install Failed'); - default: - return 'unknown status'; - } + }, 10); } private getCurrentProvider(): DeploymentProvider {