diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java index 07b538426405..27b7e7748f9e 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java @@ -1958,25 +1958,26 @@ protected MigrationOptions createFullCloneMigrationOptions(VolumeInfo srcVolumeI * - Full clones (no backing file): Take snapshot of the VM prior disk creation * Return this information */ - protected void setVolumeMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, - VirtualMachineTO vmTO, Host srcHost, StoragePoolVO destStoragePool) { - if (!destStoragePool.isManaged()) { - String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo); - - String srcPoolUuid = srcVolumeInfo.getDataStore().getUuid(); - StoragePoolVO srcPool = _storagePoolDao.findById(srcVolumeInfo.getPoolId()); - Storage.StoragePoolType srcPoolType = srcPool.getPoolType(); - - MigrationOptions migrationOptions; - if (StringUtils.isNotBlank(srcVolumeBackingFile)) { - migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo, - srcVolumeBackingFile, srcPoolUuid, srcPoolType); - } else { - migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPoolUuid, srcPoolType); - } - migrationOptions.setTimeout(StorageManager.KvmStorageOnlineMigrationWait.value()); - destVolumeInfo.setMigrationOptions(migrationOptions); + protected void setVolumeMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, VirtualMachineTO vmTO, Host srcHost, StoragePoolVO destStoragePool, + MigrationOptions.Type migrationType) { + if (destStoragePool.isManaged()) { + return; + } + + String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo); + + String srcPoolUuid = srcVolumeInfo.getDataStore().getUuid(); + StoragePoolVO srcPool = _storagePoolDao.findById(srcVolumeInfo.getPoolId()); + Storage.StoragePoolType srcPoolType = srcPool.getPoolType(); + + MigrationOptions migrationOptions; + if (MigrationOptions.Type.LinkedClone.equals(migrationType)) { + migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo, srcVolumeBackingFile, srcPoolUuid, srcPoolType); + } else { + migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPoolUuid, srcPoolType); } + migrationOptions.setTimeout(StorageManager.KvmStorageOnlineMigrationWait.value()); + destVolumeInfo.setMigrationOptions(migrationOptions); } /** @@ -2007,6 +2008,7 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach Map srcVolumeInfoToDestVolumeInfo = new HashMap<>(); boolean managedStorageDestination = false; + boolean migrateNonSharedInc = false; for (Map.Entry entry : volumeDataStoreMap.entrySet()) { VolumeInfo srcVolumeInfo = entry.getKey(); DataStore destDataStore = entry.getValue(); @@ -2024,15 +2026,8 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach continue; } - VMTemplateVO vmTemplate = _vmTemplateDao.findById(vmInstance.getTemplateId()); - if (srcVolumeInfo.getTemplateId() != null && - Objects.nonNull(vmTemplate) && - !Arrays.asList(KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME, VM_IMPORT_DEFAULT_TEMPLATE_NAME).contains(vmTemplate.getName())) { - logger.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId())); - copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost); - } else { - logger.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a template.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId())); - } + MigrationOptions.Type migrationType = decideMigrationTypeAndCopyTemplateIfNeeded(destHost, vmInstance, srcVolumeInfo, sourceStoragePool, destStoragePool, destDataStore); + migrateNonSharedInc = migrateNonSharedInc || MigrationOptions.Type.LinkedClone.equals(migrationType); VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool); VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore); @@ -2044,7 +2039,7 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach // move the volume from Ready to Migrating destVolumeInfo.processEvent(Event.MigrationRequested); - setVolumeMigrationOptions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost, destStoragePool); + setVolumeMigrationOptions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost, destStoragePool, migrationType); // create a volume on the destination storage destDataStore.getDriver().createAsync(destDataStore, destVolumeInfo, null); @@ -2059,7 +2054,7 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach _volumeDao.update(destVolume.getId(), destVolume); - postVolumeCreationActions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost); + postVolumeCreationActions(srcVolumeInfo, destVolumeInfo); destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore); @@ -2110,8 +2105,6 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach VMInstanceVO vm = _vmDao.findById(vmTO.getId()); boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); - boolean migrateNonSharedInc = isSourceAndDestinationPoolTypeOfNfs(volumeDataStoreMap); - MigrateCommand migrateCommand = new MigrateCommand(vmTO.getName(), destHost.getPrivateIpAddress(), isWindows, vmTO, true); migrateCommand.setWait(StorageManager.KvmStorageOnlineMigrationWait.value()); migrateCommand.setMigrateStorage(migrateStorage); @@ -2161,6 +2154,22 @@ public void copyAsync(Map volumeDataStoreMap, VirtualMach } } + private MigrationOptions.Type decideMigrationTypeAndCopyTemplateIfNeeded(Host destHost, VMInstanceVO vmInstance, VolumeInfo srcVolumeInfo, StoragePoolVO sourceStoragePool, StoragePoolVO destStoragePool, DataStore destDataStore) { + VMTemplateVO vmTemplate = _vmTemplateDao.findById(vmInstance.getTemplateId()); + String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo); + if (StringUtils.isNotBlank(srcVolumeBackingFile) && supportStoragePoolType(destStoragePool.getPoolType(), StoragePoolType.Filesystem) && + srcVolumeInfo.getTemplateId() != null && + Objects.nonNull(vmTemplate) && + !Arrays.asList(KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME, VM_IMPORT_DEFAULT_TEMPLATE_NAME).contains(vmTemplate.getName())) { + logger.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId())); + copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost); + return MigrationOptions.Type.LinkedClone; + } + logger.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a " + + "template or we are doing full clone migration.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId())); + return MigrationOptions.Type.FullClone; + } + protected String formatMigrationElementsAsJsonToDisplayOnLog(String objectName, Object object, Object from, Object to){ return String.format("{%s: \"%s\", from: \"%s\", to:\"%s\"}", objectName, object, from, to); } @@ -2422,7 +2431,7 @@ protected void updateCopiedTemplateReference(VolumeInfo srcVolumeInfo, VolumeInf /** * Handle post destination volume creation actions depending on the migrating volume type: full clone or linked clone */ - protected void postVolumeCreationActions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, VirtualMachineTO vmTO, Host srcHost) { + protected void postVolumeCreationActions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) { MigrationOptions migrationOptions = destVolumeInfo.getMigrationOptions(); if (migrationOptions != null) { if (migrationOptions.getType() == MigrationOptions.Type.LinkedClone && migrationOptions.isCopySrcTemplate()) { diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java index 52a6b204ee81..0f6270a0593a 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java @@ -1400,22 +1400,39 @@ protected List addJoins(StringBuilder str, Collection, Integer> searchForUserVMIdsAndCount(ListVMsCmd cmd) { if (isRootAdmin) { userVmSearchBuilder.or("keywordInstanceName", userVmSearchBuilder.entity().getInstanceName(), Op.LIKE ); } + + SearchBuilder ipAddressSearch = ipAddressDao.createSearchBuilder(); + userVmSearchBuilder.join("ipAddressSearch", ipAddressSearch, + ipAddressSearch.entity().getAssociatedWithVmId(), userVmSearchBuilder.entity().getId(), JoinBuilder.JoinType.LEFT); + + SearchBuilder nicSearch = nicDao.createSearchBuilder(); + userVmSearchBuilder.join("nicSearch", nicSearch, JoinBuilder.JoinType.LEFT, + JoinBuilder.JoinCondition.AND, + nicSearch.entity().getInstanceId(), userVmSearchBuilder.entity().getId(), + nicSearch.entity().getRemoved(), userVmSearchBuilder.entity().setLong(null)); + + userVmSearchBuilder.or("ipAddressSearch", "keywordPublicIpAddress", ipAddressSearch.entity().getAddress(), Op.LIKE); + + userVmSearchBuilder.or("nicSearch", "keywordIpAddress", nicSearch.entity().getIPv4Address(), Op.LIKE); + userVmSearchBuilder.or("nicSearch", "keywordIp6Address", nicSearch.entity().getIPv6Address(), Op.LIKE); + userVmSearchBuilder.cp(); } @@ -1554,6 +1575,9 @@ private Pair, Integer> searchForUserVMIdsAndCount(ListVMsCmd cmd) { userVmSearchCriteria.setParameters("keywordDisplayName", keywordMatch); userVmSearchCriteria.setParameters("keywordName", keywordMatch); userVmSearchCriteria.setParameters("keywordState", keyword); + userVmSearchCriteria.setParameters("keywordIpAddress", keywordMatch); + userVmSearchCriteria.setParameters("keywordPublicIpAddress", keywordMatch); + userVmSearchCriteria.setParameters("keywordIp6Address", keywordMatch); if (isRootAdmin) { userVmSearchCriteria.setParameters("keywordInstanceName", keywordMatch); }