Skip to content

Commit 2976142

Browse files
Host selection based on vddk capabilities
1 parent 7fb0b85 commit 2976142

2 files changed

Lines changed: 107 additions & 17 deletions

File tree

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

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,8 +1697,10 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster
16971697
String ovfTemplateOnConvertLocation = null;
16981698
ImportVmTask importVMTask = null;
16991699
try {
1700-
HostVO convertHost = selectKVMHostForConversionInCluster(destinationCluster, convertInstanceHostId);
1701-
HostVO importHost = selectKVMHostForImportingInCluster(destinationCluster, importInstanceHostId);
1700+
HostVO convertHost = selectKVMHostForConversionInCluster(destinationCluster, convertInstanceHostId, useVddk);
1701+
HostVO importHost = (useVddk && importInstanceHostId == null)
1702+
? convertHost
1703+
: selectKVMHostForImportingInCluster(destinationCluster, importInstanceHostId);
17021704
CheckConvertInstanceAnswer conversionSupportAnswer = checkConversionSupportOnHost(convertHost, sourceVMName, false);
17031705
logger.debug("The host {} is selected to execute the conversion of the " +
17041706
"instance {} from VMware to KVM ", convertHost, sourceVMName);
@@ -1995,7 +1997,7 @@ HostVO selectKVMHostForImportingInCluster(Cluster destinationCluster, Long impor
19951997
throw new CloudRuntimeException(err);
19961998
}
19971999

1998-
HostVO selectKVMHostForConversionInCluster(Cluster destinationCluster, Long convertInstanceHostId) {
2000+
HostVO selectKVMHostForConversionInCluster(Cluster destinationCluster, Long convertInstanceHostId, boolean useVddk) {
19992001
if (convertInstanceHostId != null) {
20002002
HostVO selectedHost = hostDao.findById(convertInstanceHostId);
20012003
String err = null;
@@ -2018,6 +2020,13 @@ HostVO selectKVMHostForConversionInCluster(Cluster destinationCluster, Long conv
20182020
err = String.format(
20192021
"Cannot perform the conversion on the host %s as it is not in the same zone as the destination cluster",
20202022
selectedHost);
2023+
} else if (useVddk) {
2024+
hostDao.loadDetails(selectedHost);
2025+
if (StringUtils.isBlank(selectedHost.getDetail(DETAIL_VDDK_LIB_DIR))) {
2026+
err = String.format(
2027+
"Cannot use VDDK-based conversion on host %s as the '%s' property is not configured on the host",
2028+
selectedHost, DETAIL_VDDK_LIB_DIR);
2029+
}
20212030
}
20222031
if (err != null) {
20232032
logger.error(err);
@@ -2029,21 +2038,41 @@ HostVO selectKVMHostForConversionInCluster(Cluster destinationCluster, Long conv
20292038
// Auto select host with conversion capability
20302039
List<HostVO> hosts = hostDao.listByClusterHypervisorTypeAndHostCapability(destinationCluster.getId(), destinationCluster.getHypervisorType(), Host.HOST_INSTANCE_CONVERSION);
20312040
if (CollectionUtils.isNotEmpty(hosts)) {
2032-
return hosts.get(new Random().nextInt(hosts.size()));
2041+
if (useVddk) {
2042+
hosts = filterHostsWithVddkLibDir(hosts);
2043+
}
2044+
if (CollectionUtils.isNotEmpty(hosts)) {
2045+
return hosts.get(new Random().nextInt(hosts.size()));
2046+
}
20332047
}
20342048

20352049
// Try without host capability check
20362050
hosts = hostDao.listByClusterAndHypervisorType(destinationCluster.getId(), destinationCluster.getHypervisorType());
20372051
if (CollectionUtils.isNotEmpty(hosts)) {
2038-
return hosts.get(new Random().nextInt(hosts.size()));
2052+
if (useVddk) {
2053+
hosts = filterHostsWithVddkLibDir(hosts);
2054+
}
2055+
if (CollectionUtils.isNotEmpty(hosts)) {
2056+
return hosts.get(new Random().nextInt(hosts.size()));
2057+
}
20392058
}
20402059

2041-
String err = String.format("Could not find any suitable %s host in cluster %s to perform the instance conversion",
2042-
destinationCluster.getHypervisorType(), destinationCluster);
2060+
String err = useVddk
2061+
? String.format("Could not find any suitable %s host in cluster %s with '%s' configured to perform the VDDK-based instance conversion",
2062+
destinationCluster.getHypervisorType(), destinationCluster, DETAIL_VDDK_LIB_DIR)
2063+
: String.format("Could not find any suitable %s host in cluster %s to perform the instance conversion",
2064+
destinationCluster.getHypervisorType(), destinationCluster);
20432065
logger.error(err);
20442066
throw new CloudRuntimeException(err);
20452067
}
20462068

2069+
private List<HostVO> filterHostsWithVddkLibDir(List<HostVO> hosts) {
2070+
return hosts.stream().filter(h -> {
2071+
hostDao.loadDetails(h);
2072+
return StringUtils.isNotBlank(h.getDetail(DETAIL_VDDK_LIB_DIR));
2073+
}).collect(Collectors.toList());
2074+
}
2075+
20472076
private CheckConvertInstanceAnswer checkConversionSupportOnHost(HostVO convertHost, String sourceVM, boolean checkWindowsGuestConversionSupport) {
20482077
logger.debug(String.format("Checking the %s conversion support on the host %s", checkWindowsGuestConversionSupport? "windows guest" : "", convertHost));
20492078
CheckConvertInstanceCommand cmd = new CheckConvertInstanceCommand(checkWindowsGuestConversionSupport);

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

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdEnabledHo
12491249

12501250
when(hostDao.findById(hostId)).thenReturn(host);
12511251

1252-
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1252+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
12531253
Assert.assertEquals(host, returnedHost);
12541254
}
12551255

@@ -1265,7 +1265,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdDisabledH
12651265

12661266
when(hostDao.findById(hostId)).thenReturn(host);
12671267

1268-
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1268+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
12691269
Assert.assertEquals(host, returnedHost);
12701270
}
12711271

@@ -1277,7 +1277,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdSuccessCo
12771277
when(hostDao.listByClusterHypervisorTypeAndHostCapability(cluster.getId(),
12781278
cluster.getHypervisorType(), Host.HOST_INSTANCE_CONVERSION)).thenReturn(List.of(host));
12791279

1280-
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null);
1280+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null, false);
12811281
Assert.assertEquals(host, returnedHost);
12821282
}
12831283

@@ -1291,7 +1291,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdSuccessNo
12911291

12921292
when(hostDao.listByClusterAndHypervisorType(cluster.getId(), cluster.getHypervisorType())).thenReturn(List.of(host));
12931293

1294-
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null);
1294+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null, false);
12951295
Assert.assertEquals(host, returnedHost);
12961296
}
12971297

@@ -1304,7 +1304,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdFailure()
13041304

13051305
when(hostDao.listByClusterAndHypervisorType(cluster.getId(), cluster.getHypervisorType())).thenReturn(List.of());
13061306

1307-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null);
1307+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null, false);
13081308
}
13091309

13101310
@Test(expected = CloudRuntimeException.class)
@@ -1319,7 +1319,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdInvalidZo
13191319

13201320
when(hostDao.findById(hostId)).thenReturn(host);
13211321

1322-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1322+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
13231323
}
13241324

13251325
@Test(expected = CloudRuntimeException.class)
@@ -1333,7 +1333,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdInvalidTy
13331333

13341334
when(hostDao.findById(hostId)).thenReturn(host);
13351335

1336-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1336+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
13371337
}
13381338

13391339
@Test(expected = CloudRuntimeException.class)
@@ -1346,7 +1346,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdInvalidSt
13461346

13471347
when(hostDao.findById(hostId)).thenReturn(host);
13481348

1349-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1349+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
13501350
}
13511351

13521352
@Test(expected = CloudRuntimeException.class)
@@ -1358,7 +1358,7 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdInvalidRe
13581358

13591359
when(hostDao.findById(hostId)).thenReturn(host);
13601360

1361-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1361+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
13621362
}
13631363

13641364
@Test(expected = CloudRuntimeException.class)
@@ -1368,7 +1368,68 @@ public void testSelectKVMHostForConversionInClusterWithImportInstanceIdInvalidHo
13681368

13691369
when(hostDao.findById(hostId)).thenReturn(null);
13701370

1371-
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
1371+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, false);
1372+
}
1373+
1374+
@Test
1375+
public void testSelectKVMHostForConversionInClusterVddkWithExplicitHostHavingVddkLibDir() {
1376+
Long hostId = 1L;
1377+
ClusterVO cluster = getClusterForTests();
1378+
HostVO host = Mockito.mock(HostVO.class);
1379+
when(host.getResourceState()).thenReturn(ResourceState.Enabled);
1380+
when(host.getStatus()).thenReturn(Status.Up);
1381+
when(host.getType()).thenReturn(Host.Type.Routing);
1382+
when(host.getDataCenterId()).thenReturn(1L);
1383+
when(host.getDetail("vddk.lib.dir")).thenReturn("/opt/vmware-vddk");
1384+
when(hostDao.findById(hostId)).thenReturn(host);
1385+
1386+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, true);
1387+
Assert.assertEquals(host, returnedHost);
1388+
Mockito.verify(hostDao).loadDetails(host);
1389+
}
1390+
1391+
@Test(expected = CloudRuntimeException.class)
1392+
public void testSelectKVMHostForConversionInClusterVddkWithExplicitHostMissingVddkLibDir() {
1393+
Long hostId = 1L;
1394+
ClusterVO cluster = getClusterForTests();
1395+
HostVO host = Mockito.mock(HostVO.class);
1396+
when(host.getResourceState()).thenReturn(ResourceState.Enabled);
1397+
when(host.getStatus()).thenReturn(Status.Up);
1398+
when(host.getType()).thenReturn(Host.Type.Routing);
1399+
when(host.getDataCenterId()).thenReturn(1L);
1400+
when(host.getDetail("vddk.lib.dir")).thenReturn(null);
1401+
when(hostDao.findById(hostId)).thenReturn(host);
1402+
1403+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId, true);
1404+
}
1405+
1406+
@Test
1407+
public void testSelectKVMHostForConversionInClusterVddkAutoSelectsHostWithVddkLibDir() {
1408+
ClusterVO cluster = getClusterForTests();
1409+
HostVO hostWithVddk = Mockito.mock(HostVO.class);
1410+
HostVO hostWithoutVddk = Mockito.mock(HostVO.class);
1411+
when(hostWithVddk.getDetail("vddk.lib.dir")).thenReturn("/opt/vmware-vddk");
1412+
when(hostWithoutVddk.getDetail("vddk.lib.dir")).thenReturn(null);
1413+
1414+
when(hostDao.listByClusterHypervisorTypeAndHostCapability(cluster.getId(),
1415+
cluster.getHypervisorType(), Host.HOST_INSTANCE_CONVERSION))
1416+
.thenReturn(List.of(hostWithoutVddk, hostWithVddk));
1417+
1418+
HostVO returnedHost = unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null, true);
1419+
Assert.assertEquals(hostWithVddk, returnedHost);
1420+
}
1421+
1422+
@Test(expected = CloudRuntimeException.class)
1423+
public void testSelectKVMHostForConversionInClusterVddkFailsWhenNoHostHasVddkLibDir() {
1424+
ClusterVO cluster = getClusterForTests();
1425+
HostVO host = Mockito.mock(HostVO.class);
1426+
when(host.getDetail("vddk.lib.dir")).thenReturn(null);
1427+
1428+
when(hostDao.listByClusterHypervisorTypeAndHostCapability(cluster.getId(),
1429+
cluster.getHypervisorType(), Host.HOST_INSTANCE_CONVERSION)).thenReturn(List.of(host));
1430+
when(hostDao.listByClusterAndHypervisorType(cluster.getId(), cluster.getHypervisorType())).thenReturn(List.of(host));
1431+
1432+
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, null, true);
13721433
}
13731434

13741435
@Test

0 commit comments

Comments
 (0)