From f6d2af58afc7271e59a45102cfb1dfb2e15f9684 Mon Sep 17 00:00:00 2001 From: Kim Santiago <31145923+kisantia@users.noreply.github.com> Date: Thu, 11 Aug 2022 14:58:09 -0700 Subject: [PATCH] Add image tag matching target platform for publish to docker (#20296) * add the image tag for the sql server version * add preview text and test * cleanup --- .../src/common/constants.ts | 1 + .../src/dialogs/publishDatabaseDialog.ts | 21 ++++++++++-- .../src/dialogs/utils.ts | 29 +++++++++++++++++ .../src/test/dialogs/utils.test.ts | 32 +++++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 extensions/sql-database-projects/src/test/dialogs/utils.test.ts diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts index 5fd4911056..7b27a300a4 100644 --- a/extensions/sql-database-projects/src/common/constants.ts +++ b/extensions/sql-database-projects/src/common/constants.ts @@ -160,6 +160,7 @@ export function OptionNotFoundWarningMessage(label: string) { return localize('o export const SqlServerName = 'SQL server'; export const AzureSqlServerName = 'Azure SQL server'; export const SqlServerDockerImageName = 'Microsoft SQL Server'; +export const SqlServerDocker2022ImageName = 'Microsoft SQL Server 2022 (preview)'; export const AzureSqlDbFullDockerImageName = 'Azure SQL Database emulator Full'; export const AzureSqlDbLiteDockerImageName = 'Azure SQL Database emulator Lite'; export const AzureSqlLogicalServerName = 'Azure SQL logical server'; diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts index 0f7549c373..68ab5c587f 100644 --- a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts @@ -13,11 +13,11 @@ import { SqlConnectionDataSource } from '../models/dataSources/sqlConnectionStri import { DeploymentOptions } from 'mssql'; import { IconPathHelper } from '../common/iconHelper'; import { cssStyles } from '../common/uiConstants'; -import { getAgreementDisplayText, getConnectionName, getDockerBaseImages, getPublishServerName } from './utils'; +import { getAgreementDisplayText, getConnectionName, getDefaultDockerImageWithTag, getDockerBaseImages, getPublishServerName } from './utils'; import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry'; import { Deferred } from '../common/promise'; import { PublishOptionsDialog } from './publishOptionsDialog'; -import { ISqlProjectPublishSettings, IPublishToDockerSettings } from 'sqldbproj'; +import { ISqlProjectPublishSettings, IPublishToDockerSettings, SqlTargetPlatform } from 'sqldbproj'; interface DataSourceDropdownValue extends azdataType.CategoryValue { dataSource: SqlConnectionDataSource; @@ -241,9 +241,14 @@ export class PublishDatabaseDialog { utils.getAzdataApi()!.window.closeDialog(this.dialog); await this.publish!(this.project, settings); } else { - const dockerBaseImage = this.getBaseDockerImageName(); + let dockerBaseImage = this.getBaseDockerImageName(); const baseImages = getDockerBaseImages(this.project.getProjectTargetVersion()); const imageInfo = baseImages.find(x => x.name === dockerBaseImage); + + // selecting the image tag isn't currently exposed in the publish dialog, so this adds the tag matching the target platform + // to make sure the correct image is used for the project's target platform when the docker base image is SQL Server + dockerBaseImage = getDefaultDockerImageWithTag(this.project.getProjectTargetVersion(), dockerBaseImage, imageInfo); + const settings: IPublishToDockerSettings = { dockerSettings: { dbName: this.targetDatabaseName, @@ -598,6 +603,16 @@ export class PublishDatabaseDialog { const baseImages = getDockerBaseImages(this.project.getProjectTargetVersion()); const baseImagesValues: azdataType.CategoryValue[] = baseImages.map(x => { return { name: x.name, displayName: x.displayName }; }); + + // add preview string for 2022 + // TODO: remove after 2022 is GA + if (this.project.getProjectTargetVersion() === constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlServer2022)) { + const sqlServerImageIndex = baseImagesValues.findIndex(image => image.displayName === constants.SqlServerDockerImageName); + if (sqlServerImageIndex >= 0) { + baseImagesValues[sqlServerImageIndex].displayName = constants.SqlServerDocker2022ImageName; + } + } + this.baseDockerImageDropDown = view.modelBuilder.dropDown().withProps({ values: baseImagesValues, ariaLabel: constants.baseDockerImage(name), diff --git a/extensions/sql-database-projects/src/dialogs/utils.ts b/extensions/sql-database-projects/src/dialogs/utils.ts index 6fe52db9f6..34a93ba82b 100644 --- a/extensions/sql-database-projects/src/dialogs/utils.ts +++ b/extensions/sql-database-projects/src/dialogs/utils.ts @@ -155,3 +155,32 @@ export function getDockerBaseImages(target: string): DockerImageInfo[] { ]; } } + +/** + * This adds the tag matching the target platform to make sure the correct image is used for the project's target platform when the docker base image is SQL Server. + * If the image is Edge, then no tag is appended + * @param projectTargetVersion target version of the project + * @param dockerImage selected base docker image without tag + * @param imageInfo docker image info of the selected docker image + * @returns dockerBaseImage with the appropriate image tag appended if there is one + */ +export function getDefaultDockerImageWithTag(projectTargetVersion: string, dockerImage: string, imageInfo?: DockerImageInfo,): string { + if (imageInfo?.displayName === constants.SqlServerDockerImageName) { + switch (projectTargetVersion) { + case constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlServer2022): + dockerImage = `${dockerImage}:2022-latest`; + break; + case constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlServer2019): + dockerImage = `${dockerImage}:2019-latest`; + break; + case constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlServer2017): + dockerImage = `${dockerImage}:2017-latest`; + break; + default: + // nothing - let it be the default image defined as default in the container registry + break; + } + } + + return dockerImage; +} diff --git a/extensions/sql-database-projects/src/test/dialogs/utils.test.ts b/extensions/sql-database-projects/src/test/dialogs/utils.test.ts new file mode 100644 index 0000000000..2387ff6f2e --- /dev/null +++ b/extensions/sql-database-projects/src/test/dialogs/utils.test.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as should from 'should'; +import * as constants from '../../common/constants'; +import { SqlTargetPlatform } from 'sqldbproj'; +import { getDefaultDockerImageWithTag, getDockerBaseImages } from '../../dialogs/utils'; + +describe('Tests to verify dialog utils functions', function (): void { + it('getDefaultDockerImageWithTag should return correct image', () => { + const baseImages = getDockerBaseImages(constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlServer2022)!); + const sqlServerImageInfo = baseImages.find(image => image.displayName === constants.SqlServerDockerImageName); + const edgeImageInfo = baseImages.find(image => image.displayName === SqlTargetPlatform.sqlEdge); + + should(getDefaultDockerImageWithTag('160', 'mcr.microsoft.com/mssql/server', sqlServerImageInfo)).equals(`${sqlServerImageInfo?.name}:2022-latest`, 'Unexpected docker image returned for target platform SQL Server 2022 and SQL Server base image'); + should(getDefaultDockerImageWithTag('150', 'mcr.microsoft.com/mssql/server', sqlServerImageInfo)).equals(`${sqlServerImageInfo?.name}:2019-latest`, 'Unexpected docker image returned for target platform SQL Server 2019 and SQL Server base image'); + should(getDefaultDockerImageWithTag('140', 'mcr.microsoft.com/mssql/server', sqlServerImageInfo)).equals(`${sqlServerImageInfo?.name}:2017-latest`, 'Unexpected docker image returned for target platform SQL Server 2017 and SQL Server base image'); + should(getDefaultDockerImageWithTag('130', 'mcr.microsoft.com/mssql/server', sqlServerImageInfo)).equals(`${sqlServerImageInfo?.name}`, 'Unexpected docker image returned for target platform SQL Server 2016 and SQL Server base image'); + should(getDefaultDockerImageWithTag('150', 'mcr.microsoft.com/azure-sql-edge', edgeImageInfo)).equals(`${edgeImageInfo?.name}`, 'Unexpected docker image returned for target platform SQL Server 2019 and Edge base image'); + + // different display names are returned when a project's target platform is Azure, but currently the Azure full image points to mcr.microsoft.com/mssql/server + const azureBaseImages = getDockerBaseImages(constants.targetPlatformToVersion.get(SqlTargetPlatform.sqlAzure)!); + const azureFullImageInfo = azureBaseImages.find(image => image.displayName === constants.AzureSqlDbFullDockerImageName); + const azureLiteImageInfo = azureBaseImages.find(image => image.displayName === constants.AzureSqlDbLiteDockerImageName); + + should(getDefaultDockerImageWithTag('AzureV12', 'mcr.microsoft.com/mssql/server', azureFullImageInfo)).equals(`${azureFullImageInfo?.name}`, 'Unexpected docker image returned for target platform Azure and Azure full base image'); + should(getDefaultDockerImageWithTag('AzureV12', 'mcr.microsoft.com/azure-sql-edge', azureLiteImageInfo)).equals(`${azureLiteImageInfo?.name}`, 'Unexpected docker image returned for target platform Azure Azure lite base image'); + }); +}); +