mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-22 09:35:37 -05:00
[SQL Migration] Disable IR scenario and check page blobs for SQL VM <= 2014 (#21373)
* Disable IR scenario and add info box for source < 2014 * Update text and link * Clean up * Fix issue where switching to another target platform wouldn't clear restriction * Remove locale from documentation URL * Refactor * Clean up * Autoselect blob scenario * Refactor * Add page blog check * Clean up * Update UI logic
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { EOL } from 'os';
|
||||
import { getStorageAccountAccessKeys } from '../api/azure';
|
||||
import { getStorageAccountAccessKeys, SqlVMServer } from '../api/azure';
|
||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
||||
import { Blob, MigrationMode, MigrationSourceAuthenticationType, MigrationStateModel, MigrationTargetType, NetworkContainerType, NetworkShare, StateChangeEvent, ValidateIrState, ValidationResult } from '../models/stateMachine';
|
||||
import * as constants from '../constants/strings';
|
||||
@@ -66,6 +66,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
private _networkDetailsContainer!: azdata.FlexContainer;
|
||||
|
||||
private _existingDatabases: string[] = [];
|
||||
private _nonPageBlobErrors: string[] = [];
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
// SQL DB table selection
|
||||
@@ -696,29 +697,33 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
break;
|
||||
case NetworkContainerType.BLOB_CONTAINER:
|
||||
this._blobContainerResourceGroupDropdowns.forEach((v, index) => {
|
||||
if (this.shouldDisplayBlobDropdownError(v, [constants.RESOURCE_GROUP_NOT_FOUND])) {
|
||||
if (this.shouldDisplayBlobDropdownError(v, blobResourceGroupErrorStrings)) {
|
||||
errors.push(constants.INVALID_BLOB_RESOURCE_GROUP_ERROR(this.migrationStateModel._databasesForMigration[index]));
|
||||
}
|
||||
});
|
||||
this._blobContainerStorageAccountDropdowns.forEach((v, index) => {
|
||||
if (this.shouldDisplayBlobDropdownError(v, [constants.NO_STORAGE_ACCOUNT_FOUND, constants.SELECT_RESOURCE_GROUP_PROMPT])) {
|
||||
if (this.shouldDisplayBlobDropdownError(v, blobStorageAccountErrorStrings)) {
|
||||
errors.push(constants.INVALID_BLOB_STORAGE_ACCOUNT_ERROR(this.migrationStateModel._databasesForMigration[index]));
|
||||
}
|
||||
});
|
||||
this._blobContainerDropdowns.forEach((v, index) => {
|
||||
if (this.shouldDisplayBlobDropdownError(v, [constants.NO_BLOBCONTAINERS_FOUND, constants.SELECT_STORAGE_ACCOUNT])) {
|
||||
if (this.shouldDisplayBlobDropdownError(v, blobContainerErrorStrings)) {
|
||||
errors.push(constants.INVALID_BLOB_CONTAINER_ERROR(this.migrationStateModel._databasesForMigration[index]));
|
||||
}
|
||||
});
|
||||
|
||||
if (this.migrationStateModel._databaseBackup.migrationMode === MigrationMode.OFFLINE) {
|
||||
this._blobContainerLastBackupFileDropdowns.forEach((v, index) => {
|
||||
if (this.shouldDisplayBlobDropdownError(v, [constants.NO_BLOBFILES_FOUND, constants.SELECT_BLOB_CONTAINER])) {
|
||||
if (this.shouldDisplayBlobDropdownError(v, blobFileErrorStrings)) {
|
||||
errors.push(constants.INVALID_BLOB_LAST_BACKUP_FILE_ERROR(this.migrationStateModel._databasesForMigration[index]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.migrationStateModel.isSqlVmTarget && utils.isTargetSqlVm2014OrBelow(this.migrationStateModel._targetServerInstance as SqlVMServer)) {
|
||||
errors.push(...this._nonPageBlobErrors);
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
const duplicates: Map<string, number[]> = new Map();
|
||||
for (let i = 0; i < this.migrationStateModel._targetDatabaseNames.length; i++) {
|
||||
@@ -1047,6 +1052,23 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
const selectedBlobContainer = this.migrationStateModel._blobContainers.find(blob => blob.name === value);
|
||||
if (selectedBlobContainer && !blobContainerErrorStrings.includes(value)) {
|
||||
this.migrationStateModel._databaseBackup.blobs[index].blobContainer = selectedBlobContainer;
|
||||
|
||||
if (this.migrationStateModel.isSqlVmTarget && utils.isTargetSqlVm2014OrBelow(this.migrationStateModel._targetServerInstance as SqlVMServer)) {
|
||||
const backups = await utils.getBlobLastBackupFileNames(
|
||||
this.migrationStateModel._azureAccount,
|
||||
this.migrationStateModel._databaseBackup.subscription,
|
||||
this.migrationStateModel._databaseBackup.blobs[index]?.storageAccount,
|
||||
this.migrationStateModel._databaseBackup.blobs[index]?.blobContainer);
|
||||
|
||||
const errorMessage = constants.INVALID_NON_PAGE_BLOB_BACKUP_FILE_ERROR(this.migrationStateModel._databasesForMigration[index]);
|
||||
this._nonPageBlobErrors = this._nonPageBlobErrors.filter(err => err !== errorMessage);
|
||||
|
||||
const allBackupsPageBlob = backups.every(backup => backup.properties.blobType === 'PageBlob')
|
||||
if (!allBackupsPageBlob) {
|
||||
this._nonPageBlobErrors.push(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.migrationStateModel._databaseBackup.migrationMode === MigrationMode.OFFLINE) {
|
||||
await this.loadBlobLastBackupFileDropdown(index);
|
||||
await blobContainerLastBackupFileDropdown.updateProperties({ enabled: true });
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MigrationMode, MigrationStateModel, NetworkContainerType, StateChangeEv
|
||||
import { CreateSqlMigrationServiceDialog } from '../dialog/createSqlMigrationService/createSqlMigrationServiceDialog';
|
||||
import * as constants from '../constants/strings';
|
||||
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
|
||||
import { getFullResourceGroupFromId, getLocationDisplayName, getSqlMigrationService, getSqlMigrationServiceAuthKeys, getSqlMigrationServiceMonitoringData } from '../api/azure';
|
||||
import { getFullResourceGroupFromId, getLocationDisplayName, getSqlMigrationService, getSqlMigrationServiceAuthKeys, getSqlMigrationServiceMonitoringData, SqlVMServer } from '../api/azure';
|
||||
import { IconPathHelper } from '../constants/iconPathHelper';
|
||||
import { logError, TelemetryViews } from '../telemtery';
|
||||
import * as utils from '../api/utils';
|
||||
@@ -38,6 +38,7 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
private _radioButtonContainer!: azdata.FlexContainer;
|
||||
private _networkShareButton!: azdata.RadioButtonComponent;
|
||||
private _blobContainerButton!: azdata.RadioButtonComponent;
|
||||
private _sqlVmPageBlobInfoBox!: azdata.TextComponent;
|
||||
private _originalMigrationMode!: MigrationMode;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
@@ -178,11 +179,26 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
}
|
||||
}));
|
||||
|
||||
this._sqlVmPageBlobInfoBox = this._view.modelBuilder.infoBox()
|
||||
.withProps({
|
||||
text: constants.DATABASE_BACKUP_SQL_VM_PAGE_BLOB_INFO,
|
||||
style: 'information',
|
||||
width: WIZARD_INPUT_COMPONENT_WIDTH,
|
||||
CSSStyles: { ...styles.BODY_CSS, 'display': 'none' },
|
||||
links: [
|
||||
{
|
||||
text: constants.DATABASE_BACKUP_SQL_VM_PAGE_BLOB_URL_LABEL,
|
||||
url: 'https://aka.ms/dms-migrations-troubleshooting'
|
||||
}
|
||||
]
|
||||
}).component();
|
||||
|
||||
const flexContainer = this._view.modelBuilder.flexContainer()
|
||||
.withItems([
|
||||
selectLocationText,
|
||||
this._blobContainerButton,
|
||||
this._networkShareButton,
|
||||
this._sqlVmPageBlobInfoBox
|
||||
])
|
||||
.withLayout({ flexFlow: 'column' })
|
||||
.component();
|
||||
@@ -192,6 +208,7 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
|
||||
public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
|
||||
const isSqlDbTarget = this.migrationStateModel.isSqlDbTarget;
|
||||
const isSqlVmTarget = this.migrationStateModel.isSqlVmTarget;
|
||||
const isNetworkShare = this.migrationStateModel.isBackupContainerNetworkShare;
|
||||
|
||||
this.wizard.registerNavigationValidator((pageChangeInfo) => {
|
||||
@@ -245,6 +262,15 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
this._radioButtonContainer,
|
||||
!isSqlDbTarget);
|
||||
|
||||
// if target SQL VM version is <= 2014, disable IR scenario and show info box
|
||||
const shouldDisableIrScenario = isSqlVmTarget && utils.isTargetSqlVm2014OrBelow(this.migrationStateModel._targetServerInstance as SqlVMServer);
|
||||
this._networkShareButton.enabled = !shouldDisableIrScenario;
|
||||
await utils.updateControlDisplay(this._sqlVmPageBlobInfoBox, shouldDisableIrScenario, 'block');
|
||||
|
||||
// always pre-select blob scenario
|
||||
this.migrationStateModel._databaseBackup.networkContainerType = NetworkContainerType.BLOB_CONTAINER;
|
||||
this._blobContainerButton.checked = true;
|
||||
|
||||
this._subscription.value = this.migrationStateModel._targetSubscription.name;
|
||||
this._location.value = await getLocationDisplayName(
|
||||
this.migrationStateModel._targetServerInstance.location);
|
||||
|
||||
Reference in New Issue
Block a user