This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.19 by this push:
     new d8c321d57ae check tags while fetching storage pool for importing vm 
(#9764)
d8c321d57ae is described below

commit d8c321d57aec526241939dae8553301140142c73
Author: Vishesh <vishes...@gmail.com>
AuthorDate: Fri Jan 3 13:35:54 2025 +0530

    check tags while fetching storage pool for importing vm (#9764)
---
 .../cloudstack/vm/UnmanagedVMsManagerImpl.java     | 134 ++++++++++++++++-----
 .../cloudstack/vm/UnmanagedVMsManagerImplTest.java |   4 +
 2 files changed, 105 insertions(+), 33 deletions(-)

diff --git 
a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java 
b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
index 67139120fa0..187afece84f 100644
--- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
@@ -536,7 +536,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         return nicIpAddresses;
     }
 
-    private StoragePool getStoragePool(final UnmanagedInstanceTO.Disk disk, 
final DataCenter zone, final Cluster cluster) {
+    private StoragePool getStoragePool(final UnmanagedInstanceTO.Disk disk, 
final DataCenter zone, final Cluster cluster, String diskOfferingTags) {
         StoragePool storagePool = null;
         final String dsHost = disk.getDatastoreHost();
         final String dsPath = disk.getDatastorePath();
@@ -546,7 +546,8 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
             List<StoragePoolVO> pools = 
primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath);
             for (StoragePool pool : pools) {
                 if (pool.getDataCenterId() == zone.getId() &&
-                        (pool.getClusterId() == null || 
pool.getClusterId().equals(cluster.getId()))) {
+                        (pool.getClusterId() == null || 
pool.getClusterId().equals(cluster.getId())) &&
+                        
volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) {
                     storagePool = pool;
                     break;
                 }
@@ -558,7 +559,8 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
             pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId()));
             for (StoragePool pool : pools) {
                 String searchPoolParam = StringUtils.isNotBlank(dsPath) ? 
dsPath : dsName;
-                if (StringUtils.contains(pool.getPath(), searchPoolParam)) {
+                if (StringUtils.contains(pool.getPath(), searchPoolParam) &&
+                        
volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOfferingTags)) {
                     storagePool = pool;
                     break;
                 }
@@ -621,7 +623,8 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         if (diskOffering != null && !diskOffering.isCustomized() && 
diskOffering.getDiskSize() < disk.getCapacity()) {
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, 
String.format("Size of disk offering(ID: %s) %dGB is found less than the size 
of disk(ID: %s) %dGB during VM import", diskOffering.getUuid(), 
(diskOffering.getDiskSize() / Resource.ResourceType.bytesToGiB), 
disk.getDiskId(), (disk.getCapacity() / (Resource.ResourceType.bytesToGiB))));
         }
-        StoragePool storagePool = getStoragePool(disk, zone, cluster);
+        diskOffering = diskOffering != null ? diskOffering : 
diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
+        StoragePool storagePool = getStoragePool(disk, zone, cluster, 
diskOffering != null ? diskOffering.getTags() : null);
         if (diskOffering != null && !migrateAllowed && 
!storagePoolSupportsDiskOffering(storagePool, diskOffering)) {
             throw new InvalidParameterValueException(String.format("Disk 
offering: %s is not compatible with storage pool: %s of unmanaged disk: %s", 
diskOffering.getUuid(), storagePool.getUuid(), disk.getDiskId()));
         }
@@ -858,7 +861,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
             diskInfo.setDiskChain(new String[]{disk.getImagePath()});
             chainInfo = gson.toJson(diskInfo);
         }
-        StoragePool storagePool = getStoragePool(disk, zone, cluster);
+        StoragePool storagePool = getStoragePool(disk, zone, cluster, 
diskOffering != null ? diskOffering.getTags() : null);
         DiskProfile profile = volumeManager.importVolume(type, name, 
diskOffering, diskSize,
                 minIops, maxIops, vm.getDataCenterId(), 
vm.getHypervisorType(), vm, template, owner, deviceId, storagePool.getId(), 
path, chainInfo);
 
@@ -1612,7 +1615,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
 
             temporaryConvertLocation = 
selectInstanceConversionTemporaryLocation(
                     destinationCluster, convertHost, convertStoragePoolId);
-            List<StoragePoolVO> convertStoragePools = 
findInstanceConversionStoragePoolsInCluster(destinationCluster);
+            List<StoragePoolVO> convertStoragePools = 
findInstanceConversionStoragePoolsInCluster(destinationCluster, 
serviceOffering, dataDiskOfferingMap);
             long importStartTime = System.currentTimeMillis();
             Pair<UnmanagedInstanceTO, Boolean> sourceInstanceDetails = 
getSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password, 
clusterName, sourceHostName, sourceVMName);
             sourceVMwareInstance = sourceInstanceDetails.first();
@@ -1628,15 +1631,18 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
             if (cmd.getForceMsToImportVmFiles() || 
!conversionSupportAnswer.isOvfExportSupported()) {
                 // Uses MS for OVF export to temporary conversion location
                 int noOfThreads = 
UnmanagedVMsManager.ThreadsOnMSToImportVMwareVMFiles.value();
-                ovfTemplateOnConvertLocation = 
createOvfTemplateOfSourceVmwareUnmanagedInstance(vcenter, datacenterName, 
username, password,
-                        clusterName, sourceHostName, 
sourceVMwareInstance.getName(), temporaryConvertLocation, noOfThreads);
+                ovfTemplateOnConvertLocation = 
createOvfTemplateOfSourceVmwareUnmanagedInstance(
+                        vcenter, datacenterName, username, password, 
clusterName, sourceHostName,
+                        sourceVMwareInstance.getName(), 
temporaryConvertLocation, noOfThreads);
                 convertedInstance = 
convertVmwareInstanceToKVMWithOVFOnConvertLocation(sourceVMName,
-                                sourceVMwareInstance, convertHost, importHost, 
convertStoragePools,
-                        temporaryConvertLocation, 
ovfTemplateOnConvertLocation);
+                        sourceVMwareInstance, convertHost, importHost, 
convertStoragePools,
+                        serviceOffering, dataDiskOfferingMap, 
temporaryConvertLocation,
+                        ovfTemplateOnConvertLocation);
             } else {
                 // Uses KVM Host for OVF export to temporary conversion 
location, through ovftool
                 convertedInstance = 
convertVmwareInstanceToKVMAfterExportingOVFToConvertLocation(
-                        sourceVMName, sourceVMwareInstance, convertHost, 
importHost, convertStoragePools,
+                        sourceVMName, sourceVMwareInstance, convertHost, 
importHost,
+                        convertStoragePools, serviceOffering, 
dataDiskOfferingMap,
                         temporaryConvertLocation, vcenter, username, password, 
datacenterName);
             }
 
@@ -1726,9 +1732,9 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         
convertedInstance.setPowerState(UnmanagedInstanceTO.PowerState.PowerOff);
         List<UnmanagedInstanceTO.Disk> convertedInstanceDisks = 
convertedInstance.getDisks();
         List<UnmanagedInstanceTO.Disk> sourceVMwareInstanceDisks = 
sourceVMwareInstance.getDisks();
-        for (int i = 0; i < convertedInstanceDisks.size(); i++) {
-            UnmanagedInstanceTO.Disk disk = convertedInstanceDisks.get(i);
-            disk.setDiskId(sourceVMwareInstanceDisks.get(i).getDiskId());
+        for (UnmanagedInstanceTO.Disk sourceVMwareInstanceDisk : 
sourceVMwareInstanceDisks) {
+            UnmanagedInstanceTO.Disk convertedDisk = 
convertedInstanceDisks.get(sourceVMwareInstanceDisk.getPosition());
+            convertedDisk.setDiskId(sourceVMwareInstanceDisk.getDiskId());
         }
         List<UnmanagedInstanceTO.Nic> convertedInstanceNics = 
convertedInstance.getNics();
         List<UnmanagedInstanceTO.Nic> sourceVMwareInstanceNics = 
sourceVMwareInstance.getNics();
@@ -1912,16 +1918,16 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
     }
 
     private UnmanagedInstanceTO 
convertVmwareInstanceToKVMWithOVFOnConvertLocation(
-            String sourceVM, UnmanagedInstanceTO sourceVMwareInstance,
-            HostVO convertHost, HostVO importHost,
-            List<StoragePoolVO> convertStoragePools, DataStoreTO 
temporaryConvertLocation,
-            String ovfTemplateDirConvertLocation
+            String sourceVM, UnmanagedInstanceTO sourceVMwareInstance, HostVO 
convertHost,
+            HostVO importHost, List<StoragePoolVO> convertStoragePools,
+            ServiceOfferingVO serviceOffering, Map<String, Long> 
dataDiskOfferingMap,
+            DataStoreTO temporaryConvertLocation, String 
ovfTemplateDirConvertLocation
     ) {
         LOGGER.debug(String.format("Delegating the conversion of instance %s 
from VMware to KVM to the host %s (%s) using OVF %s on conversion datastore",
                 sourceVM, convertHost.getId(), convertHost.getName(), 
ovfTemplateDirConvertLocation));
 
         RemoteInstanceTO remoteInstanceTO = new RemoteInstanceTO(sourceVM);
-        List<String> destinationStoragePools = 
selectInstanceConversionStoragePools(convertStoragePools, 
sourceVMwareInstance.getDisks());
+        List<String> destinationStoragePools = 
selectInstanceConversionStoragePools(convertStoragePools, 
sourceVMwareInstance.getDisks(), serviceOffering, dataDiskOfferingMap);
         ConvertInstanceCommand cmd = new 
ConvertInstanceCommand(remoteInstanceTO,
                 Hypervisor.HypervisorType.KVM, temporaryConvertLocation, 
ovfTemplateDirConvertLocation, false, false);
         int timeoutSeconds = 
UnmanagedVMsManager.ConvertVmwareInstanceToKvmTimeout.value() * 60 * 60;
@@ -1932,16 +1938,17 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
     }
 
     private UnmanagedInstanceTO 
convertVmwareInstanceToKVMAfterExportingOVFToConvertLocation(
-            String sourceVM, UnmanagedInstanceTO sourceVMwareInstance,
-            HostVO convertHost, HostVO importHost, List<StoragePoolVO> 
convertStoragePools,
-            DataStoreTO temporaryConvertLocation, String vcenterHost,
-            String vcenterUsername, String vcenterPassword, String 
datacenterName
+            String sourceVM, UnmanagedInstanceTO sourceVMwareInstance, HostVO 
convertHost,
+            HostVO importHost, List<StoragePoolVO> convertStoragePools,
+            ServiceOfferingVO serviceOffering, Map<String, Long> 
dataDiskOfferingMap,
+            DataStoreTO temporaryConvertLocation, String vcenterHost, String 
vcenterUsername,
+            String vcenterPassword, String datacenterName
     ) {
         LOGGER.debug(String.format("Delegating the conversion of instance %s 
from VMware to KVM to the host %s (%s) after OVF export through ovftool",
                 sourceVM, convertHost.getId(), convertHost.getName()));
 
         RemoteInstanceTO remoteInstanceTO = new 
RemoteInstanceTO(sourceVMwareInstance.getName(), vcenterHost, vcenterUsername, 
vcenterPassword, datacenterName);
-        List<String> destinationStoragePools = 
selectInstanceConversionStoragePools(convertStoragePools, 
sourceVMwareInstance.getDisks());
+        List<String> destinationStoragePools = 
selectInstanceConversionStoragePools(convertStoragePools, 
sourceVMwareInstance.getDisks(), serviceOffering, dataDiskOfferingMap);
         ConvertInstanceCommand cmd = new 
ConvertInstanceCommand(remoteInstanceTO,
                 Hypervisor.HypervisorType.KVM, temporaryConvertLocation, null, 
false, true);
         int timeoutSeconds = 
UnmanagedVMsManager.ConvertVmwareInstanceToKvmTimeout.value() * 60 * 60;
@@ -2004,12 +2011,31 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         return ((ImportConvertedInstanceAnswer) 
importAnswer).getConvertedInstance();
     }
 
-    private List<StoragePoolVO> 
findInstanceConversionStoragePoolsInCluster(Cluster destinationCluster) {
+    private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
+            Cluster destinationCluster, ServiceOfferingVO serviceOffering,
+            Map<String, Long> dataDiskOfferingMap
+    ) {
         List<StoragePoolVO> pools = new ArrayList<>();
-        List<StoragePoolVO> clusterPools = 
primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(),
 Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem);
-        pools.addAll(clusterPools);
-        List<StoragePoolVO> zonePools = 
primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(),
 Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem);
-        pools.addAll(zonePools);
+        
pools.addAll(primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(),
 Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
+        
pools.addAll(primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(),
 Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
+        List<String> diskOfferingTags = new ArrayList<>();
+        for (Long diskOfferingId : dataDiskOfferingMap.values()) {
+            DiskOfferingVO diskOffering = 
diskOfferingDao.findById(diskOfferingId);
+            if (diskOffering == null) {
+                String msg = String.format("Cannot find disk offering with ID 
%s", diskOfferingId);
+                LOGGER.error(msg);
+                throw new CloudRuntimeException(msg);
+            }
+            diskOfferingTags.add(diskOffering.getTags());
+        }
+        if (serviceOffering.getDiskOfferingId() != null) {
+            DiskOfferingVO diskOffering = 
diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
+            if (diskOffering != null) {
+                diskOfferingTags.add(diskOffering.getTags());
+            }
+        }
+
+        pools = getPoolsWithMatchingTags(pools, diskOfferingTags);
         if (pools.isEmpty()) {
             String msg = String.format("Cannot find suitable storage pools in 
cluster %s for the conversion", destinationCluster.getName());
             LOGGER.error(msg);
@@ -2018,12 +2044,54 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         return pools;
     }
 
-    private List<String> 
selectInstanceConversionStoragePools(List<StoragePoolVO> pools, 
List<UnmanagedInstanceTO.Disk> disks) {
+    private List<StoragePoolVO> getPoolsWithMatchingTags(List<StoragePoolVO> 
pools, List<String> diskOfferingTags) {
+        if (diskOfferingTags.isEmpty()) {
+            return pools;
+        }
+        List<StoragePoolVO> poolsSupportingTags = new ArrayList<>(pools);
+        for (String tags : diskOfferingTags) {
+            boolean tagsMatched = false;
+            for (StoragePoolVO pool : pools) {
+                if 
(volumeApiService.doesTargetStorageSupportDiskOffering(pool, tags)) {
+                    poolsSupportingTags.add(pool);
+                    tagsMatched = true;
+                }
+            }
+            if (!tagsMatched) {
+                String msg = String.format("Cannot find suitable storage pools 
for the conversion with disk offering tags %s", tags);
+                LOGGER.error(msg);
+                throw new CloudRuntimeException(msg);
+            }
+        }
+        return poolsSupportingTags;
+    }
+
+    private List<String> selectInstanceConversionStoragePools(
+            List<StoragePoolVO> pools, List<UnmanagedInstanceTO.Disk> disks,
+            ServiceOfferingVO serviceOffering, Map<String, Long> 
dataDiskOfferingMap
+    ) {
         List<String> storagePools = new ArrayList<>(disks.size());
-        //TODO: Choose pools by capacity
+        for (int i = 0; i < disks.size(); i++) {
+            storagePools.add(null);
+        }
+        Set<String> dataDiskIds = dataDiskOfferingMap.keySet();
         for (UnmanagedInstanceTO.Disk disk : disks) {
-            Long capacity = disk.getCapacity();
-            storagePools.add(pools.get(0).getUuid());
+            Long diskOfferingId = dataDiskOfferingMap.get(disk.getDiskId());
+            if (diskOfferingId == null && 
!dataDiskIds.contains(disk.getDiskId())) {
+                diskOfferingId = serviceOffering.getDiskOfferingId();
+            }
+            //TODO: Choose pools by capacity
+            if (diskOfferingId == null) {
+                storagePools.set(disk.getPosition(), pools.get(0).getUuid());
+            } else {
+                DiskOfferingVO diskOffering = 
diskOfferingDao.findById(diskOfferingId);
+                for (StoragePoolVO pool : pools) {
+                    if 
(volumeApiService.doesTargetStorageSupportDiskOffering(pool, 
diskOffering.getTags())) {
+                        storagePools.set(disk.getPosition(), pool.getUuid());
+                        break;
+                    }
+                }
+            }
         }
         return storagePools;
     }
diff --git 
a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java
 
b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java
index e9a58760828..85402c0e254 100644
--- 
a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java
+++ 
b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java
@@ -277,6 +277,7 @@ public class UnmanagedVMsManagerImplTest {
         List<UnmanagedInstanceTO.Disk> instanceDisks = new ArrayList<>();
         UnmanagedInstanceTO.Disk instanceDisk = new UnmanagedInstanceTO.Disk();
         instanceDisk.setDiskId("1000-1");
+        instanceDisk.setPosition(0);
         instanceDisk.setLabel("DiskLabel");
         instanceDisk.setController("scsi");
         instanceDisk.setImagePath("[b6ccf44a1fa13e29b3667b4954fa10ee] 
TestInstance/ROOT-1.vmdk");
@@ -423,6 +424,7 @@ public class UnmanagedVMsManagerImplTest {
         ImportUnmanagedInstanceCmd importUnmanageInstanceCmd = 
Mockito.mock(ImportUnmanagedInstanceCmd.class);
         when(importUnmanageInstanceCmd.getName()).thenReturn("TestInstance");
         when(importUnmanageInstanceCmd.getDomainId()).thenReturn(null);
+        
when(volumeApiService.doesTargetStorageSupportDiskOffering(any(StoragePool.class),
 any())).thenReturn(true);
         try (MockedStatic<UsageEventUtils> ignored = 
Mockito.mockStatic(UsageEventUtils.class)) {
             
unmanagedVMsManager.importUnmanagedInstance(importUnmanageInstanceCmd);
         }
@@ -702,6 +704,8 @@ public class UnmanagedVMsManagerImplTest {
             when(agentManager.send(Mockito.eq(convertHostId), 
Mockito.any(CheckConvertInstanceCommand.class))).thenReturn(checkConvertInstanceAnswer);
         }
 
+        
when(volumeApiService.doesTargetStorageSupportDiskOffering(any(StoragePool.class),
 any())).thenReturn(true);
+
         ConvertInstanceAnswer convertInstanceAnswer = 
mock(ConvertInstanceAnswer.class);
         ImportConvertedInstanceAnswer convertImportedInstanceAnswer = 
mock(ImportConvertedInstanceAnswer.class);
         when(convertInstanceAnswer.getResult()).thenReturn(vcenterParameter != 
VcenterParameter.CONVERT_FAILURE);

Reply via email to