You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by gu...@apache.org on 2024/02/14 21:57:55 UTC
(cloudstack) branch main updated: Allow altering only either CPU or memory during VM live scale (#8234)
This is an automated email from the ASF dual-hosted git repository.
gutoveronezi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new a31449b1049 Allow altering only either CPU or memory during VM live scale (#8234)
a31449b1049 is described below
commit a31449b10490cb386d60fc961f6d3bf3bdb09ccd
Author: GaOrtiga <49...@users.noreply.github.com>
AuthorDate: Wed Feb 14 18:57:47 2024 -0300
Allow altering only either CPU or memory during VM live scale (#8234)
* allow change only one parameter during live scale
* Update server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
Co-authored-by: sato03 <he...@gmail.com>
* apply change method name
* Update server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
Co-authored-by: João Jandre <48...@users.noreply.github.com>
---------
Co-authored-by: Gabriel <ga...@scclouds.com.br>
Co-authored-by: sato03 <he...@gmail.com>
Co-authored-by: João Jandre <48...@users.noreply.github.com>
---
.../main/java/com/cloud/vm/UserVmManagerImpl.java | 41 +++++++++++-
.../java/com/cloud/vm/UserVmManagerImplTest.java | 76 ++++++++++++++++++++++
2 files changed, 115 insertions(+), 2 deletions(-)
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index 063ed09c839..99b334a9f74 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -399,7 +399,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject
private VMTemplateZoneDao _templateZoneDao;
@Inject
- private TemplateDataStoreDao _templateStoreDao;
+ protected TemplateDataStoreDao _templateStoreDao;
@Inject
private DomainDao _domainDao;
@Inject
@@ -1226,6 +1226,39 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
return userVm;
}
+ /**
+ 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.
+ @param details Map containing the instance details.
+ @param vmInstance The virtual machine instance.
+ @param newServiceOfferingId The ID of the new service offering.
+ */
+
+ protected void updateInstanceDetails (Map<String, String> details, VirtualMachine vmInstance, Long newServiceOfferingId) {
+ ServiceOfferingVO currentServiceOffering = serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+ ServiceOfferingVO newServiceOffering = serviceOfferingDao.findById(newServiceOfferingId);
+ updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getSpeed(), details, VmDetailConstants.CPU_SPEED, currentServiceOffering.getSpeed());
+ updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getRamSize(), details, VmDetailConstants.MEMORY, currentServiceOffering.getRamSize());
+ updateInstanceDetailsKeepCurrentValueIfNull(newServiceOffering.getCpu(), details, VmDetailConstants.CPU_NUMBER, currentServiceOffering.getCpu());
+ }
+
+ /**
+ * Updates a specific instance detail with the current instance value if the new value is null.
+ *
+ * @param newValue the new value to be set
+ * @param details a map of instance details
+ * @param detailsConstant the name of the detail constant to be updated
+ * @param currentValue the current value of the detail constant
+ */
+
+ protected void updateInstanceDetailsKeepCurrentValueIfNull(Integer newValue, Map<String, String> details, String detailsConstant, Integer currentValue) {
+ if (newValue == null && details.get(detailsConstant) == null) {
+ String currentValueString = String.valueOf(currentValue);
+ logger.debug("{} was not specified, keeping the current value: {}.", detailsConstant, currentValueString);
+ details.put(detailsConstant, currentValueString);
+ }
+ }
+
+
private void validateOfferingMaxResource(ServiceOfferingVO offering) {
Integer maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value();
if (offering.getCpu() > maxCPUCores) {
@@ -1891,7 +1924,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
- boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmd.getDetails());
+ Map<String, String> cmdDetails = cmd.getDetails();
+
+ updateInstanceDetails(cmdDetails, vm, newServiceOfferingId);
+
+ boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmdDetails);
if (result) {
UserVmVO vmInstance = _vmDao.findById(vmId);
if (vmInstance.getState().equals(State.Stopped)) {
diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
index 13b937789f2..ffd0c407f13 100644
--- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
+++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
@@ -267,6 +267,9 @@ public class UserVmManagerImplTest {
@Mock
ServiceOfferingJoinDao serviceOfferingJoinDao;
+ @Mock
+ private VMInstanceVO vmInstanceMock;
+
private static final long vmId = 1l;
private static final long zoneId = 2L;
private static final long accountId = 3L;
@@ -277,6 +280,8 @@ public class UserVmManagerImplTest {
private Map<String, String> customParameters = new HashMap<>();
+ String[] detailsConstants = {VmDetailConstants.MEMORY, VmDetailConstants.CPU_NUMBER, VmDetailConstants.CPU_SPEED};
+
private DiskOfferingVO smallerDisdkOffering = prepareDiskOffering(5l * GiB_TO_BYTES, 1l, 1L, 2L);
private DiskOfferingVO largerDisdkOffering = prepareDiskOffering(10l * GiB_TO_BYTES, 2l, 10L, 20L);
@@ -293,6 +298,10 @@ public class UserVmManagerImplTest {
CallContext.register(callerUser, callerAccount);
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, "123");
+ customParameters.put(VmDetailConstants.MEMORY, "2048");
+ customParameters.put(VmDetailConstants.CPU_NUMBER, "4");
+ customParameters.put(VmDetailConstants.CPU_SPEED, "1000");
+
lenient().doNothing().when(resourceLimitMgr).incrementResourceCount(anyLong(), any(Resource.ResourceType.class));
lenient().doNothing().when(resourceLimitMgr).decrementResourceCount(anyLong(), any(Resource.ResourceType.class), anyLong());
@@ -1443,4 +1452,71 @@ public class UserVmManagerImplTest {
userVmManagerImpl.restoreVirtualMachine(accountMock, vmId, newTemplateId);
}
+
+ @Test
+ public void updateInstanceDetailsKeepCurrentValueIfNullTestDetailsConstantIsNotNullDoNothing() {
+ int currentValue = 123;
+
+ for (String detailsConstant : detailsConstants) {
+ userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(null, customParameters, detailsConstant, currentValue);
+ }
+
+ Assert.assertEquals(customParameters.get(VmDetailConstants.MEMORY), "2048");
+ Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_NUMBER), "4");
+ Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_SPEED), "1000");
+ }
+
+ @Test
+ public void updateInstanceDetailsKeepCurrentValueIfNullTestNewValueIsNotNullDoNothing() {
+ Map<String, String> details = new HashMap<>();
+ int currentValue = 123;
+
+ for (String detailsConstant : detailsConstants) {
+ userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(321, details, detailsConstant, currentValue);
+ }
+
+ Assert.assertNull(details.get(VmDetailConstants.MEMORY));
+ Assert.assertNull(details.get(VmDetailConstants.CPU_NUMBER));
+ Assert.assertNull(details.get(VmDetailConstants.CPU_SPEED));
+ }
+
+ @Test
+ public void updateInstanceDetailsKeepCurrentValueIfNullTestBothValuesAreNullKeepCurrentValue() {
+ Map<String, String> details = new HashMap<>();
+ int currentValue = 123;
+
+ for (String detailsConstant : detailsConstants) {
+ userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(null, details, detailsConstant, currentValue);
+ }
+
+ Assert.assertEquals(details.get(VmDetailConstants.MEMORY), String.valueOf(currentValue));
+ Assert.assertEquals(details.get(VmDetailConstants.CPU_NUMBER), String.valueOf(currentValue));
+ Assert.assertEquals(details.get(VmDetailConstants.CPU_SPEED),String.valueOf(currentValue));
+ }
+
+ @Test
+ public void updateInstanceDetailsKeepCurrentValueIfNullTestNeitherValueIsNullDoNothing() {
+ int currentValue = 123;
+
+ for (String detailsConstant : detailsConstants) {
+ userVmManagerImpl.updateInstanceDetailsKeepCurrentValueIfNull(321, customParameters, detailsConstant, currentValue);
+ }
+
+ Assert.assertEquals(customParameters.get(VmDetailConstants.MEMORY), "2048");
+ Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_NUMBER), "4");
+ Assert.assertEquals(customParameters.get(VmDetailConstants.CPU_SPEED),"1000");
+ }
+
+ @Test
+ public void updateInstanceDetailsTestAllConstantsAreUpdated() {
+ Mockito.doReturn(serviceOffering).when(_serviceOfferingDao).findById(Mockito.anyLong());
+ Mockito.doReturn(1L).when(vmInstanceMock).getId();
+ Mockito.doReturn(1L).when(vmInstanceMock).getServiceOfferingId();
+ Mockito.doReturn(serviceOffering).when(_serviceOfferingDao).findByIdIncludingRemoved(Mockito.anyLong(), Mockito.anyLong());
+ userVmManagerImpl.updateInstanceDetails(null, vmInstanceMock, 0l);
+
+ Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.CPU_SPEED), Mockito.any());
+ Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.MEMORY), Mockito.any());
+ Mockito.verify(userVmManagerImpl).updateInstanceDetailsKeepCurrentValueIfNull(Mockito.any(), Mockito.any(), Mockito.eq(VmDetailConstants.CPU_NUMBER), Mockito.any());
+ }
}