mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Alanren/sql on windows (#6785)
* download file * add entry * fix issues * add 2019 * string updates * make dialog self contained * expose notebook input dialog * refactoring * add log and correct the url * comments
This commit is contained in:
@@ -40,12 +40,17 @@
|
|||||||
"command": "azdata.resource.deploy",
|
"command": "azdata.resource.deploy",
|
||||||
"title": "%deploy-resource-command-name%",
|
"title": "%deploy-resource-command-name%",
|
||||||
"category": "%deploy-resource-command-category%"
|
"category": "%deploy-resource-command-category%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "azdata.openNotebookInputDialog",
|
||||||
|
"title": "Open notebook input dialog",
|
||||||
|
"category": "Notebook"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
"commandPalette": [
|
"commandPalette": [
|
||||||
{
|
{
|
||||||
"command": "azdata.resource.deploy",
|
"command": "azdata.openNotebookInputDialog",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -57,6 +62,10 @@
|
|||||||
{
|
{
|
||||||
"command": "azdata.resource.sql-bdc.deploy",
|
"command": "azdata.resource.sql-bdc.deploy",
|
||||||
"group": "secondary"
|
"group": "secondary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "azdata.resource.deploy",
|
||||||
|
"group": "secondary"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -94,6 +103,7 @@
|
|||||||
"providers": [
|
"providers": [
|
||||||
{
|
{
|
||||||
"dialog": {
|
"dialog": {
|
||||||
|
"notebook": "%sql-2017-docker-notebook%",
|
||||||
"title": "%docker-sql-2017-title%",
|
"title": "%docker-sql-2017-title%",
|
||||||
"name": "docker-sql-2017-dialog",
|
"name": "docker-sql-2017-dialog",
|
||||||
"tabs": [
|
"tabs": [
|
||||||
@@ -135,7 +145,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notebook": "%sql-2017-docker-notebook%",
|
|
||||||
"requiredTools": [
|
"requiredTools": [
|
||||||
{
|
{
|
||||||
"name": "docker"
|
"name": "docker"
|
||||||
@@ -145,6 +154,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"dialog": {
|
"dialog": {
|
||||||
|
"notebook": "%sql-2019-docker-notebook%",
|
||||||
"title": "%docker-sql-2019-title%",
|
"title": "%docker-sql-2019-title%",
|
||||||
"name": "docker-sql-2019-dialog",
|
"name": "docker-sql-2019-dialog",
|
||||||
"tabs": [
|
"tabs": [
|
||||||
@@ -186,7 +196,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notebook": "%sql-2019-docker-notebook%",
|
|
||||||
"requiredTools": [
|
"requiredTools": [
|
||||||
{
|
{
|
||||||
"name": "docker"
|
"name": "docker"
|
||||||
@@ -242,6 +251,7 @@
|
|||||||
"providers": [
|
"providers": [
|
||||||
{
|
{
|
||||||
"dialog": {
|
"dialog": {
|
||||||
|
"notebook": "%bdc-2019-aks-notebook%",
|
||||||
"title": "%bdc-new-aks-dialog-title%",
|
"title": "%bdc-new-aks-dialog-title%",
|
||||||
"name": "bdc-new-aks-dialog",
|
"name": "bdc-new-aks-dialog",
|
||||||
"tabs": [
|
"tabs": [
|
||||||
@@ -331,7 +341,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notebook": "%bdc-2019-aks-notebook%",
|
|
||||||
"requiredTools": [
|
"requiredTools": [
|
||||||
{
|
{
|
||||||
"name": "kubectl"
|
"name": "kubectl"
|
||||||
@@ -347,6 +356,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"dialog": {
|
"dialog": {
|
||||||
|
"notebook": "%bdc-2019-existing-aks-notebook%",
|
||||||
"title": "%bdc-existing-aks-dialog-title%",
|
"title": "%bdc-existing-aks-dialog-title%",
|
||||||
"name": "bdc-existing-aks-dialog",
|
"name": "bdc-existing-aks-dialog",
|
||||||
"tabs": [
|
"tabs": [
|
||||||
@@ -386,7 +396,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notebook": "%bdc-2019-existing-aks-notebook%",
|
|
||||||
"requiredTools": [
|
"requiredTools": [
|
||||||
{
|
{
|
||||||
"name": "kubectl"
|
"name": "kubectl"
|
||||||
@@ -401,6 +410,7 @@
|
|||||||
"dialog": {
|
"dialog": {
|
||||||
"title": "%bdc-existing-kubeadm-dialog-title%",
|
"title": "%bdc-existing-kubeadm-dialog-title%",
|
||||||
"name": "bdc-existing-kubeadm-dialog",
|
"name": "bdc-existing-kubeadm-dialog",
|
||||||
|
"notebook": "%bdc-2019-existing-kubeadm-notebook%",
|
||||||
"tabs": [
|
"tabs": [
|
||||||
{
|
{
|
||||||
"title": "",
|
"title": "",
|
||||||
@@ -461,7 +471,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notebook": "%bdc-2019-existing-kubeadm-notebook%",
|
|
||||||
"requiredTools": [
|
"requiredTools": [
|
||||||
{
|
{
|
||||||
"name": "kubectl"
|
"name": "kubectl"
|
||||||
@@ -473,6 +482,46 @@
|
|||||||
"when": "target=existing-kubeadm&&version=bdc2019"
|
"when": "target=existing-kubeadm&&version=bdc2019"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sql-windows-setup",
|
||||||
|
"displayName": "%resource-type-sql-windows-setup-display-name%",
|
||||||
|
"description": "%resource-type-sql-windows-setup-description%",
|
||||||
|
"platforms": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"icon": {
|
||||||
|
"light": "./images/sql_server.svg",
|
||||||
|
"dark": "./images/sql_server_inverse.svg"
|
||||||
|
},
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"displayName": "%version-display-name%",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"name": "sql2017",
|
||||||
|
"displayName": "%sql-2017-display-name%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sql2019",
|
||||||
|
"displayName": "%sql-2019-display-name%"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"downloadUrl": "https://go.microsoft.com/fwlink/?linkid=853016",
|
||||||
|
"requiredTools": [],
|
||||||
|
"when": "version=sql2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"webPageUrl": "https://www.microsoft.com/evalcenter/evaluate-sql-server-2019-ctp",
|
||||||
|
"requiredTools": [],
|
||||||
|
"when": "version=sql2019"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"extension-description": "Provides a notebook-based experience to deploy Microsoft SQL Server",
|
"extension-description": "Provides a notebook-based experience to deploy Microsoft SQL Server",
|
||||||
"deploy-sql-image-command-name": "Deploy SQL Server on Docker…",
|
"deploy-sql-image-command-name": "Deploy SQL Server on Docker…",
|
||||||
"deploy-sql-bdc-command-name": "Deploy SQL Server big data cluster…",
|
"deploy-sql-bdc-command-name": "Deploy SQL Server big data cluster…",
|
||||||
"deploy-resource-command-name": "Deploy SQL Server…",
|
"deploy-resource-command-name": "Open SQL Server deployment dialog",
|
||||||
"deploy-resource-command-category": "Deployment",
|
"deploy-resource-command-category": "Deployment",
|
||||||
"resource-type-sql-image-display-name": "SQL Server container image",
|
"resource-type-sql-image-display-name": "SQL Server container image",
|
||||||
"resource-type-sql-image-description": "Run SQL Server container image with Docker",
|
"resource-type-sql-image-description": "Run SQL Server container image with Docker",
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
"resource-type-sql-bdc-description": "SQL Server big data cluster allows you to deploy scalable clusters of SQL Server, Spark, and HDFS containers running on Kubernetes",
|
"resource-type-sql-bdc-description": "SQL Server big data cluster allows you to deploy scalable clusters of SQL Server, Spark, and HDFS containers running on Kubernetes",
|
||||||
"version-display-name": "Version",
|
"version-display-name": "Version",
|
||||||
"sql-2017-display-name": "SQL Server 2017",
|
"sql-2017-display-name": "SQL Server 2017",
|
||||||
"sql-2019-display-name": "SQL Server 2019 CTP 3.2",
|
"sql-2019-display-name": "SQL Server 2019 CTP",
|
||||||
"sql-2017-docker-notebook": "./notebooks/docker/2017/deploy-sql2017-image.ipynb",
|
"sql-2017-docker-notebook": "./notebooks/docker/2017/deploy-sql2017-image.ipynb",
|
||||||
"sql-2019-docker-notebook": "./notebooks/docker/2019/deploy-sql2019-image.ipynb",
|
"sql-2019-docker-notebook": "./notebooks/docker/2019/deploy-sql2019-image.ipynb",
|
||||||
"bdc-2019-display-name": "SQL Server 2019 CTP 3.2 big data cluster",
|
"bdc-2019-display-name": "SQL Server 2019 CTP big data cluster",
|
||||||
"bdc-deployment-target": "Deployment target",
|
"bdc-deployment-target": "Deployment target",
|
||||||
"bdc-deployment-target-aks": "New Azure Kubernetes Service Cluster",
|
"bdc-deployment-target-aks": "New Azure Kubernetes Service Cluster",
|
||||||
"bdc-deployment-target-existing-aks": "Existing Azure Kubernetes Service Cluster",
|
"bdc-deployment-target-existing-aks": "Existing Azure Kubernetes Service Cluster",
|
||||||
@@ -46,5 +46,7 @@
|
|||||||
"bdc-existing-kubeadm-dialog-title": "Deployment target: existing Kubernetes cluster (kubeadm)",
|
"bdc-existing-kubeadm-dialog-title": "Deployment target: existing Kubernetes cluster (kubeadm)",
|
||||||
"bdc-storage-class-field": "Storage class name",
|
"bdc-storage-class-field": "Storage class name",
|
||||||
"bdc-data-size-field": "Capacity for data (GB)",
|
"bdc-data-size-field": "Capacity for data (GB)",
|
||||||
"bdc-log-size-field": "Capacity for logs (GB)"
|
"bdc-log-size-field": "Capacity for logs (GB)",
|
||||||
|
"resource-type-sql-windows-setup-display-name": "SQL Server on Windows",
|
||||||
|
"resource-type-sql-windows-setup-description": "Run SQL Server on Windows, select a version to get started."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,14 @@ export interface DeploymentProvider {
|
|||||||
title: string;
|
title: string;
|
||||||
dialog: DialogInfo;
|
dialog: DialogInfo;
|
||||||
notebook: string | NotebookInfo;
|
notebook: string | NotebookInfo;
|
||||||
|
downloadUrl: string;
|
||||||
|
webPageUrl: string;
|
||||||
requiredTools: ToolRequirementInfo[];
|
requiredTools: ToolRequirementInfo[];
|
||||||
when: string;
|
when: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DialogInfo {
|
export interface DialogInfo {
|
||||||
|
notebook: string | NotebookInfo;
|
||||||
title: string;
|
title: string;
|
||||||
name: string;
|
name: string;
|
||||||
tabs: DialogTabInfo[];
|
tabs: DialogTabInfo[];
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import vscode = require('vscode');
|
import * as vscode from 'vscode';
|
||||||
import { ResourceTypePickerDialog } from './ui/resourceDeploymentDialog';
|
|
||||||
import { ToolsService } from './services/toolsService';
|
|
||||||
import { NotebookService } from './services/notebookService';
|
|
||||||
import { ResourceTypeService } from './services/resourceTypeService';
|
|
||||||
import { PlatformService } from './services/platformService';
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
|
import { DialogInfo } from './interfaces';
|
||||||
|
import { NotebookService } from './services/notebookService';
|
||||||
|
import { PlatformService } from './services/platformService';
|
||||||
|
import { ResourceTypeService } from './services/resourceTypeService';
|
||||||
|
import { ToolsService } from './services/toolsService';
|
||||||
|
import { NotebookInputDialog } from './ui/notebookInputDialog';
|
||||||
|
import { ResourceTypePickerDialog } from './ui/resourceTypePickerDialog';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
@@ -18,8 +20,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
const platformService = new PlatformService();
|
const platformService = new PlatformService();
|
||||||
const toolsService = new ToolsService();
|
const toolsService = new ToolsService();
|
||||||
const notebookService = new NotebookService(platformService, context.extensionPath);
|
const notebookService = new NotebookService(platformService, context.extensionPath);
|
||||||
const resourceTypeService = new ResourceTypeService(platformService, toolsService);
|
const resourceTypeService = new ResourceTypeService(platformService, toolsService, notebookService);
|
||||||
|
|
||||||
const resourceTypes = resourceTypeService.getResourceTypes();
|
const resourceTypes = resourceTypeService.getResourceTypes();
|
||||||
const validationFailures = resourceTypeService.validateResourceTypes(resourceTypes);
|
const validationFailures = resourceTypeService.validateResourceTypes(resourceTypes);
|
||||||
if (validationFailures.length !== 0) {
|
if (validationFailures.length !== 0) {
|
||||||
@@ -33,7 +34,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
if (filtered.length !== 1) {
|
if (filtered.length !== 1) {
|
||||||
vscode.window.showErrorMessage(localize('resourceDeployment.UnknownResourceType', 'The resource type: {0} is not defined', resourceTypeName));
|
vscode.window.showErrorMessage(localize('resourceDeployment.UnknownResourceType', 'The resource type: {0} is not defined', resourceTypeName));
|
||||||
} else {
|
} else {
|
||||||
const dialog = new ResourceTypePickerDialog(context, notebookService, toolsService, resourceTypeService, filtered[0]);
|
const dialog = new ResourceTypePickerDialog(context, toolsService, resourceTypeService, filtered[0]);
|
||||||
dialog.open();
|
dialog.open();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -47,6 +48,10 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
vscode.commands.registerCommand('azdata.resource.deploy', () => {
|
vscode.commands.registerCommand('azdata.resource.deploy', () => {
|
||||||
openDialog('sql-bdc');
|
openDialog('sql-bdc');
|
||||||
});
|
});
|
||||||
|
vscode.commands.registerCommand('azdata.openNotebookInputDialog', (dialogInfo: DialogInfo) => {
|
||||||
|
const dialog = new NotebookInputDialog(notebookService, dialogInfo);
|
||||||
|
dialog.open();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method is called when your extension is deactivated
|
// this method is called when your extension is deactivated
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { NotebookInfo } from '../interfaces';
|
|
||||||
import { isString } from 'util';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import { isString } from 'util';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { IPlatformService } from './platformService';
|
import { IPlatformService } from './platformService';
|
||||||
|
import { NotebookInfo } from '../interfaces';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
export interface INotebookService {
|
export interface INotebookService {
|
||||||
@@ -26,13 +26,16 @@ export class NotebookService implements INotebookService {
|
|||||||
* @param notebook the path of the notebook
|
* @param notebook the path of the notebook
|
||||||
*/
|
*/
|
||||||
launchNotebook(notebook: string | NotebookInfo): void {
|
launchNotebook(notebook: string | NotebookInfo): void {
|
||||||
const notebookRelativePath = this.getNotebook(notebook);
|
const notebookPath = this.getNotebook(notebook);
|
||||||
const notebookFullPath = path.join(this.extensionPath, notebookRelativePath);
|
const notebookFullPath = path.join(this.extensionPath, notebookPath);
|
||||||
if (notebookRelativePath && this.platformService.fileExists(notebookFullPath)) {
|
if (notebookPath && this.platformService.fileExists(notebookPath)) {
|
||||||
|
this.showNotebookAsUntitled(notebookPath);
|
||||||
|
}
|
||||||
|
else if (notebookPath && this.platformService.fileExists(notebookFullPath)) {
|
||||||
this.showNotebookAsUntitled(notebookFullPath);
|
this.showNotebookAsUntitled(notebookFullPath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.platformService.showErrorMessage(localize('resourceDeployment.notebookNotFound', 'The notebook {0} does not exist', notebookFullPath));
|
this.platformService.showErrorMessage(localize('resourceDeployment.notebookNotFound', "The notebook {0} does not exist", notebookPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,22 +4,31 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { ResourceType, ResourceTypeOption, DeploymentProvider } from '../interfaces';
|
import * as azdata from 'azdata';
|
||||||
import { IToolsService } from './toolsService';
|
import * as cp from 'child_process';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as https from 'https';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { IPlatformService } from './platformService';
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
|
import { INotebookService } from './notebookService';
|
||||||
|
import { IPlatformService } from './platformService';
|
||||||
|
import { IToolsService } from './toolsService';
|
||||||
|
import { ResourceType, ResourceTypeOption, DeploymentProvider } from '../interfaces';
|
||||||
|
import { NotebookInputDialog } from '../ui/notebookInputDialog';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
export interface IResourceTypeService {
|
export interface IResourceTypeService {
|
||||||
getResourceTypes(filterByPlatform?: boolean): ResourceType[];
|
getResourceTypes(filterByPlatform?: boolean): ResourceType[];
|
||||||
validateResourceTypes(resourceTypes: ResourceType[]): string[];
|
validateResourceTypes(resourceTypes: ResourceType[]): string[];
|
||||||
|
startDeployment(provider: DeploymentProvider): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResourceTypeService implements IResourceTypeService {
|
export class ResourceTypeService implements IResourceTypeService {
|
||||||
private _resourceTypes: ResourceType[] = [];
|
private _resourceTypes: ResourceType[] = [];
|
||||||
|
|
||||||
constructor(private platformService: IPlatformService, private toolsService: IToolsService) { }
|
constructor(private platformService: IPlatformService, private toolsService: IToolsService, private notebookService: INotebookService) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the supported resource types
|
* Get the supported resource types
|
||||||
@@ -129,8 +138,8 @@ export class ResourceTypeService implements IResourceTypeService {
|
|||||||
let providerIndex = 1;
|
let providerIndex = 1;
|
||||||
resourceType.providers.forEach(provider => {
|
resourceType.providers.forEach(provider => {
|
||||||
const providerPositionInfo = `${positionInfo}, provider index: ${providerIndex} `;
|
const providerPositionInfo = `${positionInfo}, provider index: ${providerIndex} `;
|
||||||
if (!provider.notebook) {
|
if (!provider.dialog && !provider.notebook && !provider.downloadUrl && !provider.webPageUrl) {
|
||||||
errorMessages.push(`Notebook is not specified for the provider, ${providerPositionInfo}`);
|
errorMessages.push(`No deployment method defined for the provider, ${providerPositionInfo}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (provider.requiredTools && provider.requiredTools.length > 0) {
|
if (provider.requiredTools && provider.requiredTools.length > 0) {
|
||||||
@@ -183,4 +192,79 @@ export class ResourceTypeService implements IResourceTypeService {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public startDeployment(provider: DeploymentProvider): void {
|
||||||
|
const self = this;
|
||||||
|
if (provider.dialog) {
|
||||||
|
const dialog = new NotebookInputDialog(this.notebookService, provider.dialog);
|
||||||
|
dialog.open();
|
||||||
|
} else if (provider.notebook) {
|
||||||
|
this.notebookService.launchNotebook(provider.notebook);
|
||||||
|
} else if (provider.downloadUrl) {
|
||||||
|
const taskName = localize('resourceDeployment.DownloadAndLaunchTaskName', "Download and launch installer, URL: {0}", provider.downloadUrl);
|
||||||
|
azdata.tasks.startBackgroundOperation({
|
||||||
|
displayName: taskName,
|
||||||
|
description: taskName,
|
||||||
|
isCancelable: false,
|
||||||
|
operation: op => {
|
||||||
|
op.updateStatus(azdata.TaskStatus.InProgress, localize('resourceDeployment.DownloadingText', "Downloading from: {0}", provider.downloadUrl));
|
||||||
|
self.download(provider.downloadUrl).then((downloadedFile) => {
|
||||||
|
op.updateStatus(azdata.TaskStatus.InProgress, localize('resourceDeployment.DownloadCompleteText', "Successfully downloaded: {0}", downloadedFile));
|
||||||
|
op.updateStatus(azdata.TaskStatus.InProgress, localize('resourceDeployment.LaunchingProgramText', "Launching: {0}", downloadedFile));
|
||||||
|
cp.exec(downloadedFile);
|
||||||
|
op.updateStatus(azdata.TaskStatus.Succeeded, localize('resourceDeployment.ProgramLaunchedText', "Successfully launched: {0}", downloadedFile));
|
||||||
|
}, (error) => {
|
||||||
|
op.updateStatus(azdata.TaskStatus.Failed, error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (provider.webPageUrl) {
|
||||||
|
vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(provider.webPageUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private download(url: string): Promise<string> {
|
||||||
|
const self = this;
|
||||||
|
const promise = new Promise<string>((resolve, reject) => {
|
||||||
|
https.get(url, function (response) {
|
||||||
|
console.log('Download installer from: ' + url);
|
||||||
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
||||||
|
// Redirect and download from new location
|
||||||
|
console.log('Redirecting the download to: ' + response.headers.location);
|
||||||
|
self.download(response.headers.location!).then((result) => {
|
||||||
|
resolve(result);
|
||||||
|
}, (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
reject(localize('downloadError', "Download failed, status code: {0}, message: {1}", response.statusCode, response.statusMessage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const extension = path.extname(url);
|
||||||
|
const originalFileName = path.basename(url, extension);
|
||||||
|
let fileName = originalFileName;
|
||||||
|
const downloadFolder = os.homedir();
|
||||||
|
let cnt = 1;
|
||||||
|
while (fs.existsSync(path.join(downloadFolder, fileName + extension))) {
|
||||||
|
fileName = `${originalFileName}-${cnt}`;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
fileName = path.join(downloadFolder, fileName + extension);
|
||||||
|
const file = fs.createWriteStream(fileName);
|
||||||
|
response.pipe(file);
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
resolve(fileName);
|
||||||
|
});
|
||||||
|
file.on('error', (err) => {
|
||||||
|
fs.unlink(fileName, () => { });
|
||||||
|
reject(err.message);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,15 @@ import { EOL } from 'os';
|
|||||||
import { ResourceTypeService } from '../services/resourceTypeService';
|
import { ResourceTypeService } from '../services/resourceTypeService';
|
||||||
import { IPlatformService } from '../services/platformService';
|
import { IPlatformService } from '../services/platformService';
|
||||||
import { ToolsService } from '../services/toolsService';
|
import { ToolsService } from '../services/toolsService';
|
||||||
|
import { NotebookService } from '../services/notebookService';
|
||||||
|
|
||||||
suite('Resource Type Service Tests', function (): void {
|
suite('Resource Type Service Tests', function (): void {
|
||||||
|
|
||||||
test('test resource types', () => {
|
test('test resource types', () => {
|
||||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||||
const toolsService = new ToolsService();
|
const toolsService = new ToolsService();
|
||||||
const resourceTypeService = new ResourceTypeService(mockPlatformService.object, toolsService);
|
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||||
|
const resourceTypeService = new ResourceTypeService(mockPlatformService.object, toolsService, notebookService);
|
||||||
// index 0: platform name, index 1: number of expected resource types
|
// index 0: platform name, index 1: number of expected resource types
|
||||||
const platforms: { platform: string; resourceTypeCount: number }[] = [
|
const platforms: { platform: string; resourceTypeCount: number }[] = [
|
||||||
{ platform: 'win32', resourceTypeCount: 2 },
|
{ platform: 'win32', resourceTypeCount: 2 },
|
||||||
@@ -39,4 +41,4 @@ suite('Resource Type Service Tests', function (): void {
|
|||||||
const validationErrors = resourceTypeService.validateResourceTypes(allResourceTypes);
|
const validationErrors = resourceTypeService.validateResourceTypes(allResourceTypes);
|
||||||
assert(validationErrors.length === 0, `Validation errors detected in the package.json: ${validationErrors.join(EOL)}.`);
|
assert(validationErrors.length === 0, `Validation errors detected in the package.json: ${validationErrors.join(EOL)}.`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export abstract class DialogBase {
|
|||||||
protected _toDispose: vscode.Disposable[] = [];
|
protected _toDispose: vscode.Disposable[] = [];
|
||||||
protected _dialogObject: azdata.window.Dialog;
|
protected _dialogObject: azdata.window.Dialog;
|
||||||
|
|
||||||
constructor(protected extensionContext: vscode.ExtensionContext, dialogTitle: string, dialogName: string, isWide: boolean = false) {
|
constructor(dialogTitle: string, dialogName: string, isWide: boolean = false) {
|
||||||
this._dialogObject = azdata.window.createModelViewDialog(dialogTitle, dialogName, isWide);
|
this._dialogObject = azdata.window.createModelViewDialog(dialogTitle, dialogName, isWide);
|
||||||
this._dialogObject.cancelButton.onClick(() => this.onCancel());
|
this._dialogObject.cancelButton.onClick(() => this.onCancel());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,29 +6,27 @@
|
|||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import * as vscode from 'vscode';
|
|
||||||
import { DialogBase } from './dialogBase';
|
import { DialogBase } from './dialogBase';
|
||||||
import { INotebookService } from '../services/notebookService';
|
import { INotebookService } from '../services/notebookService';
|
||||||
import { DeploymentProvider, DialogFieldInfo, FieldType } from '../interfaces';
|
import { DialogFieldInfo, FieldType, DialogInfo } from '../interfaces';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
export class DeploymentDialog extends DialogBase {
|
export class NotebookInputDialog extends DialogBase {
|
||||||
|
|
||||||
private variables: { [s: string]: string | undefined; } = {};
|
private variables: { [s: string]: string | undefined; } = {};
|
||||||
private validators: (() => { valid: boolean, message: string })[] = [];
|
private validators: (() => { valid: boolean, message: string })[] = [];
|
||||||
|
|
||||||
constructor(context: vscode.ExtensionContext,
|
constructor(private notebookService: INotebookService,
|
||||||
private notebookService: INotebookService,
|
private dialogInfo: DialogInfo) {
|
||||||
private deploymentProvider: DeploymentProvider) {
|
super(dialogInfo.title, dialogInfo.name, false);
|
||||||
super(context, deploymentProvider.dialog.title, deploymentProvider.dialog.name, false);
|
|
||||||
this._dialogObject.okButton.label = localize('deploymentDialog.OKButtonText', 'Open Notebook');
|
this._dialogObject.okButton.label = localize('deploymentDialog.OKButtonText', 'Open Notebook');
|
||||||
this._dialogObject.okButton.onClick(() => this.onComplete());
|
this._dialogObject.okButton.onClick(() => this.onComplete());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected initializeDialog() {
|
protected initializeDialog() {
|
||||||
const tabs: azdata.window.DialogTab[] = [];
|
const tabs: azdata.window.DialogTab[] = [];
|
||||||
this.deploymentProvider.dialog.tabs.forEach(tabInfo => {
|
this.dialogInfo.tabs.forEach(tabInfo => {
|
||||||
const tab = azdata.window.createTab(tabInfo.title);
|
const tab = azdata.window.createTab(tabInfo.title);
|
||||||
tab.registerContent((view: azdata.ModelView) => {
|
tab.registerContent((view: azdata.ModelView) => {
|
||||||
const sections: azdata.FormComponentGroup[] = [];
|
const sections: azdata.FormComponentGroup[] = [];
|
||||||
@@ -191,7 +189,7 @@ export class DeploymentDialog extends DialogBase {
|
|||||||
Object.keys(this.variables).forEach(key => {
|
Object.keys(this.variables).forEach(key => {
|
||||||
process.env[key] = this.variables[key];
|
process.env[key] = this.variables[key];
|
||||||
});
|
});
|
||||||
this.notebookService.launchNotebook(this.deploymentProvider.notebook);
|
this.notebookService.launchNotebook(this.dialogInfo.notebook);
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5,14 +5,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as nls from 'vscode-nls';
|
|
||||||
import { IResourceTypeService } from '../services/resourceTypeService';
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { ResourceType, DeploymentProvider } from '../interfaces';
|
import * as nls from 'vscode-nls';
|
||||||
import { IToolsService } from '../services/toolsService';
|
|
||||||
import { INotebookService } from '../services/notebookService';
|
|
||||||
import { DialogBase } from './dialogBase';
|
import { DialogBase } from './dialogBase';
|
||||||
import { DeploymentDialog } from './deploymentDialog';
|
import { ResourceType, DeploymentProvider } from '../interfaces';
|
||||||
|
import { IResourceTypeService } from '../services/resourceTypeService';
|
||||||
|
import { IToolsService } from '../services/toolsService';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
@@ -26,12 +24,11 @@ export class ResourceTypePickerDialog extends DialogBase {
|
|||||||
private _cardResourceTypeMap: Map<string, azdata.CardComponent> = new Map();
|
private _cardResourceTypeMap: Map<string, azdata.CardComponent> = new Map();
|
||||||
private _optionDropDownMap: Map<string, azdata.DropDownComponent> = new Map();
|
private _optionDropDownMap: Map<string, azdata.DropDownComponent> = new Map();
|
||||||
|
|
||||||
constructor(context: vscode.ExtensionContext,
|
constructor(private extensionContext: vscode.ExtensionContext,
|
||||||
private notebookService: INotebookService,
|
|
||||||
private toolsService: IToolsService,
|
private toolsService: IToolsService,
|
||||||
private resourceTypeService: IResourceTypeService,
|
private resourceTypeService: IResourceTypeService,
|
||||||
resourceType: ResourceType) {
|
resourceType: ResourceType) {
|
||||||
super(context, localize('resourceTypePickerDialog.title', "Select the deployment options"), 'ResourceTypePickerDialog', true);
|
super(localize('resourceTypePickerDialog.title', "Select the deployment options"), 'ResourceTypePickerDialog', true);
|
||||||
this._selectedResourceType = resourceType;
|
this._selectedResourceType = resourceType;
|
||||||
this._dialogObject.okButton.label = localize('deploymentDialog.OKButtonText', 'Select');
|
this._dialogObject.okButton.label = localize('deploymentDialog.OKButtonText', 'Select');
|
||||||
this._dialogObject.okButton.onClick(() => this.onComplete());
|
this._dialogObject.okButton.onClick(() => this.onComplete());
|
||||||
@@ -156,11 +153,15 @@ export class ResourceTypePickerDialog extends DialogBase {
|
|||||||
private updateTools(): void {
|
private updateTools(): void {
|
||||||
const tools = this.getCurrentProvider().requiredTools;
|
const tools = this.getCurrentProvider().requiredTools;
|
||||||
const headerRowHeight = 28;
|
const headerRowHeight = 28;
|
||||||
this._toolsTable.height = 25 * tools.length + headerRowHeight;
|
this._toolsTable.height = 25 * Math.max(tools.length, 1) + headerRowHeight;
|
||||||
this._toolsTable.data = tools.map(toolRef => {
|
if (tools.length === 0) {
|
||||||
const tool = this.toolsService.getToolByName(toolRef.name)!;
|
this._toolsTable.data = [[localize('deploymentDialog.NoRequiredTool', "No tools required"), '']];
|
||||||
return [tool.displayName, tool.description];
|
} else {
|
||||||
});
|
this._toolsTable.data = tools.map(toolRef => {
|
||||||
|
const tool = this.toolsService.getToolByName(toolRef.name)!;
|
||||||
|
return [tool.displayName, tool.description];
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCurrentProvider(): DeploymentProvider {
|
private getCurrentProvider(): DeploymentProvider {
|
||||||
@@ -175,13 +176,7 @@ export class ResourceTypePickerDialog extends DialogBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onComplete(): void {
|
private onComplete(): void {
|
||||||
const provider = this.getCurrentProvider();
|
this.resourceTypeService.startDeployment(this.getCurrentProvider());
|
||||||
if (provider.dialog) {
|
|
||||||
const dialog = new DeploymentDialog(this.extensionContext, this.notebookService, provider);
|
|
||||||
dialog.open();
|
|
||||||
} else {
|
|
||||||
this.notebookService.launchNotebook(provider.notebook);
|
|
||||||
}
|
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user