Skip to content

Commit 5e3c0f5

Browse files
committed
add checks for storage tags and fix ordering of destination storage pools
1 parent 8e473f3 commit 5e3c0f5

File tree

2 files changed

+72
-50
lines changed

2 files changed

+72
-50
lines changed

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ private void checkUnmanagedDiskAndOfferingForImport(String instanceName, Unmanag
623623
if (diskOffering != null && !diskOffering.isCustomized() && diskOffering.getDiskSize() < disk.getCapacity()) {
624624
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))));
625625
}
626+
diskOffering = diskOffering != null ? diskOffering : diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
626627
StoragePool storagePool = getStoragePool(disk, zone, cluster, diskOffering != null ? diskOffering.getTags() : null);
627628
if (diskOffering != null && !migrateAllowed && !storagePoolSupportsDiskOffering(storagePool, diskOffering)) {
628629
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()));
@@ -1614,7 +1615,7 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster
16141615

16151616
temporaryConvertLocation = selectInstanceConversionTemporaryLocation(
16161617
destinationCluster, convertHost, convertStoragePoolId);
1617-
List<StoragePoolVO> convertStoragePools = findInstanceConversionStoragePoolsInCluster(destinationCluster, dataDiskOfferingMap);
1618+
List<StoragePoolVO> convertStoragePools = findInstanceConversionStoragePoolsInCluster(destinationCluster, serviceOffering, dataDiskOfferingMap);
16181619
long importStartTime = System.currentTimeMillis();
16191620
Pair<UnmanagedInstanceTO, Boolean> sourceInstanceDetails = getSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password, clusterName, sourceHostName, sourceVMName);
16201621
sourceVMwareInstance = sourceInstanceDetails.first();
@@ -1630,17 +1631,19 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster
16301631
if (cmd.getForceMsToImportVmFiles() || !conversionSupportAnswer.isOvfExportSupported()) {
16311632
// Uses MS for OVF export to temporary conversion location
16321633
int noOfThreads = UnmanagedVMsManager.ThreadsOnMSToImportVMwareVMFiles.value();
1633-
ovfTemplateOnConvertLocation = createOvfTemplateOfSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password,
1634-
clusterName, sourceHostName, sourceVMwareInstance.getName(), temporaryConvertLocation, noOfThreads);
1634+
ovfTemplateOnConvertLocation = createOvfTemplateOfSourceVmwareUnmanagedInstance(
1635+
vcenter, datacenterName, username, password, clusterName, sourceHostName,
1636+
sourceVMwareInstance.getName(), temporaryConvertLocation, noOfThreads);
16351637
convertedInstance = convertVmwareInstanceToKVMWithOVFOnConvertLocation(sourceVMName,
16361638
sourceVMwareInstance, convertHost, importHost, convertStoragePools,
1637-
dataDiskOfferingMap, temporaryConvertLocation, ovfTemplateOnConvertLocation);
1639+
serviceOffering, dataDiskOfferingMap, temporaryConvertLocation,
1640+
ovfTemplateOnConvertLocation);
16381641
} else {
16391642
// Uses KVM Host for OVF export to temporary conversion location, through ovftool
16401643
convertedInstance = convertVmwareInstanceToKVMAfterExportingOVFToConvertLocation(
16411644
sourceVMName, sourceVMwareInstance, convertHost, importHost,
1642-
convertStoragePools, dataDiskOfferingMap, temporaryConvertLocation, vcenter,
1643-
username, password, datacenterName);
1645+
convertStoragePools, serviceOffering, dataDiskOfferingMap,
1646+
temporaryConvertLocation, vcenter, username, password, datacenterName);
16441647
}
16451648

16461649
sanitizeConvertedInstance(convertedInstance, sourceVMwareInstance);
@@ -1729,9 +1732,9 @@ private void sanitizeConvertedInstance(UnmanagedInstanceTO convertedInstance, Un
17291732
convertedInstance.setPowerState(UnmanagedInstanceTO.PowerState.PowerOff);
17301733
List<UnmanagedInstanceTO.Disk> convertedInstanceDisks = convertedInstance.getDisks();
17311734
List<UnmanagedInstanceTO.Disk> sourceVMwareInstanceDisks = sourceVMwareInstance.getDisks();
1732-
for (int i = 0; i < convertedInstanceDisks.size(); i++) {
1733-
UnmanagedInstanceTO.Disk disk = convertedInstanceDisks.get(i);
1734-
disk.setDiskId(sourceVMwareInstanceDisks.get(i).getDiskId());
1735+
for (UnmanagedInstanceTO.Disk sourceVMwareInstanceDisk : sourceVMwareInstanceDisks) {
1736+
UnmanagedInstanceTO.Disk convertedDisk = convertedInstanceDisks.get(sourceVMwareInstanceDisk.getPosition());
1737+
convertedDisk.setDiskId(sourceVMwareInstanceDisk.getDiskId());
17351738
}
17361739
List<UnmanagedInstanceTO.Nic> convertedInstanceNics = convertedInstance.getNics();
17371740
List<UnmanagedInstanceTO.Nic> sourceVMwareInstanceNics = sourceVMwareInstance.getNics();
@@ -1915,16 +1918,16 @@ private CheckConvertInstanceAnswer checkConversionSupportOnHost(HostVO convertHo
19151918
}
19161919

19171920
private UnmanagedInstanceTO convertVmwareInstanceToKVMWithOVFOnConvertLocation(
1918-
String sourceVM, UnmanagedInstanceTO sourceVMwareInstance,
1919-
HostVO convertHost, HostVO importHost,
1920-
List<StoragePoolVO> convertStoragePools, Map<String, Long> dataDiskOfferingMap, DataStoreTO temporaryConvertLocation,
1921-
String ovfTemplateDirConvertLocation
1921+
String sourceVM, UnmanagedInstanceTO sourceVMwareInstance, HostVO convertHost,
1922+
HostVO importHost, List<StoragePoolVO> convertStoragePools,
1923+
ServiceOfferingVO serviceOffering, Map<String, Long> dataDiskOfferingMap,
1924+
DataStoreTO temporaryConvertLocation, String ovfTemplateDirConvertLocation
19221925
) {
19231926
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",
19241927
sourceVM, convertHost.getId(), convertHost.getName(), ovfTemplateDirConvertLocation));
19251928

19261929
RemoteInstanceTO remoteInstanceTO = new RemoteInstanceTO(sourceVM);
1927-
List<String> destinationStoragePools = selectInstanceConversionStoragePools(convertStoragePools, sourceVMwareInstance.getDisks(), dataDiskOfferingMap);
1930+
List<String> destinationStoragePools = selectInstanceConversionStoragePools(convertStoragePools, sourceVMwareInstance.getDisks(), serviceOffering, dataDiskOfferingMap);
19281931
ConvertInstanceCommand cmd = new ConvertInstanceCommand(remoteInstanceTO,
19291932
Hypervisor.HypervisorType.KVM, temporaryConvertLocation, ovfTemplateDirConvertLocation, false, false);
19301933
int timeoutSeconds = UnmanagedVMsManager.ConvertVmwareInstanceToKvmTimeout.value() * 60 * 60;
@@ -1935,16 +1938,17 @@ private UnmanagedInstanceTO convertVmwareInstanceToKVMWithOVFOnConvertLocation(
19351938
}
19361939

19371940
private UnmanagedInstanceTO convertVmwareInstanceToKVMAfterExportingOVFToConvertLocation(
1938-
String sourceVM, UnmanagedInstanceTO sourceVMwareInstance,
1939-
HostVO convertHost, HostVO importHost, List<StoragePoolVO> convertStoragePools,
1940-
Map<String, Long> dataDiskOfferingMap, DataStoreTO temporaryConvertLocation, String vcenterHost,
1941-
String vcenterUsername, String vcenterPassword, String datacenterName
1941+
String sourceVM, UnmanagedInstanceTO sourceVMwareInstance, HostVO convertHost,
1942+
HostVO importHost, List<StoragePoolVO> convertStoragePools,
1943+
ServiceOfferingVO serviceOffering, Map<String, Long> dataDiskOfferingMap,
1944+
DataStoreTO temporaryConvertLocation, String vcenterHost, String vcenterUsername,
1945+
String vcenterPassword, String datacenterName
19421946
) {
19431947
LOGGER.debug(String.format("Delegating the conversion of instance %s from VMware to KVM to the host %s (%s) after OVF export through ovftool",
19441948
sourceVM, convertHost.getId(), convertHost.getName()));
19451949

19461950
RemoteInstanceTO remoteInstanceTO = new RemoteInstanceTO(sourceVMwareInstance.getName(), vcenterHost, vcenterUsername, vcenterPassword, datacenterName);
1947-
List<String> destinationStoragePools = selectInstanceConversionStoragePools(convertStoragePools, sourceVMwareInstance.getDisks(), dataDiskOfferingMap);
1951+
List<String> destinationStoragePools = selectInstanceConversionStoragePools(convertStoragePools, sourceVMwareInstance.getDisks(), serviceOffering, dataDiskOfferingMap);
19481952
ConvertInstanceCommand cmd = new ConvertInstanceCommand(remoteInstanceTO,
19491953
Hypervisor.HypervisorType.KVM, temporaryConvertLocation, null, false, true);
19501954
int timeoutSeconds = UnmanagedVMsManager.ConvertVmwareInstanceToKvmTimeout.value() * 60 * 60;
@@ -2007,10 +2011,13 @@ private UnmanagedInstanceTO convertAndImportToKVM(ConvertInstanceCommand convert
20072011
return ((ImportConvertedInstanceAnswer) importAnswer).getConvertedInstance();
20082012
}
20092013

2010-
private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(Cluster destinationCluster, Map<String, Long> dataDiskOfferingMap) {
2014+
private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
2015+
Cluster destinationCluster, ServiceOfferingVO serviceOffering,
2016+
Map<String, Long> dataDiskOfferingMap
2017+
) {
20112018
List<StoragePoolVO> pools = new ArrayList<>();
2012-
List<StoragePoolVO> clusterPools = primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem);
2013-
List<StoragePoolVO> zonePools = primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem);
2019+
pools.addAll(primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
2020+
pools.addAll(primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
20142021
List<String> diskOfferingTags = new ArrayList<>();
20152022
for (Long diskOfferingId : dataDiskOfferingMap.values()) {
20162023
DiskOfferingVO diskOffering = diskOfferingDao.findById(diskOfferingId);
@@ -2021,32 +2028,14 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(Cluster
20212028
}
20222029
diskOfferingTags.add(diskOffering.getTags());
20232030
}
2024-
if (dataDiskOfferingMap.isEmpty()) {
2025-
pools.addAll(clusterPools);
2026-
pools.addAll(zonePools);
2027-
} else {
2028-
for (String tags : diskOfferingTags) {
2029-
boolean tagsMatched = false;
2030-
for (StoragePoolVO pool : clusterPools) {
2031-
if (volumeApiService.doesTargetStorageSupportDiskOffering(pool, tags)) {
2032-
pools.add(pool);
2033-
tagsMatched = true;
2034-
}
2035-
}
2036-
for (StoragePoolVO pool : zonePools) {
2037-
if (volumeApiService.doesTargetStorageSupportDiskOffering(pool, tags)) {
2038-
pools.add(pool);
2039-
tagsMatched = true;
2040-
}
2041-
}
2042-
if (!tagsMatched) {
2043-
String msg = String.format("Cannot find suitable storage pools in cluster %s for the conversion with disk offering tags %s",
2044-
destinationCluster, tags);
2045-
LOGGER.error(msg);
2046-
throw new CloudRuntimeException(msg);
2047-
}
2031+
if (serviceOffering.getDiskOfferingId() != null) {
2032+
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
2033+
if (diskOffering != null) {
2034+
diskOfferingTags.add(diskOffering.getTags());
20482035
}
20492036
}
2037+
2038+
pools = getPoolsWithMatchingTags(pools, diskOfferingTags);
20502039
if (pools.isEmpty()) {
20512040
String msg = String.format("Cannot find suitable storage pools in cluster %s for the conversion", destinationCluster.getName());
20522041
LOGGER.error(msg);
@@ -2055,18 +2044,50 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(Cluster
20552044
return pools;
20562045
}
20572046

2058-
private List<String> selectInstanceConversionStoragePools(List<StoragePoolVO> pools, List<UnmanagedInstanceTO.Disk> disks, Map<String, Long> dataDiskOfferingMap) {
2047+
private List<StoragePoolVO> getPoolsWithMatchingTags(List<StoragePoolVO> pools, List<String> diskOfferingTags) {
2048+
if (diskOfferingTags.isEmpty()) {
2049+
return pools;
2050+
}
2051+
List<StoragePoolVO> poolsSupportingTags = new ArrayList<>(pools);
2052+
for (String tags : diskOfferingTags) {
2053+
boolean tagsMatched = false;
2054+
for (StoragePoolVO pool : pools) {
2055+
if (volumeApiService.doesTargetStorageSupportDiskOffering(pool, tags)) {
2056+
poolsSupportingTags.add(pool);
2057+
tagsMatched = true;
2058+
}
2059+
}
2060+
if (!tagsMatched) {
2061+
String msg = String.format("Cannot find suitable storage pools for the conversion with disk offering tags %s", tags);
2062+
LOGGER.error(msg);
2063+
throw new CloudRuntimeException(msg);
2064+
}
2065+
}
2066+
return poolsSupportingTags;
2067+
}
2068+
2069+
private List<String> selectInstanceConversionStoragePools(
2070+
List<StoragePoolVO> pools, List<UnmanagedInstanceTO.Disk> disks,
2071+
ServiceOfferingVO serviceOffering, Map<String, Long> dataDiskOfferingMap
2072+
) {
20592073
List<String> storagePools = new ArrayList<>(disks.size());
2060-
//TODO: Choose pools by capacity
2074+
for (int i = 0; i < disks.size(); i++) {
2075+
storagePools.add(null);
2076+
}
2077+
Set<String> dataDiskIds = dataDiskOfferingMap.keySet();
20612078
for (UnmanagedInstanceTO.Disk disk : disks) {
20622079
Long diskOfferingId = dataDiskOfferingMap.get(disk.getDiskId());
2080+
if (diskOfferingId == null && !dataDiskIds.contains(disk.getDiskId())) {
2081+
diskOfferingId = serviceOffering.getDiskOfferingId();
2082+
}
2083+
//TODO: Choose pools by capacity
20632084
if (diskOfferingId == null) {
2064-
storagePools.add(pools.get(0).getUuid());
2085+
storagePools.set(disk.getPosition(), pools.get(0).getUuid());
20652086
} else {
20662087
DiskOfferingVO diskOffering = diskOfferingDao.findById(diskOfferingId);
20672088
for (StoragePoolVO pool : pools) {
20682089
if (volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOffering.getTags())) {
2069-
storagePools.add(pool.getUuid());
2090+
storagePools.set(disk.getPosition(), pool.getUuid());
20702091
break;
20712092
}
20722093
}

server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ public void setUp() throws Exception {
277277
List<UnmanagedInstanceTO.Disk> instanceDisks = new ArrayList<>();
278278
UnmanagedInstanceTO.Disk instanceDisk = new UnmanagedInstanceTO.Disk();
279279
instanceDisk.setDiskId("1000-1");
280+
instanceDisk.setPosition(0);
280281
instanceDisk.setLabel("DiskLabel");
281282
instanceDisk.setController("scsi");
282283
instanceDisk.setImagePath("[b6ccf44a1fa13e29b3667b4954fa10ee] TestInstance/ROOT-1.vmdk");

0 commit comments

Comments
 (0)