From a83173e8a676a9c61dd2d14fb75172deb9168260 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 5 Feb 2021 17:56:14 +0530 Subject: [PATCH] Added version number on new API parameters Used single method for multiple checks Added the case for restore VM where VM can be restored to new template. In that case VM's dynamic scalability needs to be updated based on new template --- .../offering/CreateServiceOfferingCmd.java | 3 +-- .../api/command/user/vm/DeployVMCmd.java | 3 +-- .../cloud/vm/VirtualMachineManagerImpl.java | 3 ++- .../KubernetesClusterStartWorker.java | 7 ++--- .../main/java/com/cloud/vm/UserVmManager.java | 5 ++++ .../java/com/cloud/vm/UserVmManagerImpl.java | 26 ++++++++++++------- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index 253881e0959..638319f02a0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -223,8 +223,7 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.STORAGE_POLICY, type = CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,required = false, description = "Name of the storage policy defined at vCenter, this is applicable only for VMware", since = "4.15") private Long storagePolicy; - @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, - type = CommandType.BOOLEAN, + @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, since = "4.16", description = "true if virtual machine needs to be dynamically scalable of cpu or memory") protected Boolean isDynamicScalingEnabled; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 346d49ca6c5..789365fae58 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -235,8 +235,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG @LogLevel(LogLevel.Log4jLevel.Off) private Map vAppNetworks; - @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, - type = CommandType.BOOLEAN, + @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, since = "4.16", description = "true if virtual machine needs to be dynamically scalable") protected Boolean dynamicScalingEnabled; diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index cc938a9974c..41a7c8d627c 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3916,7 +3916,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { removeCustomOfferingDetails(vmId); } - Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && newServiceOffering.isDynamicScalingEnabled() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vmForUpdate.getDataCenterId()); + VMTemplateVO template = _templateDao.findById(vmForUpdate.getTemplateId()); + Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && _userVmMgr.checkIfDynamicScalingCanBeEnabled(newServiceOffering, template, vmForUpdate.getDataCenterId()); vmForUpdate.setDynamicallyScalable(dynamicScalingEnabled); return _vmDao.update(vmId, vmForUpdate); } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java index 6021427bd32..307b4f13f2b 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java @@ -72,7 +72,6 @@ import com.cloud.vm.Nic; import com.cloud.vm.ReservationContext; import com.cloud.vm.ReservationContextImpl; import com.cloud.vm.VirtualMachine; -import com.cloud.vm.UserVmManager; import com.google.common.base.Strings; public class KubernetesClusterStartWorker extends KubernetesClusterResourceModifierActionWorker { @@ -209,11 +208,10 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); - Boolean dynamicScalingEnabled = serviceOffering.isDynamicScalingEnabled() && clusterTemplate.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); masterVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner, hostName, hostName, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(), - requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, dynamicScalingEnabled); + requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, true); if (LOGGER.isInfoEnabled()) { LOGGER.info(String.format("Created master VM ID: %s, %s in the Kubernetes cluster : %s", masterVm.getUuid(), hostName, kubernetesCluster.getName())); } @@ -264,11 +262,10 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); - Boolean dynamicScalingEnabled = serviceOffering.isDynamicScalingEnabled() && clusterTemplate.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); additionalMasterVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner, hostName, hostName, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(), - null, addrs, null, null, null, customParameterMap, null, null, null, null, dynamicScalingEnabled); + null, addrs, null, null, null, customParameterMap, null, null, null, null, true); if (LOGGER.isInfoEnabled()) { LOGGER.info(String.format("Created master VM ID : %s, %s in the Kubernetes cluster : %s", additionalMasterVm.getUuid(), hostName, kubernetesCluster.getName())); } diff --git a/server/src/main/java/com/cloud/vm/UserVmManager.java b/server/src/main/java/com/cloud/vm/UserVmManager.java index e4206efe5d8..ba720aebc3d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManager.java +++ b/server/src/main/java/com/cloud/vm/UserVmManager.java @@ -20,6 +20,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.cloud.offering.ServiceOffering; +import com.cloud.template.VirtualMachineTemplate; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.framework.config.ConfigKey; @@ -124,4 +126,7 @@ public interface UserVmManager extends UserVmService { void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString); HashMap> getVmNetworkStatistics(long hostId, String hostName, List vmIds); + + Boolean checkIfDynamicScalingCanBeEnabled(ServiceOffering offering, VirtualMachineTemplate template, Long zoneId); + } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index b37252fda36..9fc2e56cbed 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3939,7 +3939,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(dynamicScalingEnabled, offering, template, zone.getId()); + dynamicScalingEnabled = dynamicScalingEnabled && checkIfDynamicScalingCanBeEnabled(offering, template, zone.getId()); UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dhcpOptionMap, @@ -3967,13 +3967,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return vm; } - private Boolean checkIfDynamicScalingCanBeEnabled(Boolean dynamicScalingEnabled, ServiceOfferingVO offering, VMTemplateVO template, Long zoneId) { - if (dynamicScalingEnabled) { - if (!(offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId))) { - s_logger.info("VM cannot be configured to be dynamically scalable if any of the service offering's dynamic scaling property, template's dynamic scaling property or global setting is false"); - } + @Override + public Boolean checkIfDynamicScalingCanBeEnabled(ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) { + Boolean canEnableDynamicScaling = offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + if (!canEnableDynamicScaling) { + s_logger.info("VM cannot be configured to be dynamically scalable if any of the service offering's dynamic scaling property, template's dynamic scaling property or global setting is false"); } - return dynamicScalingEnabled && offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + + return canEnableDynamicScaling; } /** @@ -7095,13 +7096,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir vm.setIsoId(newTemplateId); vm.setGuestOSId(template.getGuestOSId()); vm.setTemplateId(newTemplateId); - _vmDao.update(vmId, vm); } else { newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId); vm.setGuestOSId(template.getGuestOSId()); vm.setTemplateId(newTemplateId); - _vmDao.update(vmId, vm); } + // check if VM can be dynamically scalable with the new template + ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getServiceOfferingId()); + VMTemplateVO newTemplate = _templateDao.findById(newTemplateId); + Boolean dynamicScalingEnabled = vm.isDynamicallyScalable() && checkIfDynamicScalingCanBeEnabled(serviceOffering, newTemplate, vm.getDataCenterId()); + vm.setDynamicallyScalable(dynamicScalingEnabled); + _vmDao.update(vmId, vm); + } else { newVol = volumeMgr.allocateDuplicateVolume(root, null); } @@ -7506,7 +7512,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir final String uuidName = _uuidMgr.generateUuid(UserVm.class, null); final Host lastHost = powerState != VirtualMachine.PowerState.PowerOn ? host : null; - final Boolean dynamicScalingEnabled = serviceOffering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); + final Boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(serviceOffering, template, zone.getId()); return commitUserVm(true, zone, host, lastHost, template, hostName, displayName, owner, null, null, userData, caller, isDisplayVm, keyboard, accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), sshPublicKey, null,