Skip to content

Commit 2c52bfa

Browse files
committed
Support Local storage when forceconverttopool is set to true
1 parent 0638763 commit 2c52bfa

File tree

2 files changed

+84
-53
lines changed

2 files changed

+84
-53
lines changed

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

Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,15 @@
176176
import org.apache.commons.collections.CollectionUtils;
177177
import org.apache.commons.collections.MapUtils;
178178
import org.apache.commons.lang3.BooleanUtils;
179+
import org.apache.commons.lang3.ObjectUtils;
179180
import org.apache.commons.lang3.StringUtils;
180181
import org.apache.logging.log4j.LogManager;
181182
import org.apache.logging.log4j.Logger;
182183

183184
import javax.inject.Inject;
184185
import java.util.ArrayList;
185186
import java.util.Arrays;
187+
import java.util.Collections;
186188
import java.util.HashMap;
187189
import java.util.HashSet;
188190
import java.util.LinkedHashMap;
@@ -1689,8 +1691,9 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster
16891691
"instance {} from VMware to KVM ", convertHost, sourceVMName);
16901692

16911693
temporaryConvertLocation = selectInstanceConversionTemporaryLocation(
1692-
destinationCluster, convertHost, convertStoragePoolId, forceConvertToPool);
1693-
List<StoragePoolVO> convertStoragePools = findInstanceConversionStoragePoolsInCluster(destinationCluster, serviceOffering, dataDiskOfferingMap);
1694+
destinationCluster, convertHost, importHost, convertStoragePoolId, forceConvertToPool);
1695+
List<StoragePoolVO> convertStoragePools = findInstanceConversionDestinationStoragePoolsInCluster(destinationCluster, serviceOffering, dataDiskOfferingMap, temporaryConvertLocation, forceConvertToPool);
1696+
16941697
long importStartTime = System.currentTimeMillis();
16951698
importVMTask = importVmTasksManager.createImportVMTaskRecord(zone, owner, userId, displayName, vcenter, datacenterName, sourceVMName,
16961699
convertHost, importHost);
@@ -2119,17 +2122,23 @@ private UnmanagedInstanceTO convertAndImportToKVM(ConvertInstanceCommand convert
21192122
return ((ImportConvertedInstanceAnswer) importAnswer).getConvertedInstance();
21202123
}
21212124

2122-
private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
2125+
private List<StoragePoolVO> findInstanceConversionDestinationStoragePoolsInCluster(
21232126
Cluster destinationCluster, ServiceOfferingVO serviceOffering,
2124-
Map<String, Long> dataDiskOfferingMap
2125-
) {
2126-
List<StoragePoolVO> pools = new ArrayList<>();
2127-
pools.addAll(primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
2128-
pools.addAll(primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
2129-
if (pools.isEmpty()) {
2130-
String msg = String.format("Cannot find suitable storage pools in the cluster %s for the conversion", destinationCluster.getName());
2131-
logger.error(msg);
2132-
throw new CloudRuntimeException(msg);
2127+
Map<String, Long> dataDiskOfferingMap,
2128+
DataStoreTO temporaryConvertLocation, boolean forceConvertToPool) {
2129+
List<StoragePoolVO> poolsList;
2130+
if (!forceConvertToPool) {
2131+
Set<StoragePoolVO> pools = new HashSet<>(primaryDataStoreDao.findClusterWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
2132+
pools.addAll(primaryDataStoreDao.findZoneWideStoragePoolsByHypervisorAndPoolType(destinationCluster.getDataCenterId(), Hypervisor.HypervisorType.KVM, Storage.StoragePoolType.NetworkFilesystem));
2133+
if (pools.isEmpty()) {
2134+
String msg = String.format("Cannot find suitable storage pools in the cluster %s for the conversion", destinationCluster.getName());
2135+
logger.error(msg);
2136+
throw new CloudRuntimeException(msg);
2137+
}
2138+
poolsList = new ArrayList<>(pools);
2139+
} else {
2140+
DataStore dataStore = dataStoreManager.getDataStore(temporaryConvertLocation.getUuid(), temporaryConvertLocation.getRole());
2141+
poolsList = Collections.singletonList(primaryDataStoreDao.findById(dataStore.getId()));
21332142
}
21342143

21352144
if (serviceOffering.getDiskOfferingId() != null) {
@@ -2139,7 +2148,7 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
21392148
logger.error(msg);
21402149
throw new CloudRuntimeException(msg);
21412150
}
2142-
if (getStoragePoolWithTags(pools, diskOffering.getTags()) == null) {
2151+
if (getStoragePoolWithTags(poolsList, diskOffering.getTags()) == null) {
21432152
String msg = String.format("Cannot find suitable storage pool for disk offering %s that belongs to the service offering %s", diskOffering.getName(), serviceOffering.getName());
21442153
logger.error(msg);
21452154
throw new CloudRuntimeException(msg);
@@ -2152,14 +2161,14 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
21522161
logger.error(msg);
21532162
throw new CloudRuntimeException(msg);
21542163
}
2155-
if (getStoragePoolWithTags(pools, diskOffering.getTags()) == null) {
2164+
if (getStoragePoolWithTags(poolsList, diskOffering.getTags()) == null) {
21562165
String msg = String.format("Cannot find suitable storage pool for disk offering %s", diskOffering.getName());
21572166
logger.error(msg);
21582167
throw new CloudRuntimeException(msg);
21592168
}
21602169
}
21612170

2162-
return pools;
2171+
return poolsList;
21632172
}
21642173

21652174
private StoragePoolVO getStoragePoolWithTags(List<StoragePoolVO> pools, String tags) {
@@ -2205,41 +2214,63 @@ private void logFailureAndThrowException(String msg) {
22052214
throw new CloudRuntimeException(msg);
22062215
}
22072216

2217+
private void checkBeforeSelectingTemporaryConversionStoragePool(StoragePoolVO selectedStoragePool, Long convertStoragePoolId, Cluster destinationCluster, HostVO convertHost) {
2218+
if (selectedStoragePool == null) {
2219+
logFailureAndThrowException(String.format("Cannot find a storage pool with ID %s", convertStoragePoolId));
2220+
}
2221+
if ((selectedStoragePool.getScope() == ScopeType.CLUSTER && selectedStoragePool.getClusterId() != destinationCluster.getId()) ||
2222+
(selectedStoragePool.getScope() == ScopeType.ZONE && selectedStoragePool.getDataCenterId() != destinationCluster.getDataCenterId())) {
2223+
logFailureAndThrowException(String.format("Cannot use the storage pool %s for the instance conversion as " +
2224+
"it is not in the scope of the cluster %s", selectedStoragePool.getName(), destinationCluster.getName()));
2225+
}
2226+
if (convertHost != null && selectedStoragePool.getScope() == ScopeType.CLUSTER && !selectedStoragePool.getClusterId().equals(convertHost.getClusterId())) {
2227+
logFailureAndThrowException(String.format("Cannot use the storage pool %s for the instance conversion as " +
2228+
"the host %s for conversion is in a different cluster", selectedStoragePool.getName(), convertHost.getName()));
2229+
}
2230+
}
2231+
2232+
private DataStoreTO getImageStoreOnDestinationZoneForTemporaryConversion(Cluster destinationCluster, boolean forceConvertToPool) {
2233+
if (forceConvertToPool) {
2234+
logFailureAndThrowException("Please select a primary storage pool when the parameter forceconverttopool is set to true");
2235+
}
2236+
long zoneId = destinationCluster.getDataCenterId();
2237+
ImageStoreVO imageStore = imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
2238+
if (imageStore == null) {
2239+
logFailureAndThrowException(String.format("Could not find an NFS secondary storage pool on zone %s to use as a temporary location " +
2240+
"for instance conversion", zoneId));
2241+
}
2242+
DataStore dataStore = dataStoreManager.getDataStore(imageStore.getId(), DataStoreRole.Image);
2243+
return dataStore.getTO();
2244+
}
2245+
2246+
private void checkDestinationOrTemporaryStoragePoolForConversion(StoragePoolVO selectedStoragePool, boolean forceConvertToPool, HostVO convertHost, HostVO importHost) {
2247+
if (selectedStoragePool.getScope() == ScopeType.HOST && (ObjectUtils.anyNull(convertHost, importHost) ||
2248+
ObjectUtils.allNotNull(convertHost, importHost) && convertHost.getId() != importHost.getId() ||
2249+
!forceConvertToPool) ) {
2250+
logFailureAndThrowException("Please select the same host as convert and importing host and " +
2251+
"set forceconvertopool to true to use a local storage pool for conversion");
2252+
}
2253+
if (!forceConvertToPool && selectedStoragePool.getPoolType() != Storage.StoragePoolType.NetworkFilesystem) {
2254+
logFailureAndThrowException(String.format("The storage pool %s is not supported for temporary conversion location," +
2255+
"only NFS storage pools are supported when forceconverttopool is set to false", selectedStoragePool.getName()));
2256+
}
2257+
}
2258+
22082259
protected DataStoreTO selectInstanceConversionTemporaryLocation(Cluster destinationCluster,
2209-
HostVO convertHost,
2260+
HostVO convertHost, HostVO importHost,
22102261
Long convertStoragePoolId, boolean forceConvertToPool) {
2211-
if (convertStoragePoolId != null) {
2212-
StoragePoolVO selectedStoragePool = primaryDataStoreDao.findById(convertStoragePoolId);
2213-
if (selectedStoragePool == null) {
2214-
logFailureAndThrowException(String.format("Cannot find a storage pool with ID %s", convertStoragePoolId));
2215-
}
2216-
if ((selectedStoragePool.getScope() == ScopeType.CLUSTER && selectedStoragePool.getClusterId() != destinationCluster.getId()) ||
2217-
(selectedStoragePool.getScope() == ScopeType.ZONE && selectedStoragePool.getDataCenterId() != destinationCluster.getDataCenterId())) {
2218-
logFailureAndThrowException(String.format("Cannot use the storage pool %s for the instance conversion as " +
2219-
"it is not in the scope of the cluster %s", selectedStoragePool.getName(), destinationCluster.getName()));
2220-
}
2221-
if (convertHost != null && selectedStoragePool.getScope() == ScopeType.CLUSTER && !selectedStoragePool.getClusterId().equals(convertHost.getClusterId())) {
2222-
logFailureAndThrowException(String.format("Cannot use the storage pool %s for the instance conversion as " +
2223-
"the host %s for conversion is in a different cluster", selectedStoragePool.getName(), convertHost.getName()));
2224-
}
2225-
if (!forceConvertToPool) {
2226-
if (selectedStoragePool.getScope() == ScopeType.HOST) {
2227-
logFailureAndThrowException(String.format("The storage pool %s is a local storage pool and not supported for temporary conversion location, cluster and zone wide NFS storage pools are supported", selectedStoragePool.getName()));
2228-
} else if (selectedStoragePool.getPoolType() != Storage.StoragePoolType.NetworkFilesystem) {
2229-
logFailureAndThrowException(String.format("The storage pool %s is not supported for temporary conversion location, only NFS storage pools are supported", selectedStoragePool.getName()));
2230-
}
2231-
}
2232-
return dataStoreManager.getPrimaryDataStore(convertStoragePoolId).getTO();
2233-
} else {
2234-
long zoneId = destinationCluster.getDataCenterId();
2235-
ImageStoreVO imageStore = imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
2236-
if (imageStore == null) {
2237-
logFailureAndThrowException(String.format("Could not find an NFS secondary storage pool on zone %s to use as a temporary location " +
2238-
"for instance conversion", zoneId));
2239-
}
2240-
DataStore dataStore = dataStoreManager.getDataStore(imageStore.getId(), DataStoreRole.Image);
2241-
return dataStore.getTO();
2262+
if (convertStoragePoolId == null) {
2263+
String msg = String.format("No convert storage pool has been provided, " +
2264+
"selecting an NFS secondary storage pool from the destination cluster (%s) zone", destinationCluster.getName());
2265+
logger.debug(msg);
2266+
return getImageStoreOnDestinationZoneForTemporaryConversion(destinationCluster, forceConvertToPool);
22422267
}
2268+
2269+
StoragePoolVO selectedStoragePool = primaryDataStoreDao.findById(convertStoragePoolId);
2270+
checkBeforeSelectingTemporaryConversionStoragePool(selectedStoragePool, convertStoragePoolId, destinationCluster, convertHost);
2271+
checkDestinationOrTemporaryStoragePoolForConversion(selectedStoragePool, forceConvertToPool, convertHost, importHost);
2272+
2273+
return dataStoreManager.getPrimaryDataStore(convertStoragePoolId).getTO();
22432274
}
22442275

22452276
protected Map<String, String> createParamsForTemplateFromVmwareVmMigration(String vcenterHost, String datacenterName,

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ public void testSelectInstanceConversionTemporaryLocationInvalidStorage() {
903903

904904
long poolId = 1L;
905905
when(primaryDataStoreDao.findById(poolId)).thenReturn(null);
906-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, poolId, false);
906+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, poolId, false);
907907
}
908908

909909
@Test(expected = CloudRuntimeException.class)
@@ -914,7 +914,7 @@ public void testSelectInstanceConversionTemporaryLocationPoolInvalidScope() {
914914
when(pool.getScope()).thenReturn(ScopeType.CLUSTER);
915915
when(pool.getClusterId()).thenReturn(100L);
916916
when(primaryDataStoreDao.findById(poolId)).thenReturn(pool);
917-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, poolId, false);
917+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, poolId, false);
918918
}
919919

920920

@@ -928,7 +928,7 @@ public void testSelectInstanceConversionTemporaryLocationPoolConvertHostDifferen
928928
HostVO host = mock(HostVO.class);
929929
when(primaryDataStoreDao.findById(poolId)).thenReturn(pool);
930930
when(host.getClusterId()).thenReturn(2L);
931-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, host, poolId, false);
931+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, host, null, poolId, false);
932932
}
933933

934934

@@ -939,7 +939,7 @@ public void testSelectInstanceConversionTemporaryLocationLocalStoragePoolInvalid
939939
StoragePoolVO pool = mock(StoragePoolVO.class);
940940
when(pool.getScope()).thenReturn(ScopeType.HOST);
941941
when(primaryDataStoreDao.findById(poolId)).thenReturn(pool);
942-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, poolId, false);
942+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, poolId, false);
943943
}
944944

945945
@Test(expected = CloudRuntimeException.class)
@@ -951,14 +951,14 @@ public void testSelectInstanceConversionTemporaryLocationStoragePoolInvalidType(
951951
when(pool.getClusterId()).thenReturn(1L);
952952
when(primaryDataStoreDao.findById(poolId)).thenReturn(pool);
953953
when(pool.getPoolType()).thenReturn(Storage.StoragePoolType.RBD);
954-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, poolId, false);
954+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, poolId, false);
955955
}
956956

957957
@Test(expected = CloudRuntimeException.class)
958958
public void testSelectInstanceConversionTemporaryLocationNoPoolAvailable() {
959959
ClusterVO cluster = getClusterForTests();
960960
when(imageStoreDao.findOneByZoneAndProtocol(anyLong(), anyString())).thenReturn(null);
961-
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, false);
961+
unmanagedVMsManager.selectInstanceConversionTemporaryLocation(cluster, null, null, null, false);
962962
}
963963

964964
@Test

0 commit comments

Comments
 (0)