diff --git a/extensions/resource-deployment/src/services/tools/azdataTool.ts b/extensions/resource-deployment/src/services/tools/azdataTool.ts index fb807ac26f..5fa65b0048 100644 --- a/extensions/resource-deployment/src/services/tools/azdataTool.ts +++ b/extensions/resource-deployment/src/services/tools/azdataTool.ts @@ -8,11 +8,10 @@ import * as path from 'path'; import { SemVer } from 'semver'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; -import { AzdataInstallLocationKey, DeploymentConfigurationKey } from '../../constants'; import { Command, OsDistribution, ToolStatus, ToolType } from '../../interfaces'; import * as loc from '../../localizedConstants'; import { IPlatformService } from '../platformService'; -import { dependencyType, ToolBase } from './toolBase'; +import { ToolBase } from './toolBase'; const localize = nls.loadMessageBundle(); export const AzdataToolName = 'azdata'; @@ -47,6 +46,9 @@ export class AzdataTool extends ToolBase { } public isEulaAccepted(): boolean { + if (!this.azdataApi) { + return false; + } if (this.azdataApi.isEulaAccepted()) { return true; } else { @@ -82,6 +84,11 @@ export class AzdataTool extends ToolBase { */ protected async updateVersionAndStatus(): Promise { this.azdataApi = await vscode.extensions.getExtension(azdataExt.extension.name)?.activate(); + if (!this.azdataApi) { + this.setInstallationPathOrAdditionalInformation(localize('deploy.azdataExtMissing', "The Azure Data CLI extension must be installed to deploy this resource. Please install it through the extension gallery and try again.")); + this.setStatus(ToolStatus.NotInstalled); + return; + } this.setStatusDescription(''); await this.addInstallationSearchPathsToSystemPath(); @@ -125,101 +132,6 @@ export class AzdataTool extends ToolBase { } protected get allInstallationCommands(): Map { - return new Map([ - [OsDistribution.debian, this.debianInstallationCommands], - [OsDistribution.win32, this.win32InstallationCommands], - [OsDistribution.darwin, this.macOsInstallationCommands], - [OsDistribution.others, []] - ]); - } - - - private get azdataInstallLocation(): string { - return vscode.workspace.getConfiguration(DeploymentConfigurationKey)[AzdataInstallLocationKey] || this.defaultInstallLocationByDistribution.get(this.osDistribution); - } - - private defaultInstallLocationByDistribution: Map = new Map([ - [OsDistribution.debian, 'https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2019.list'], - [OsDistribution.win32, 'https://aka.ms/azdata-msi'], - [OsDistribution.darwin, 'microsoft/azdata-cli-release'], - [OsDistribution.others, ''] - ]); - - protected dependenciesByOsType: Map = new Map([ - [OsDistribution.debian, []], - [OsDistribution.win32, []], - [OsDistribution.darwin, [dependencyType.Brew]], - [OsDistribution.others, []] - ]); - - private get win32InstallationCommands() { - return [ - { - comment: localize('resourceDeployment.Azdata.DeletingPreviousAzdata.msi', "deleting previously downloaded Azdata.msi if one exists …"), - command: `IF EXIST .\\Azdata.msi DEL /F .\\Azdata.msi` - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.DownloadingAndInstallingAzdata', "downloading Azdata.msi and installing azdata-cli …"), - command: `powershell -NoLogo -NonInteractive -NoProfile -Command "& {try {(New-Object System.Net.WebClient).DownloadFile('${this.azdataInstallLocation}', 'Azdata.msi'); Start-Process msiexec.exe -Wait -ArgumentList '/I Azdata.msi /passive /quiet /lvx ADS_AzdataInstall.log'} catch { Write-Error $_.Exception; exit 1 }}"` - }, - { - comment: localize('resourceDeployment.Azdata.DisplayingInstallationLog', "displaying the installation log …"), - command: `type ADS_AzdataInstall.log | findstr /i /v ^MSI"`, - ignoreError: true - } - ]; - } - - private get macOsInstallationCommands() { - return [ - { - comment: localize('resourceDeployment.Azdata.TappingBrewRepository', "tapping into the brew repository for azdata-cli …"), - command: `brew tap ${this.azdataInstallLocation}` - }, - { - comment: localize('resourceDeployment.Azdata.UpdatingBrewRepository', "updating the brew repository for azdata-cli installation …"), - command: 'brew update' - }, - { - comment: localize('resourceDeployment.Azdata.InstallingAzdata', "installing azdata …"), - command: 'brew install azdata-cli' - } - ]; - } - - private get debianInstallationCommands() { - return [ - { - sudo: true, - comment: localize('resourceDeployment.Azdata.AptGetUpdate', "updating repository information …"), - command: 'apt-get update' - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.AptGetPackages', "getting packages needed for azdata installation …"), - command: 'apt-get install gnupg ca-certificates curl apt-transport-https lsb-release -y' - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.DownloadAndInstallingSigningKey', "downloading and installing the signing key for azdata …"), - command: 'wget -qO- https://packages.microsoft.com/keys/microsoft.asc | apt-key add -' - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.AddingAzdataRepositoryInformation', "adding the azdata repository information …"), - command: `add-apt-repository "$(wget -qO- ${this.azdataInstallLocation})"` - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.AptGetUpdate', "updating repository information …"), - command: 'apt-get update' - }, - { - sudo: true, - comment: localize('resourceDeployment.Azdata.InstallingAzdata', "installing azdata …"), - command: 'apt-get install -y azdata-cli' - } - ]; + return new Map(); } } diff --git a/extensions/resource-deployment/src/ui/toolsAndEulaSettingsPage.ts b/extensions/resource-deployment/src/ui/toolsAndEulaSettingsPage.ts index 4ac1de8249..8383b88fc7 100644 --- a/extensions/resource-deployment/src/ui/toolsAndEulaSettingsPage.ts +++ b/extensions/resource-deployment/src/ui/toolsAndEulaSettingsPage.ts @@ -48,14 +48,6 @@ export class ToolsAndEulaPage extends ResourceTypePage { public async onEnter(): Promise { this.wizard.wizardObject.generateScriptButton.hidden = true; this.wizard.wizardObject.registerNavigationValidator(async (pcInfo) => { - if (!this._eulaValidationSucceeded && !(await this.acquireEulaAndProceed())) { - this.wizard.wizardObject.message = { - text: localize('deploymentDialog.FailedEulaValidation', "To proceed, you must accept the terms of the End User License Agreement(EULA)"), - level: azdata.window.MessageLevel.Error - }; - return false; // we return false so that the workflow does not proceed and user gets to either click acceptEulaAndSelect again or cancel - } - for (let i = 0; i < this._tools.length; i++) { switch (this._tools[i].status) { case ToolStatus.Installing: @@ -75,6 +67,14 @@ export class ToolsAndEulaPage extends ResourceTypePage { } } + if (!this._eulaValidationSucceeded && !(await this.acquireEulaAndProceed())) { + this.wizard.wizardObject.message = { + text: localize('deploymentDialog.FailedEulaValidation', "To proceed, you must accept the terms of the End User License Agreement(EULA)"), + level: azdata.window.MessageLevel.Error + }; + return false; // we return false so that the workflow does not proceed and user gets to either click acceptEulaAndSelect again or cancel + } + this.wizard.wizardObject.message = { text: '' }; @@ -338,7 +338,7 @@ export class ToolsAndEulaPage extends ResourceTypePage { this._installationInProgress = true; let tool: ITool; try { - this.enableDoneButton(false); + this.setDoneAndNextButtonEnabledState(false); const toolRequirements = this.toolRequirements; let toolsNotInstalled: ITool[] = []; for (let i: number = 0; i < toolRequirements.length; i++) { @@ -370,7 +370,7 @@ export class ToolsAndEulaPage extends ResourceTypePage { level: azdata.window.MessageLevel.Information, text: localize('deploymentDialog.InstalledTools', "All required tools are installed now.") }; - this.enableDoneButton(true); + this.setDoneAndNextButtonEnabledState(true); } else { this.wizard.wizardObject.message = { level: azdata.window.MessageLevel.Information, @@ -475,7 +475,7 @@ export class ToolsAndEulaPage extends ResourceTypePage { 'display': erroredOrFailedTool || minVersionCheckFailed || (toolsToAutoInstall.length === 0) ? 'none' : 'inline' } }); - this.enableDoneButton(!erroredOrFailedTool && messages.length === 0 && !minVersionCheckFailed && (toolsToAutoInstall.length === 0)); + this.setDoneAndNextButtonEnabledState(!erroredOrFailedTool && messages.length === 0 && !minVersionCheckFailed && (toolsToAutoInstall.length === 0)); if (messages.length !== 0) { if (messages.length > 1) { messages = messages.map(message => `• ${message}`); @@ -506,8 +506,7 @@ export class ToolsAndEulaPage extends ResourceTypePage { level: azdata.window.MessageLevel.Warning, text: infoText.join(EOL) }; - } - if (!this.areToolsEulaAccepted()) { + } else if (!this.areToolsEulaAccepted()) { this.wizard.wizardObject.doneButton.label = loc.acceptEulaAndSelect; this.wizard.wizardObject.nextButton.label = loc.acceptEulaAndSelect; } @@ -531,13 +530,13 @@ export class ToolsAndEulaPage extends ResourceTypePage { }); if (this.toolRequirements.length === 0) { this._toolsLoadingComponent.loading = false; - this.enableDoneButton(true); + this.setDoneAndNextButtonEnabledState(true); this._toolsTable.data = [[localize('deploymentDialog.NoRequiredTool', "No tools required"), '']]; this._tools = []; } else { this._tools = this.toolRequirements.map(toolReq => this.toolsService.getToolByName(toolReq.name)!); this._toolsLoadingComponent.loading = true; - this.enableDoneButton(false); + this.setDoneAndNextButtonEnabledState(false); let toolsLoadingErrors: string[] = []; Promise.all( this._tools.map( @@ -549,8 +548,8 @@ export class ToolsAndEulaPage extends ResourceTypePage { } } - private enableDoneButton(enable: boolean) { - this.wizard.wizardObject.doneButton.enabled = enable; - this.wizard.wizardObject.nextButton.enabled = enable; + private setDoneAndNextButtonEnabledState(enabled: boolean) { + this.wizard.wizardObject.doneButton.enabled = enabled; + this.wizard.wizardObject.nextButton.enabled = enabled; } }