mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-16 01:25:36 -05:00
sqlproj publish to container - october release improvements (#17289)
This commit is contained in:
@@ -160,7 +160,8 @@ export const enterConnStringTemplateDescription = localize('enterConnStringTempl
|
||||
export const appSettingPrompt = localize('appSettingPrompt', "Would you like to update Azure Function local.settings.json with the new connection string?");
|
||||
export const enterConnectionStringEnvNameDescription = localize('enterConnectionStringEnvNameDescription', "Enter environment variable for SQL connection string");
|
||||
export const deployDbTaskName = localize('deployDbTaskName', "Deploying SQL Db Project Locally");
|
||||
export const deployProjectSucceed = localize('deployProjectSucceed', "Database project deployed successfully");
|
||||
export const publishProjectSucceed = localize('publishProjectSucceed', "Database project published successfully");
|
||||
export const publishingProjectMessage = localize('publishingProjectMessage', "Publishing project in a container...");
|
||||
export const cleaningDockerImagesMessage = localize('cleaningDockerImagesMessage', "Cleaning existing deployments...");
|
||||
export const creatingDeploymentSettingsMessage = localize('creatingDeploymentSettingsMessage', "Creating deployment settings ...");
|
||||
export const runningDockerMessage = localize('runningDockerMessage', "Building and running the docker container ...");
|
||||
@@ -169,8 +170,10 @@ export const dockerContainerNotRunningErrorMessage = localize('dockerContainerNo
|
||||
export const dockerContainerFailedToRunErrorMessage = localize('dockerContainerFailedToRunErrorMessage', "Failed to run the docker container");
|
||||
export const connectingToSqlServerOnDockerMessage = localize('connectingToSqlServerOnDockerMessage', "Connecting to SQL Server on Docker");
|
||||
export const deployProjectFailedMessage = localize('deployProjectFailedMessage', "Failed to open a connection to the deployed database'");
|
||||
export const containerAlreadyExistForProject = localize('containerAlreadyExistForProject', "Other servers on container already exist for the project. Do you want to delete them?'");
|
||||
export const checkoutOutputMessage = localize('checkoutOutputMessage', "Check output pane for more details.");
|
||||
export function taskFailedError(taskName: string, err: string): string { return localize('taskFailedError.error', "Failed to complete task '{0}'. Error: {1}", taskName, err); }
|
||||
export function publishToContainerFailed(errorMessage: string) { return localize('publishToContainerFailed', "Failed to publish to container. Check output pane for more details. {0}", errorMessage); }
|
||||
export function publishToContainerFailed(errorMessage: string) { return localize('publishToContainerFailed', "Failed to publish to container. {0}", errorMessage); }
|
||||
export function deployAppSettingUpdateFailed(appSetting: string) { return localize('deployAppSettingUpdateFailed', "Failed to update app setting '{0}'", appSetting); }
|
||||
export function deployAppSettingUpdating(appSetting: string) { return localize('deployAppSettingUpdating', "Updating app setting: '{0}'", appSetting); }
|
||||
export function connectionFailedError(error: string) { return localize('connectionFailedError', "Connection failed error: '{0}'", error); }
|
||||
|
||||
@@ -437,6 +437,12 @@ export async function executeCommand(cmd: string, outputChannel: vscode.OutputCh
|
||||
timeout: timeout
|
||||
}, (err, stdout) => {
|
||||
if (err) {
|
||||
|
||||
// removing sensitive data from the exception
|
||||
sensitiveData.forEach(element => {
|
||||
err.cmd = err.cmd?.replace(element, '***');
|
||||
err.message = err.message?.replace(element, '***');
|
||||
});
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(stdout);
|
||||
@@ -552,3 +558,18 @@ export function isValidSQLPassword(password: string, userName: string = 'sa'): b
|
||||
const hasNonAlphas = /\W/.test(password) ? 1 : 0;
|
||||
return !containsUserName && password.length >= 8 && password.length <= 128 && (hasUpperCase + hasLowerCase + hasNumbers + hasNonAlphas >= 3);
|
||||
}
|
||||
|
||||
export async function showErrorMessageWithOutputChannel(errorMessageFunc: (error: string) => string, error: any, outputChannel: vscode.OutputChannel): Promise<void> {
|
||||
const result = await vscode.window.showErrorMessage(errorMessageFunc(getErrorMessage(error)), constants.checkoutOutputMessage);
|
||||
if (result !== undefined) {
|
||||
outputChannel.show();
|
||||
}
|
||||
}
|
||||
|
||||
export async function showInfoMessageWithOutputChannel(message: string, outputChannel: vscode.OutputChannel): Promise<void> {
|
||||
const result = await vscode.window.showInformationMessage(message, constants.checkoutOutputMessage);
|
||||
if (result !== undefined) {
|
||||
outputChannel.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,11 +73,11 @@ export class ProjectsController {
|
||||
|
||||
projFileWatchers = new Map<string, vscode.FileSystemWatcher>();
|
||||
|
||||
constructor(outputChannel: vscode.OutputChannel) {
|
||||
this.netCoreTool = new NetCoreTool(outputChannel);
|
||||
constructor(private _outputChannel: vscode.OutputChannel) {
|
||||
this.netCoreTool = new NetCoreTool(this._outputChannel);
|
||||
this.buildHelper = new BuildHelper();
|
||||
this.deployService = new DeployService(outputChannel);
|
||||
this.autorestHelper = new AutorestHelper(outputChannel);
|
||||
this.deployService = new DeployService(this._outputChannel);
|
||||
this.autorestHelper = new AutorestHelper(this._outputChannel);
|
||||
}
|
||||
|
||||
public getDashboardPublishData(projectFile: string): (string | dataworkspace.IconCellValue)[][] {
|
||||
@@ -270,6 +270,7 @@ export class ProjectsController {
|
||||
if (deployProfile && deployProfile.deploySettings) {
|
||||
let connectionUri: string | undefined;
|
||||
if (deployProfile.localDbSetting) {
|
||||
void utils.showInfoMessageWithOutputChannel(constants.publishingProjectMessage, this._outputChannel);
|
||||
connectionUri = await this.deployService.deploy(deployProfile, project);
|
||||
if (connectionUri) {
|
||||
deployProfile.deploySettings.connectionUri = connectionUri;
|
||||
@@ -281,16 +282,16 @@ export class ProjectsController {
|
||||
if (deployProfile.localDbSetting) {
|
||||
await this.deployService.getConnection(deployProfile.localDbSetting, true, deployProfile.localDbSetting.dbName);
|
||||
}
|
||||
void vscode.window.showInformationMessage(constants.deployProjectSucceed);
|
||||
void vscode.window.showInformationMessage(constants.publishProjectSucceed);
|
||||
} else {
|
||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(publishResult?.errorMessage || ''));
|
||||
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, publishResult?.errorMessage || '', this._outputChannel);
|
||||
}
|
||||
} else {
|
||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(constants.deployProjectFailedMessage));
|
||||
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, constants.deployProjectFailedMessage, this._outputChannel);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(utils.getErrorMessage(error)));
|
||||
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, error, this._outputChannel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,11 +111,15 @@ export class DeployService {
|
||||
const dockerFilePath = path.join(mssqlFolderPath, constants.dockerFileName);
|
||||
const startFilePath = path.join(commandsFolderPath, constants.startCommandName);
|
||||
|
||||
this.logToOutput(constants.cleaningDockerImagesMessage);
|
||||
// Clean up existing docker image
|
||||
|
||||
await this.cleanDockerObjects(`docker ps -q -a --filter label=${imageLabel}`, ['docker stop', 'docker rm']);
|
||||
await this.cleanDockerObjects(`docker images -f label=${imageLabel} -q`, [`docker rmi -f `]);
|
||||
const containerIds = await this.getCurrentDockerContainer(imageLabel);
|
||||
if (containerIds && containerIds.length > 0) {
|
||||
const result = await vscode.window.showWarningMessage(constants.containerAlreadyExistForProject, constants.yesString, constants.noString);
|
||||
if (result === constants.yesString) {
|
||||
this.logToOutput(constants.cleaningDockerImagesMessage);
|
||||
await this.cleanDockerObjects(containerIds, ['docker stop', 'docker rm']);
|
||||
}
|
||||
}
|
||||
|
||||
this.logToOutput(constants.creatingDeploymentSettingsMessage);
|
||||
// Create commands
|
||||
@@ -363,17 +367,22 @@ RUN ["/bin/bash", "/opt/commands/start.sh"]
|
||||
await fse.writeFile(filePath, content);
|
||||
}
|
||||
|
||||
public async cleanDockerObjects(commandToGetObjects: string, commandsToClean: string[]): Promise<void> {
|
||||
const currentIds = await utils.executeCommand(commandToGetObjects, this._outputChannel);
|
||||
if (currentIds) {
|
||||
const ids = currentIds.split(/\r?\n/);
|
||||
for (let index = 0; index < ids.length; index++) {
|
||||
const id = ids[index];
|
||||
if (id) {
|
||||
for (let commandId = 0; commandId < commandsToClean.length; commandId++) {
|
||||
const command = commandsToClean[commandId];
|
||||
await utils.executeCommand(`${command} ${id}`, this._outputChannel);
|
||||
}
|
||||
private async getCurrentIds(commandToRun: string): Promise<string[]> {
|
||||
const currentIds = await utils.executeCommand(commandToRun, this._outputChannel);
|
||||
return currentIds ? currentIds.split(/\r?\n/) : [];
|
||||
}
|
||||
|
||||
public async getCurrentDockerContainer(imageLabel: string): Promise<string[]> {
|
||||
return await this.getCurrentIds(`docker ps -q -a --filter label=${imageLabel}`);
|
||||
}
|
||||
|
||||
public async cleanDockerObjects(ids: string[], commandsToClean: string[]): Promise<void> {
|
||||
for (let index = 0; index < ids.length; index++) {
|
||||
const id = ids[index];
|
||||
if (id) {
|
||||
for (let commandId = 0; commandId < commandsToClean.length; commandId++) {
|
||||
const command = commandsToClean[commandId];
|
||||
await utils.executeCommand(`${command} ${id}`, this._outputChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import * as childProcess from 'child_process';
|
||||
import { AppSettingType, IDeployProfile } from '../../models/deploy/deployProfile';
|
||||
let fse = require('fs-extra');
|
||||
let path = require('path');
|
||||
import * as constants from '../../common/constants';
|
||||
|
||||
export interface TestContext {
|
||||
outputChannel: vscode.OutputChannel;
|
||||
@@ -81,6 +82,7 @@ describe('deploy service', function (): void {
|
||||
const deployService = new DeployService(testContext.outputChannel);
|
||||
sandbox.stub(azdata.connection, 'connect').returns(Promise.resolve(mockConnectionResult));
|
||||
sandbox.stub(azdata.connection, 'getUriForConnection').returns(Promise.resolve('connection'));
|
||||
sandbox.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve(constants.yesString));
|
||||
sandbox.stub(azdata.tasks, 'startBackgroundOperation').callThrough();
|
||||
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
||||
let connection = await deployService.deploy(deployProfile, project1);
|
||||
@@ -168,10 +170,12 @@ describe('deploy service', function (): void {
|
||||
}
|
||||
};
|
||||
|
||||
const appInteg = {appSettingType: AppSettingType.AzureFunction,
|
||||
const appInteg = {
|
||||
appSettingType: AppSettingType.AzureFunction,
|
||||
appSettingFile: filePath,
|
||||
deploySettings: undefined,
|
||||
envVariableName: 'SQLConnectionString'};
|
||||
envVariableName: 'SQLConnectionString'
|
||||
};
|
||||
|
||||
const deployService = new DeployService(testContext.outputChannel);
|
||||
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
||||
@@ -240,8 +244,8 @@ describe('deploy service', function (): void {
|
||||
id2
|
||||
id3`);
|
||||
|
||||
await deployService.cleanDockerObjects(`docker ps -q -a --filter label=test`, ['docker stop', 'docker rm']);
|
||||
const ids = await deployService.getCurrentDockerContainer('label');
|
||||
await deployService.cleanDockerObjects(ids, ['docker stop', 'docker rm']);
|
||||
should(process.calledThrice);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user