Skip to content

Commit ca2ba80

Browse files
GaOrtigahsato03JoaoJandre
authored andcommitted
Allow altering only either CPU or memory during VM live scale (apache#8234)
* allow change only one parameter during live scale * Update server/src/main/java/com/cloud/vm/UserVmManagerImpl.java Co-authored-by: sato03 <henriquesato2003@gmail.com> * apply change method name * Update server/src/main/java/com/cloud/vm/UserVmManagerImpl.java Co-authored-by: João Jandre <48719461+JoaoJandre@users.noreply.github.com> --------- Co-authored-by: Gabriel <gabriel.fernandes@scclouds.com.br> Co-authored-by: sato03 <henriquesato2003@gmail.com> Co-authored-by: João Jandre <48719461+JoaoJandre@users.noreply.github.com>
1 parent b277266 commit ca2ba80

2 files changed

Lines changed: 115 additions & 2 deletions

File tree

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
407407
@Inject
408408
private VMTemplateZoneDao _templateZoneDao;
409409
@Inject
410-
private TemplateDataStoreDao _templateStoreDao;
410+
protected TemplateDataStoreDao _templateStoreDao;
411411
@Inject
412412
private DomainDao _domainDao;
413413
@Inject
@@ -1239,6 +1239,39 @@ public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationE
12391239
return userVm;
12401240
}
12411241

1242+
/**
1243+
Updates the instance details map with the current values of the instance for the CPU speed, memory, and CPU number if they have not been specified.
1244+
@param details Map containing the instance details.
1245+
@param vmInstance The virtual machine instance.
1246+
@param newServiceOfferingId The ID of the new service offering.
1247+
*/
1248+
1249+
protected void updateInstanceDetails (Map<String, String> details, VirtualMachine vmInstance, Long newServiceOfferingId) {
1250+
ServiceOfferingVO currentServiceOffering = serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
1251+
ServiceOfferingVO newServiceOffering = serviceOfferingDao.findById(newServiceOfferingId);
1252+
updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getSpeed(), details, VmDetailConstants.CPU_SPEED, currentServiceOffering.getSpeed());
1253+
updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getRamSize(), details, VmDetailConstants.MEMORY, currentServiceOffering.getRamSize());
1254+
updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getCpu(), details, VmDetailConstants.CPU_NUMBER, currentServiceOffering.getCpu());
1255+
}
1256+
1257+
/**
1258+
* Updates a specific instance detail with the current instance value if the new value is null.
1259+
*
1260+
* @param newValue the new value to be set
1261+
* @param details a map of instance details
1262+
* @param detailsConstant the name of the detail constant to be updated
1263+
* @param currentValue the current value of the detail constant
1264+
*/
1265+
1266+
protected void updateInstanceDetailsKeepCurrentValueIfNull(Integer newValue, Map<String, String> details, String detailsConstant, Integer currentValue) {
1267+
if (newValue == null && details.get(detailsConstant) == null) {
1268+
String currentValueString = String.valueOf(currentValue);
1269+
logger.debug("{} was not specified, keeping the current value: {}.", detailsConstant, currentValueString);
1270+
details.put(detailsConstant, currentValueString);
1271+
}
1272+
}
1273+
1274+
12421275
private void validateOfferingMaxResource(ServiceOfferingVO offering) {
12431276
Integer maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value();
12441277
if (offering.getCpu() > maxCPUCores) {
@@ -1904,7 +1937,11 @@ public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableEx
19041937
}
19051938
CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
19061939

1907-
boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmd.getDetails());
1940+
Map<String, String> cmdDetails = cmd.getDetails();
1941+
1942+
updateInstanceDetails(cmdDetails, vm, newServiceOfferingId);
1943+
1944+
boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmdDetails);
19081945
if (result) {
19091946
UserVmVO vmInstance = _vmDao.findById(vmId);
19101947
if (vmInstance.getState().equals(State.Stopped)) {

server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ public class UserVmManagerImplTest {
268268
@Mock
269269
ServiceOfferingJoinDao serviceOfferingJoinDao;
270270

271+
@Mock
272+
private VMInstanceVO vmInstanceMock;
273+
271274
private static final long vmId = 1l;
272275
private static final long zoneId = 2L;
273276
private static final long accountId = 3L;
@@ -278,6 +281,8 @@ public class UserVmManagerImplTest {
278281

279282
private Map<String, String> customParameters = new HashMap<>();
280283

284+
String[] detailsConstants = {VmDetailConstants.MEMORY, VmDetailConstants.CPU_NUMBER, VmDetailConstants.CPU_SPEED};
285+
281286
private DiskOfferingVO smallerDisdkOffering = prepareDiskOffering(5l * GiB_TO_BYTES, 1l, 1L, 2L);
282287
private DiskOfferingVO largerDisdkOffering = prepareDiskOffering(10l * GiB_TO_BYTES, 2l, 10L, 20L);
283288

@@ -294,6 +299,10 @@ public void beforeTest() {
294299
CallContext.register(callerUser, callerAccount);
295300

296301
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, "123");
302+
customParameters.put(VmDetailConstants.MEMORY, "2048");
303+
customParameters.put(VmDetailConstants.CPU_NUMBER, "4");
304+
customParameters.put(VmDetailConstants.CPU_SPEED, "1000");
305+
297306
lenient().doNothing().when(resourceLimitMgr).incrementResourceCount(anyLong(), any(Resource.ResourceType.class));
298307
lenient().doNothing().when(resourceLimitMgr).decrementResourceCount(anyLong(), any(Resource.ResourceType.class), anyLong());
299308

@@ -1444,4 +1453,71 @@ public void testRestoreVirtualMachineWithVMSnapshots() throws ResourceUnavailabl
14441453

14451454
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
14461455
}
1456+
1457+
@Test
1458+
public void updateInstanceDetailsKeepCurrentValueIfNullTestDetailsConstantIsNotNullDoNothing() {
1459+
int currentValue = 123;
1460+
1461+
for (String detailsConstant : detailsConstants) {
1462+
userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(null, customParameters, detailsConstant, currentValue);
1463+
}
1464+
1465+
Assert.assertEquals(customParameters.get(VmDetailConstants.MEMORY), "2048");
1466+
Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_NUMBER), "4");
1467+
Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_SPEED), "1000");
1468+
}
1469+
1470+
@Test
1471+
public void updateInstanceDetailsKeepCurrentValueIfNullTestNewValueIsNotNullDoNothing() {
1472+
Map<String, String> details = new HashMap<>();
1473+
int currentValue = 123;
1474+
1475+
for (String detailsConstant : detailsConstants) {
1476+
userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(321, details, detailsConstant, currentValue);
1477+
}
1478+
1479+
Assert.assertNull(details.get(VmDetailConstants.MEMORY));
1480+
Assert.assertNull(details.get(VmDetailConstants.CPU_NUMBER));
1481+
Assert.assertNull(details.get(VmDetailConstants.CPU_SPEED));
1482+
}
1483+
1484+
@Test
1485+
public void updateInstanceDetailsKeepCurrentValueIfNullTestBothValuesAreNullKeepCurrentValue() {
1486+
Map<String, String> details = new HashMap<>();
1487+
int currentValue = 123;
1488+
1489+
for (String detailsConstant : detailsConstants) {
1490+
userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(null, details, detailsConstant, currentValue);
1491+
}
1492+
1493+
Assert.assertEquals(details.get(VmDetailConstants.MEMORY), String.valueOf(currentValue));
1494+
Assert.assertEquals(details.get(VmDetailConstants.CPU_NUMBER), String.valueOf(currentValue));
1495+
Assert.assertEquals(details.get(VmDetailConstants.CPU_SPEED),String.valueOf(currentValue));
1496+
}
1497+
1498+
@Test
1499+
public void updateInstanceDetailsKeepCurrentValueIfNullTestNeitherValueIsNullDoNothing() {
1500+
int currentValue = 123;
1501+
1502+
for (String detailsConstant : detailsConstants) {
1503+
userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(321, customParameters, detailsConstant, currentValue);
1504+
}
1505+
1506+
Assert.assertEquals(customParameters.get(VmDetailConstants.MEMORY), "2048");
1507+
Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_NUMBER), "4");
1508+
Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_SPEED),"1000");
1509+
}
1510+
1511+
@Test
1512+
public void updateInstanceDetailsTestAllConstantsAreUpdated() {
1513+
Mockito.doReturn(serviceOffering).when(_serviceOfferingDao).findById(Mockito.anyLong());
1514+
Mockito.doReturn(1L).when(vmInstanceMock).getId();
1515+
Mockito.doReturn(1L).when(vmInstanceMock).getServiceOfferingId();
1516+
Mockito.doReturn(serviceOffering).when(_serviceOfferingDao).findByIdIncludingRemoved(Mockito.anyLong(), Mockito.anyLong());
1517+
userVmManagerImpl.updateInstanceDetails(null, vmInstanceMock, 0l);
1518+
1519+
Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.CPU_SPEED), Mockito.any());
1520+
Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.MEMORY), Mockito.any());
1521+
Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.CPU_NUMBER), Mockito.any());
1522+
}
14471523
}

0 commit comments

Comments
 (0)