mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51: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 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 enterConnectionStringEnvNameDescription = localize('enterConnectionStringEnvNameDescription', "Enter environment variable for SQL connection string");
|
||||||
export const deployDbTaskName = localize('deployDbTaskName', "Deploying SQL Db Project Locally");
|
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 cleaningDockerImagesMessage = localize('cleaningDockerImagesMessage', "Cleaning existing deployments...");
|
||||||
export const creatingDeploymentSettingsMessage = localize('creatingDeploymentSettingsMessage', "Creating deployment settings ...");
|
export const creatingDeploymentSettingsMessage = localize('creatingDeploymentSettingsMessage', "Creating deployment settings ...");
|
||||||
export const runningDockerMessage = localize('runningDockerMessage', "Building and running the docker container ...");
|
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 dockerContainerFailedToRunErrorMessage = localize('dockerContainerFailedToRunErrorMessage', "Failed to run the docker container");
|
||||||
export const connectingToSqlServerOnDockerMessage = localize('connectingToSqlServerOnDockerMessage', "Connecting to SQL Server on Docker");
|
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 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 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 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 deployAppSettingUpdating(appSetting: string) { return localize('deployAppSettingUpdating', "Updating app setting: '{0}'", appSetting); }
|
||||||
export function connectionFailedError(error: string) { return localize('connectionFailedError', "Connection failed error: '{0}'", error); }
|
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
|
timeout: timeout
|
||||||
}, (err, stdout) => {
|
}, (err, stdout) => {
|
||||||
if (err) {
|
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);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
resolve(stdout);
|
resolve(stdout);
|
||||||
@@ -552,3 +558,18 @@ export function isValidSQLPassword(password: string, userName: string = 'sa'): b
|
|||||||
const hasNonAlphas = /\W/.test(password) ? 1 : 0;
|
const hasNonAlphas = /\W/.test(password) ? 1 : 0;
|
||||||
return !containsUserName && password.length >= 8 && password.length <= 128 && (hasUpperCase + hasLowerCase + hasNumbers + hasNonAlphas >= 3);
|
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>();
|
projFileWatchers = new Map<string, vscode.FileSystemWatcher>();
|
||||||
|
|
||||||
constructor(outputChannel: vscode.OutputChannel) {
|
constructor(private _outputChannel: vscode.OutputChannel) {
|
||||||
this.netCoreTool = new NetCoreTool(outputChannel);
|
this.netCoreTool = new NetCoreTool(this._outputChannel);
|
||||||
this.buildHelper = new BuildHelper();
|
this.buildHelper = new BuildHelper();
|
||||||
this.deployService = new DeployService(outputChannel);
|
this.deployService = new DeployService(this._outputChannel);
|
||||||
this.autorestHelper = new AutorestHelper(outputChannel);
|
this.autorestHelper = new AutorestHelper(this._outputChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDashboardPublishData(projectFile: string): (string | dataworkspace.IconCellValue)[][] {
|
public getDashboardPublishData(projectFile: string): (string | dataworkspace.IconCellValue)[][] {
|
||||||
@@ -270,6 +270,7 @@ export class ProjectsController {
|
|||||||
if (deployProfile && deployProfile.deploySettings) {
|
if (deployProfile && deployProfile.deploySettings) {
|
||||||
let connectionUri: string | undefined;
|
let connectionUri: string | undefined;
|
||||||
if (deployProfile.localDbSetting) {
|
if (deployProfile.localDbSetting) {
|
||||||
|
void utils.showInfoMessageWithOutputChannel(constants.publishingProjectMessage, this._outputChannel);
|
||||||
connectionUri = await this.deployService.deploy(deployProfile, project);
|
connectionUri = await this.deployService.deploy(deployProfile, project);
|
||||||
if (connectionUri) {
|
if (connectionUri) {
|
||||||
deployProfile.deploySettings.connectionUri = connectionUri;
|
deployProfile.deploySettings.connectionUri = connectionUri;
|
||||||
@@ -281,16 +282,16 @@ export class ProjectsController {
|
|||||||
if (deployProfile.localDbSetting) {
|
if (deployProfile.localDbSetting) {
|
||||||
await this.deployService.getConnection(deployProfile.localDbSetting, true, deployProfile.localDbSetting.dbName);
|
await this.deployService.getConnection(deployProfile.localDbSetting, true, deployProfile.localDbSetting.dbName);
|
||||||
}
|
}
|
||||||
void vscode.window.showInformationMessage(constants.deployProjectSucceed);
|
void vscode.window.showInformationMessage(constants.publishProjectSucceed);
|
||||||
} else {
|
} else {
|
||||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(publishResult?.errorMessage || ''));
|
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, publishResult?.errorMessage || '', this._outputChannel);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(constants.deployProjectFailedMessage));
|
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, constants.deployProjectFailedMessage, this._outputChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
void vscode.window.showErrorMessage(constants.publishToContainerFailed(utils.getErrorMessage(error)));
|
void utils.showErrorMessageWithOutputChannel(constants.publishToContainerFailed, error, this._outputChannel);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,11 +111,15 @@ export class DeployService {
|
|||||||
const dockerFilePath = path.join(mssqlFolderPath, constants.dockerFileName);
|
const dockerFilePath = path.join(mssqlFolderPath, constants.dockerFileName);
|
||||||
const startFilePath = path.join(commandsFolderPath, constants.startCommandName);
|
const startFilePath = path.join(commandsFolderPath, constants.startCommandName);
|
||||||
|
|
||||||
this.logToOutput(constants.cleaningDockerImagesMessage);
|
|
||||||
// Clean up existing docker image
|
// Clean up existing docker image
|
||||||
|
const containerIds = await this.getCurrentDockerContainer(imageLabel);
|
||||||
await this.cleanDockerObjects(`docker ps -q -a --filter label=${imageLabel}`, ['docker stop', 'docker rm']);
|
if (containerIds && containerIds.length > 0) {
|
||||||
await this.cleanDockerObjects(`docker images -f label=${imageLabel} -q`, [`docker rmi -f `]);
|
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);
|
this.logToOutput(constants.creatingDeploymentSettingsMessage);
|
||||||
// Create commands
|
// Create commands
|
||||||
@@ -363,10 +367,16 @@ RUN ["/bin/bash", "/opt/commands/start.sh"]
|
|||||||
await fse.writeFile(filePath, content);
|
await fse.writeFile(filePath, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async cleanDockerObjects(commandToGetObjects: string, commandsToClean: string[]): Promise<void> {
|
private async getCurrentIds(commandToRun: string): Promise<string[]> {
|
||||||
const currentIds = await utils.executeCommand(commandToGetObjects, this._outputChannel);
|
const currentIds = await utils.executeCommand(commandToRun, this._outputChannel);
|
||||||
if (currentIds) {
|
return currentIds ? currentIds.split(/\r?\n/) : [];
|
||||||
const ids = 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++) {
|
for (let index = 0; index < ids.length; index++) {
|
||||||
const id = ids[index];
|
const id = ids[index];
|
||||||
if (id) {
|
if (id) {
|
||||||
@@ -377,5 +387,4 @@ RUN ["/bin/bash", "/opt/commands/start.sh"]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import * as childProcess from 'child_process';
|
|||||||
import { AppSettingType, IDeployProfile } from '../../models/deploy/deployProfile';
|
import { AppSettingType, IDeployProfile } from '../../models/deploy/deployProfile';
|
||||||
let fse = require('fs-extra');
|
let fse = require('fs-extra');
|
||||||
let path = require('path');
|
let path = require('path');
|
||||||
|
import * as constants from '../../common/constants';
|
||||||
|
|
||||||
export interface TestContext {
|
export interface TestContext {
|
||||||
outputChannel: vscode.OutputChannel;
|
outputChannel: vscode.OutputChannel;
|
||||||
@@ -81,6 +82,7 @@ describe('deploy service', function (): void {
|
|||||||
const deployService = new DeployService(testContext.outputChannel);
|
const deployService = new DeployService(testContext.outputChannel);
|
||||||
sandbox.stub(azdata.connection, 'connect').returns(Promise.resolve(mockConnectionResult));
|
sandbox.stub(azdata.connection, 'connect').returns(Promise.resolve(mockConnectionResult));
|
||||||
sandbox.stub(azdata.connection, 'getUriForConnection').returns(Promise.resolve('connection'));
|
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(azdata.tasks, 'startBackgroundOperation').callThrough();
|
||||||
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
||||||
let connection = await deployService.deploy(deployProfile, project1);
|
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,
|
appSettingFile: filePath,
|
||||||
deploySettings: undefined,
|
deploySettings: undefined,
|
||||||
envVariableName: 'SQLConnectionString'};
|
envVariableName: 'SQLConnectionString'
|
||||||
|
};
|
||||||
|
|
||||||
const deployService = new DeployService(testContext.outputChannel);
|
const deployService = new DeployService(testContext.outputChannel);
|
||||||
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
sandbox.stub(childProcess, 'exec').yields(undefined, 'id');
|
||||||
@@ -240,8 +244,8 @@ describe('deploy service', function (): void {
|
|||||||
id2
|
id2
|
||||||
id3`);
|
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);
|
should(process.calledThrice);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user