Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@
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();
Expand All @@ -546,7 +546,8 @@
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;
}
Expand All @@ -558,7 +559,8 @@
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;
}
Expand Down Expand Up @@ -621,7 +623,8 @@
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()));
}
Expand Down Expand Up @@ -858,7 +861,7 @@
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);

Expand Down Expand Up @@ -1612,7 +1615,7 @@

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();
Expand All @@ -1628,15 +1631,18 @@
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);
}

Expand Down Expand Up @@ -1726,9 +1732,9 @@
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();
Expand Down Expand Up @@ -1912,16 +1918,16 @@
}

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;
Expand All @@ -1932,16 +1938,17 @@
}

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);

Check warning on line 1951 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1951 was not covered by tests
ConvertInstanceCommand cmd = new ConvertInstanceCommand(remoteInstanceTO,
Hypervisor.HypervisorType.KVM, temporaryConvertLocation, null, false, true);
int timeoutSeconds = UnmanagedVMsManager.ConvertVmwareInstanceToKvmTimeout.value() * 60 * 60;
Expand Down Expand Up @@ -2004,12 +2011,31 @@
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);

Check warning on line 2023 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

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

Added line #L2023 was not covered by tests
if (diskOffering == null) {
String msg = String.format("Cannot find disk offering with ID %s", diskOfferingId);
LOGGER.error(msg);
throw new CloudRuntimeException(msg);

Check warning on line 2027 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java#L2025-L2027

Added lines #L2025 - L2027 were not covered by tests
}
diskOfferingTags.add(diskOffering.getTags());
}

Check warning on line 2030 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java#L2029-L2030

Added lines #L2029 - L2030 were not covered by tests
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);
Expand All @@ -2018,12 +2044,54 @@
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;

Check warning on line 2049 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

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

Added line #L2049 was not covered by tests
}
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);

Check warning on line 2063 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java#L2061-L2063

Added lines #L2061 - L2063 were not covered by tests
}
}
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());

Check warning on line 2085 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

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

Added line #L2085 was not covered by tests
} else {
DiskOfferingVO diskOffering = diskOfferingDao.findById(diskOfferingId);
for (StoragePoolVO pool : pools) {
if (volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOffering.getTags())) {
storagePools.set(disk.getPosition(), pool.getUuid());
break;
}
}
}

Check warning on line 2094 in server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java#L2093-L2094

Added lines #L2093 - L2094 were not covered by tests
}
return storagePools;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ public void setUp() throws Exception {
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");
Expand Down Expand Up @@ -423,6 +424,7 @@ public void importUnmanagedInstanceTest() {
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);
}
Expand Down Expand Up @@ -702,6 +704,8 @@ private void baseTestImportVmFromVmwareToKvm(VcenterParameter vcenterParameter,
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);
Expand Down
Loading