/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import * as constants from '../common/constants'; import * as utils from '../common/utils'; import * as uiUtils from './utils'; import { ISqlProject } from 'sqldbproj'; import { getPublishDatabaseSettings } from './publishDatabaseQuickpick'; import { DockerImageInfo } from '../models/deploy/deployProfile'; import { IDockerSettings, IPublishToDockerSettings } from '../models/deploy/publishSettings'; /** * Gets the settings for publishing a database to docker container using only VS Code-native APIs such as QuickPick */ export async function getPublishToDockerSettings(project: ISqlProject): Promise { const target = project.getProjectTargetVersion(); const name = uiUtils.getPublishServerName(target); // Deploy to docker selected let portNumber = await vscode.window.showInputBox({ title: constants.enterPortNumber(name), ignoreFocusOut: true, value: constants.defaultPortNumber, validateInput: input => !utils.validateSqlServerPortNumber(input) ? constants.portMustBeNumber : undefined } ); // Return when user hits escape if (!portNumber) { return undefined; } let password: string | undefined = ''; password = await vscode.window.showInputBox({ title: constants.enterPassword(name), ignoreFocusOut: true, value: password, validateInput: input => !utils.isValidSQLPassword(input) ? constants.invalidSQLPasswordMessage(name) : undefined, password: true } ); // Return when user hits escape if (!password) { return undefined; } let confirmPassword: string | undefined = ''; confirmPassword = await vscode.window.showInputBox({ title: constants.confirmPassword(name), ignoreFocusOut: true, value: confirmPassword, validateInput: input => input !== password ? constants.passwordNotMatch(name) : undefined, password: true } ); // Return when user hits escape if (!confirmPassword) { return undefined; } const baseImages = uiUtils.getDockerBaseImages(target); const baseImage = await vscode.window.showQuickPick( baseImages.map(x => x.displayName), { title: constants.selectBaseImage(name), ignoreFocusOut: true, placeHolder: uiUtils.getDockerImagePlaceHolder(target) }); // Return when user hits escape if (!baseImage) { return undefined; } const imageInfo = baseImages.find(x => x.displayName === baseImage); if (!imageInfo) { return undefined; } const eulaAccepted = await launchEulaQuickPick(imageInfo); if (!eulaAccepted) { return undefined; } let imageTags = await uiUtils.getImageTags(imageInfo, target); let imageTagsItems: vscode.QuickPickItem[] = imageTags.map(tag => { return { label: tag }; }); if (imageInfo.defaultTag) { // move the default to be the first one in the list const defaultIndex = imageTagsItems.findIndex(i => i.label === imageInfo.defaultTag); if (defaultIndex > -1) { imageTagsItems.splice(defaultIndex, 1); } // add default next to the default value imageTagsItems.unshift({ label: imageInfo.defaultTag, description: constants.defaultQuickPickItem }); } const imageTag = await vscode.window.showQuickPick( imageTagsItems, { title: constants.selectImageTag(name), ignoreFocusOut: true }); if (!imageTag) { return undefined; } // Add the image tag if it's not the latest let imageName = imageInfo.name; if (imageTag && imageTag.label !== constants.dockerImageDefaultTag) { imageName = `${imageName}:${imageTag.label}`; } const dockerSettings: IDockerSettings = { serverName: constants.defaultLocalServerName, userName: constants.defaultLocalServerAdminName, dbName: project.projectFileName, password: password, port: +portNumber, dockerBaseImage: imageName, dockerBaseImageEula: imageInfo.agreementInfo.link.url }; let deploySettings = await getPublishDatabaseSettings(project, false); // Return when user hits escape if (!deploySettings) { return undefined; } // Server name should be set to localhost deploySettings.serverName = dockerSettings.serverName; // Get the database name from deploy settings dockerSettings.dbName = deploySettings.databaseName; return { dockerSettings, sqlProjectPublishSettings: deploySettings, }; } async function launchEulaQuickPick(imageInfo: DockerImageInfo | undefined): Promise { let eulaAccepted: boolean = false; const agreementInfo = imageInfo?.agreementInfo; if (agreementInfo) { const openEulaButton: vscode.QuickInputButton = { iconPath: new vscode.ThemeIcon('link-external'), tooltip: constants.openEulaString }; const quickPick = vscode.window.createQuickPick(); quickPick.items = [{ label: constants.yesString }, { label: constants.noString }]; quickPick.title = uiUtils.getAgreementDisplayText(agreementInfo); quickPick.ignoreFocusOut = true; quickPick.buttons = [openEulaButton]; const disposables: vscode.Disposable[] = []; try { const eulaAcceptedPromise = new Promise((resolve) => { disposables.push( quickPick.onDidHide(() => { resolve(false); }), quickPick.onDidTriggerButton(async () => { await vscode.env.openExternal(vscode.Uri.parse(agreementInfo.link.url)); }), quickPick.onDidChangeSelection((item) => { resolve(item[0].label === constants.yesString); })); }); quickPick.show(); eulaAccepted = await eulaAcceptedPromise; quickPick.hide(); } finally { disposables.forEach(d => d.dispose()); } return eulaAccepted; } return false; }