From d28cb789d5f0cc014afe963af24876e144681ff2 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 29 Jan 2021 10:48:07 +0530 Subject: [PATCH 01/22] Dynamic Scaling option granularity --- .../com/cloud/offering/ServiceOffering.java | 2 + .../main/java/com/cloud/vm/UserVmService.java | 6 +- .../java/com/cloud/vm/VirtualMachine.java | 2 + .../apache/cloudstack/api/ApiConstants.java | 1 + .../offering/CreateServiceOfferingCmd.java | 9 ++ .../api/command/user/vm/DeployVMCmd.java | 9 ++ .../api/response/ServiceOfferingResponse.java | 13 ++- .../api/response/SystemVmResponse.java | 12 +++ .../cloud/vm/VirtualMachineManagerImpl.java | 2 + .../com/cloud/service/ServiceOfferingVO.java | 67 ++++--------- .../cloud/entity/api/db/VMEntityVO.java | 8 ++ .../META-INF/db/schema-41400to41500.sql | 2 +- .../META-INF/db/schema-41510to41600.sql | 93 ++++++++++++++++++- .../quota/vo/ServiceOfferingVO.java | 8 ++ ...esClusterResourceModifierActionWorker.java | 2 +- .../KubernetesClusterStartWorker.java | 7 +- .../java/com/cloud/api/ApiResponseHelper.java | 1 + .../query/dao/ServiceOfferingJoinDaoImpl.java | 1 + .../api/query/vo/ServiceOfferingJoinVO.java | 11 +++ .../ConfigurationManagerImpl.java | 6 +- .../cloud/hypervisor/HypervisorGuruBase.java | 3 +- .../network/as/AutoScaleManagerImpl.java | 6 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 71 +++++++++----- .../DeploymentPlanningManagerImplTest.java | 6 +- 24 files changed, 256 insertions(+), 92 deletions(-) diff --git a/api/src/main/java/com/cloud/offering/ServiceOffering.java b/api/src/main/java/com/cloud/offering/ServiceOffering.java index 2a80ba5bd61c..163762202b04 100644 --- a/api/src/main/java/com/cloud/offering/ServiceOffering.java +++ b/api/src/main/java/com/cloud/offering/ServiceOffering.java @@ -116,4 +116,6 @@ public enum StorageType { String getDeploymentPlanner(); boolean isDynamic(); + + boolean isDynamicallyScalable(); } diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index eab9c736a377..da2591ecac88 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -218,7 +218,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameter, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFProperties) throws InsufficientCapacityException, + Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -300,7 +300,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFProperties) throws InsufficientCapacityException, + Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -379,7 +379,7 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map templateOvfPropertiesMap) + Map templateOvfPropertiesMap, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; diff --git a/api/src/main/java/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java index 829e743df730..02f55377845a 100644 --- a/api/src/main/java/com/cloud/vm/VirtualMachine.java +++ b/api/src/main/java/com/cloud/vm/VirtualMachine.java @@ -342,4 +342,6 @@ public boolean isUsedBySystem() { @Override boolean isDisplay(); + Boolean isDynamicallyScalable(); + } diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 605a6c006ebd..006f58a28330 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -837,6 +837,7 @@ public class ApiConstants { public static final String CROSS_ZONES = "crossZones"; public static final String TEMPLATETYPE = "templatetype"; public static final String SOURCETEMPLATEID = "sourcetemplateid"; + public static final String DynamicScalingEnabled = "dynamicscalingenabled"; public static final String POOL_TYPE ="pooltype"; 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 d2d6f387744c..428309a3278b 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,6 +223,11 @@ 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.DynamicScalingEnabled, + type = CommandType.BOOLEAN, + description = "true if virtual machine needs to be dynamically scalable of cpu or memory") + protected Boolean isDynamicScalingEnabled; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -441,6 +446,10 @@ public Long getStoragePolicy() { return storagePolicy; } + public Boolean getDynamicScalingEnabled() { + return isDynamicScalingEnabled == null ? Boolean.TRUE : isDynamicScalingEnabled; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// 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 6d7cc9c81c2f..d6f3727128c7 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,6 +235,11 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG @LogLevel(LogLevel.Log4jLevel.Off) private Map vAppNetworks; + @Parameter(name = ApiConstants.DynamicScalingEnabled, + type = CommandType.BOOLEAN, + description = "true if virtual machine needs to be dynamically scalable") + protected Boolean isDynamicScalingEnabled; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -623,6 +628,10 @@ public Boolean getBootIntoSetup() { return bootIntoSetup; } + public Boolean getDynamicScalingEnabled() { + return isDynamicScalingEnabled == null ? Boolean.TRUE : isDynamicScalingEnabled; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 05fcfbdc7b2e..40be57c3975d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -204,6 +204,10 @@ public class ServiceOfferingResponse extends BaseResponse { @Param(description = "Root disk size in GB", since = "4.15") private Long rootDiskSize; + @SerializedName("dynamicscalingenabled") + @Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory") + private Boolean dynamicscalingenabled; + public ServiceOfferingResponse() { } @@ -457,7 +461,6 @@ public void setDetails(Map details) { public void setIscutomized(boolean iscutomized) { this.isCustomized = iscutomized; - } public void setCacheMode(String cacheMode) { @@ -475,4 +478,12 @@ public void setVsphereStoragePolicy(String vsphereStoragePolicy) { public void setRootDiskSize(Long rootDiskSize) { this.rootDiskSize = rootDiskSize; } + + public Boolean getDynamicscalingenabled() { + return dynamicscalingenabled; + } + + public void setDynamicscalingenabled(Boolean dynamicscalingenabled) { + this.dynamicscalingenabled = dynamicscalingenabled; + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java index 934e84fe9d0a..bfc9f9aad86d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java @@ -170,6 +170,10 @@ public class SystemVmResponse extends BaseResponse { @Param(description = "the systemvm agent version", since = "4.13.1") private String version; + @SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE) + @Param(description = "true if vm contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory.") + private Boolean isDynamicallyScalable; + @Override public String getObjectId() { return this.getId(); @@ -442,4 +446,12 @@ public String getVersion() { public void setVersion(String version) { this.version = version; } + + public Boolean getDynamicallyScalable() { + return isDynamicallyScalable; + } + + public void setDynamicallyScalable(Boolean dynamicallyScalable) { + isDynamicallyScalable = dynamicallyScalable; + } } 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 3e5ddbfcbc8c..4c1ce803dcac 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3916,6 +3916,8 @@ public boolean upgradeVmDb(final long vmId, final ServiceOffering newServiceOffe if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { removeCustomOfferingDetails(vmId); } + Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && newServiceOffering.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vmForUpdate.getDataCenterId()); + vmForUpdate.setDynamicallyScalable(dynamicScalingEnabled); return _vmDao.update(vmId, vmForUpdate); } diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java index 3a5f3182b731..c265bcd290d5 100644 --- a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java @@ -75,6 +75,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering @Column(name = "deployment_planner") private String deploymentPlanner = null; + @Column(name = "dynamically_scalable") + private boolean dynamicallyScalable; + // This is a delayed load value. If the value is null, // then this field has not been loaded yet. // Call service offering dao to load it. @@ -91,7 +94,7 @@ protected ServiceOfferingVO() { } public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, - ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) { + ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) { super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true); this.cpu = cpu; this.ramSize = ramSize; @@ -105,8 +108,9 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee this.vmType = vmType == null ? null : vmType.toString().toLowerCase(); } - public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse, - boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType) { + public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, + boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, + VirtualMachine.Type vmType, String hostTag, String deploymentPlanner, Boolean dynamicScalingEnabled) { super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true); this.cpu = cpu; this.ramSize = ramSize; @@ -114,55 +118,12 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee this.rateMbps = rateMbps; this.multicastRateMbps = multicastRateMbps; this.offerHA = offerHA; - this.limitCpuUse = limitCpuUse; + this.limitCpuUse = limitResourceUse; this.volatileVm = volatileVm; this.vmType = vmType == null ? null : vmType.toString().toLowerCase(); - } - - public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, - VirtualMachine.Type vmType, String hostTag) { - this(name, - cpu, - ramSize, - speed, - rateMbps, - multicastRateMbps, - offerHA, - limitResourceUse, - volatileVm, - displayText, - provisioningType, - useLocalStorage, - recreatable, - tags, - systemUse, - vmType - ); this.hostTag = hostTag; - } - - public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, - VirtualMachine.Type vmType, String hostTag, String deploymentPlanner) { - this(name, - cpu, - ramSize, - speed, - rateMbps, - multicastRateMbps, - offerHA, - limitResourceUse, - volatileVm, - displayText, - provisioningType, - useLocalStorage, - recreatable, - tags, - systemUse, - vmType, - hostTag); this.deploymentPlanner = deploymentPlanner; + this.dynamicallyScalable = dynamicScalingEnabled; } public ServiceOfferingVO(ServiceOfferingVO offering) { @@ -189,6 +150,7 @@ public ServiceOfferingVO(ServiceOfferingVO offering) { volatileVm = offering.isVolatileVm(); hostTag = offering.getHostTag(); vmType = offering.getSystemVmType(); + dynamicallyScalable = offering.isDynamicallyScalable(); } @Override @@ -334,4 +296,13 @@ public void setDynamicFlag(boolean isdynamic) { public boolean isCustomCpuSpeedSupported() { return isCustomized() && getDetail("minCPU") != null; } + + @Override + public boolean isDynamicallyScalable() { + return dynamicallyScalable; + } + + public void setDynamicallyScalable(boolean dynamicallyScalable) { + this.dynamicallyScalable = dynamicallyScalable; + } } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java index 4ab5f4275917..494ffc6be230 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java @@ -189,6 +189,9 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject details = new HashMap(); @@ -284,4 +287,9 @@ public boolean isDynamic() { public void setDynamicFlag(boolean isdynamic) { isDynamic = isdynamic; } + + @Override + public boolean isDynamicallyScalable() { + return dynamicallyScalable; + } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java index 17def806c332..28f925915c95 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java @@ -374,7 +374,7 @@ protected UserVm createKubernetesNode(String joinIp, int nodeInstance) throws Ma nodeVm = 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); + null, addrs, null, null, null, customParameterMap, null, null, null, null, true); if (LOGGER.isInfoEnabled()) { LOGGER.info(String.format("Created node VM : %s, %s in the Kubernetes cluster : %s", hostName, nodeVm.getUuid(), kubernetesCluster.getName())); } 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 4a96b9ed2bab..a67375eb4c25 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,6 +72,7 @@ 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 { @@ -208,10 +209,11 @@ private UserVm createKubernetesMaster(final Network network, String serverIp) th logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); + Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && 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); + requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, dynamicScalingEnabled); if (LOGGER.isInfoEnabled()) { LOGGER.info(String.format("Created master VM ID: %s, %s in the Kubernetes cluster : %s", masterVm.getUuid(), hostName, kubernetesCluster.getName())); } @@ -262,10 +264,11 @@ private UserVm createKubernetesAdditionalMaster(final String joinIp, final int a logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); + Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && 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); + null, addrs, null, null, null, customParameterMap, null, null, null, null, dynamicScalingEnabled); 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/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 5c5ba55f1972..1f28deae78bc 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -1470,6 +1470,7 @@ public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { vmResponse.setState(vm.getState().toString()); } + vmResponse.setDynamicallyScalable(vm.isDynamicallyScalable()); // for console proxies, add the active sessions if (vm.getType() == Type.ConsoleProxy) { ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId()); diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 87b03748dbcd..7692f5448373 100644 --- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -113,6 +113,7 @@ public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offeringResponse.setObjectName("serviceoffering"); offeringResponse.setIscutomized(offering.isDynamic()); offeringResponse.setCacheMode(offering.getCacheMode()); + offeringResponse.setDynamicscalingenabled(offering.isDynamicallyScalable()); if (offeringDetails != null && !offeringDetails.isEmpty()) { String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY); diff --git a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java index 4d9b2cd5c0b6..e549bacdfbbd 100644 --- a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java +++ b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java @@ -193,6 +193,9 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit @Column(name = "root_disk_size") private Long rootDiskSize; + @Column(name = "dynamically_scalable") + private boolean dynamicallyScalable; + public ServiceOfferingJoinVO() { } @@ -397,4 +400,12 @@ public String getVsphereStoragePolicy() { public Long getRootDiskSize() { return rootDiskSize ; } + + public boolean isDynamicallyScalable() { + return dynamicallyScalable; + } + + public void setDynamicallyScalable(boolean dynamicallyScalable) { + this.dynamicallyScalable = dynamicallyScalable; + } } diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index f5de35af3ed2..668acc1676c8 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2481,7 +2481,7 @@ public ServiceOffering createServiceOffering(final CreateServiceOfferingCmd cmd) cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(), cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(), cmd.getIopsWriteRate(), cmd.getIopsWriteRateMax(), cmd.getIopsWriteRateMaxLength(), - cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode(), storagePolicyId); + cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode(), storagePolicyId, cmd.getDynamicScalingEnabled()); } protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType, @@ -2492,7 +2492,7 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, - final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID) { + final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID, final Boolean dynamicScalingEnabled) { // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); @@ -2524,7 +2524,7 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA, limitResourceUse, volatileVm, displayText, typedProvisioningType, localStorageRequired, false, tags, isSystem, vmType, - hostTag, deploymentPlanner); + hostTag, deploymentPlanner, dynamicScalingEnabled); if (Boolean.TRUE.equals(isCustomizedIops) || isCustomizedIops == null) { minIops = null; diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index 7d6c88870c0e..8e982f0cc19d 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -54,7 +54,6 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; -import com.cloud.vm.UserVmManager; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -258,7 +257,7 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { // Workaround to make sure the TO has the UUID we need for Niciri integration VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId()); // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global) - Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId()); + Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable(); to.setEnableDynamicallyScaleVm(isDynamicallyScalable); to.setUuid(vmInstance.getUuid()); diff --git a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java index c71054951619..5e7f0a952643 100644 --- a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java @@ -1325,18 +1325,18 @@ private long createNewVM(AutoScaleVmGroupVO asGroup) { vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, - null, true, null, null, null, null, null, null, null); + null, true, null, null, null, null, null, null, null, true); } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, - null, null, true, null, null, null, null, null, null, null); + null, null, true, null, null, null, null, null, null, null, true); } else { vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), - null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null, null); + null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null, null, true); } } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 0fecd604995d..9f732a384709 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1881,6 +1881,10 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); + if (newServiceOffering.isDynamicallyScalable() != currentServiceOffering.isDynamicallyScalable()) { + throw new InvalidParameterValueException("Unable to Scale VM: since dynamicscalingenabled flag is not same for new service offering and old service offering"); + } + int newCpu = newServiceOffering.getCpu(); int newMemory = newServiceOffering.getRamSize(); int newSpeed = newServiceOffering.getSpeed(); @@ -2764,10 +2768,6 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo userData = vm.getUserData(); } - if (isDynamicallyScalable == null) { - isDynamicallyScalable = vm.isDynamicallyScalable(); - } - if (osTypeId == null) { osTypeId = vm.getGuestOSId(); } @@ -2778,6 +2778,15 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo if (isDynamicallyScalable == null) { isDynamicallyScalable = vm.isDynamicallyScalable(); + } else { + if (isDynamicallyScalable == true) { + if (!offering.isDynamicallyScalable()) { + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since service offering is not dynamic scaling enabled"); + } + if (!UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId())) { + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since global configuration \"enable.dynamic.scale.vm\" is false"); + } + } } boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware); @@ -3226,7 +3235,7 @@ public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOff Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParametes, String customId, Map> dhcpOptionMap, - Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3275,7 +3284,7 @@ public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOff return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, dhcpOptionMap, - dataDiskTemplateToDiskOfferingMap, userVmOVFProperties); + dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled); } @@ -3285,7 +3294,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, - Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties) throws InsufficientCapacityException, ConcurrentOperationException, + Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3386,7 +3395,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap, - userVmOVFProperties); + userVmOVFProperties, dynamicScalingEnabled); } @Override @@ -3395,7 +3404,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List affinityGroupIdList, Map customParametrs, String customId, Map> dhcpOptionsMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFPropertiesMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map userVmOVFPropertiesMap, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3447,7 +3456,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, dhcpOptionsMap, - dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap); + dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap, dynamicScalingEnabled); } private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, Account owner, HypervisorType hypervisor, @@ -3562,11 +3571,11 @@ public void checkNameForRFCCompliance(String name) { @DB private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner, - Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, String userData, - String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, - List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, - Map datadiskTemplateToDiskOfferringMap, - Map userVmOVFPropertiesMap) throws InsufficientCapacityException, ResourceUnavailableException, + Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, String userData, + String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, + List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, + Map datadiskTemplateToDiskOfferringMap, + Map userVmOVFPropertiesMap, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, true, owner); @@ -3926,9 +3935,11 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe } } + dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(dynamicScalingEnabled, 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, - datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap); + datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled); // Assign instance to the group try { @@ -3952,6 +3963,15 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe return vm; } + private Boolean checkIfDynamicScalingCanBeEnabled(Boolean dynamicScalingEnabled, ServiceOfferingVO offering, VMTemplateVO template, Long zoneId) { + if (dynamicScalingEnabled) { + if (!(offering.isDynamicallyScalable() && 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"); + } + } + return dynamicScalingEnabled && offering.isDynamicallyScalable() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + } + /** * Configures the Root disk size via User`s custom parameters. * If the Service Offering has the Root Disk size field configured then the User`s root disk custom parameter is overwritten by the service offering. @@ -4030,14 +4050,14 @@ private UserVmVO commitUserVm(final boolean isImport, final DataCenter zone, fin final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map customParameters, final Map> extraDhcpOptionMap, final Map dataDiskTemplateToDiskOfferingMap, - final Map userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState) throws InsufficientCapacityException { + final Map userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final Boolean dynamicScalingEnabled) throws InsufficientCapacityException { return Transaction.execute(new TransactionCallbackWithException() { @Override public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(), offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, hostName, diskOfferingId); vm.setUuid(uuidName); - vm.setDynamicallyScalable(template.isDynamicallyScalable()); + vm.setDynamicallyScalable(dynamicScalingEnabled); Map details = template.getDetails(); if (details != null && !details.isEmpty()) { @@ -4221,13 +4241,13 @@ private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplat final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map customParameters, final Map> extraDhcpOptionMap, final Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFPropertiesMap) throws InsufficientCapacityException { + Map userVmOVFPropertiesMap, final Boolean dynamicScalingEnabled) throws InsufficientCapacityException { return commitUserVm(false, zone, null, null, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap, - userVmOVFPropertiesMap, null); + userVmOVFPropertiesMap, null, dynamicScalingEnabled); } public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map customParameters) throws InvalidParameterValueException @@ -5312,6 +5332,8 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE Long templateId = cmd.getTemplateId(); + Boolean dynamicScalingEnabled = cmd.getDynamicScalingEnabled(); + VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId); // Make sure a valid template ID was specified if (template == null) { @@ -5389,14 +5411,14 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId, size , group , cmd.getHypervisor(), cmd.getHttpMethod(), userData , sshKeyPairName , cmd.getIpToNetworkMap(), addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), - dataDiskTemplateToDiskOfferingMap, userVmOVFProperties); + dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled); } } else { if (zone.isSecurityGroupEnabled()) { vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), - dataDiskTemplateToDiskOfferingMap, userVmOVFProperties); + dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled); } else { if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) { @@ -5404,7 +5426,7 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE } vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(), - cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties); + cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled); } } // check if this templateId has a child ISO @@ -7480,11 +7502,12 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach final String uuidName = _uuidMgr.generateUuid(UserVm.class, null); final Host lastHost = powerState != VirtualMachine.PowerState.PowerOn ? host : null; + final Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(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, id, instanceName, uuidName, hypervisorType, customParameters, - null, null, null, powerState); + null, null, null, powerState, dynamicScalingEnabled); } @Override diff --git a/server/src/test/java/com/cloud/deploy/DeploymentPlanningManagerImplTest.java b/server/src/test/java/com/cloud/deploy/DeploymentPlanningManagerImplTest.java index ab73e63f287a..97e15de6f846 100644 --- a/server/src/test/java/com/cloud/deploy/DeploymentPlanningManagerImplTest.java +++ b/server/src/test/java/com/cloud/deploy/DeploymentPlanningManagerImplTest.java @@ -214,7 +214,7 @@ public void dataCenterAvoidTest() throws InsufficientServerCapacityException, Af ServiceOfferingVO svcOffering = new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User, - null, "FirstFitPlanner"); + null, "FirstFitPlanner", true); Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); @@ -229,7 +229,7 @@ public void plannerCannotHandleTest() throws InsufficientServerCapacityException ServiceOfferingVO svcOffering = new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User, - null, "UserDispersingPlanner"); + null, "UserDispersingPlanner", true); Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); @@ -245,7 +245,7 @@ public void emptyClusterListTest() throws InsufficientServerCapacityException, A ServiceOfferingVO svcOffering = new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm", ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User, - null, "FirstFitPlanner"); + null, "FirstFitPlanner", true); Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); From 536ea98bcaba68c17e19a291578ab305fdf36a4c Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 1 Feb 2021 11:43:06 +0530 Subject: [PATCH 02/22] UI changes --- ui/src/views/compute/DeployVM.vue | 11 +++++++++++ ui/src/views/offering/AddComputeOffering.vue | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index c0965bfd593e..0c535ac3c082 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -509,6 +509,15 @@ v-decorator="['bootintosetup']"> + + + {{ $t('label.isdynamicallyscalable') }} + + + + + + @@ -675,6 +684,7 @@ export default { clusterId: null, zoneSelected: false, startvm: true, + dynamicscalingenabled: true, vm: { name: null, zoneid: null, @@ -1416,6 +1426,7 @@ export default { deployVmData.keyboard = values.keyboard deployVmData.boottype = values.boottype deployVmData.bootmode = values.bootmode + deployVmData.dynamicscalingenabled = values.dynamicscalingenabled if (values.userdata && values.userdata.length > 0) { deployVmData.userdata = encodeURIComponent(btoa(this.sanitizeReverse(values.userdata))) } diff --git a/ui/src/views/offering/AddComputeOffering.vue b/ui/src/views/offering/AddComputeOffering.vue index 1c13dc3dca16..060aee6c600e 100644 --- a/ui/src/views/offering/AddComputeOffering.vue +++ b/ui/src/views/offering/AddComputeOffering.vue @@ -532,6 +532,15 @@ + + + {{ $t('label.isdynamicallyscalable') }} + + + + + + {{ $t('label.hosttags') }} @@ -797,7 +806,8 @@ export default { ], vGpuVisible: false, vGpuTypes: [], - loading: false + loading: false, + dynamicscalingenabled: true } }, beforeCreate () { @@ -959,7 +969,8 @@ export default { cachemode: values.cachemode, customized: values.offeringtype !== 'fixed', offerha: values.offerha === true, - limitcpuuse: values.limitcpuuse === true + limitcpuuse: values.limitcpuuse === true, + dynamicscalingenabled: values.dynamicscalingenabled } // custom fields (begin) From c9e6d4d7366e6e7e0b1390b87552d01eaa6e3cf0 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 1 Feb 2021 13:05:02 +0530 Subject: [PATCH 03/22] UI changes, added new labels --- ui/public/locales/ar.json | 1 + ui/public/locales/ca.json | 1 + ui/public/locales/de_DE.json | 1 + ui/public/locales/en.json | 1 + ui/public/locales/es.json | 1 + ui/public/locales/fr_FR.json | 1 + ui/public/locales/hu.json | 1 + ui/public/locales/it_IT.json | 1 + ui/public/locales/ja_JP.json | 1 + ui/public/locales/nb_NO.json | 1 + ui/public/locales/nl_NL.json | 1 + ui/public/locales/pl.json | 1 + ui/public/locales/pt_BR.json | 1 + ui/public/locales/ru_RU.json | 1 + ui/public/locales/zh_CN.json | 1 + ui/src/config/section/offering.js | 2 +- ui/src/views/compute/DeployVM.vue | 4 ++-- ui/src/views/offering/AddComputeOffering.vue | 2 +- 18 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ui/public/locales/ar.json b/ui/public/locales/ar.json index bcb39769107a..eadfeef88b9b 100644 --- a/ui/public/locales/ar.json +++ b/ui/public/locales/ar.json @@ -659,6 +659,7 @@ "label.drag.new.position": "\u0627\u0633\u062d\u0628 \u0644\u0645\u0648\u0642\u0641 \u062c\u062f\u064a\u062f", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/ca.json b/ui/public/locales/ca.json index 1e312e9965b2..959740d3b105 100644 --- a/ui/public/locales/ca.json +++ b/ui/public/locales/ca.json @@ -659,6 +659,7 @@ "label.drag.new.position": "Arrosegar a la nova posici\u00f3", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/de_DE.json b/ui/public/locales/de_DE.json index 348b1075c56b..50711fc003b0 100644 --- a/ui/public/locales/de_DE.json +++ b/ui/public/locales/de_DE.json @@ -783,6 +783,7 @@ "label.drag.new.position": "Ziehe zu neuer Position", "label.driver": "Treiber", "label.duration.in.sec": "Dauer (in Sekunden)", +"label.dynamicscalingenabled": "Dynamische Skalierung aktiviert", "label.edit": "Bearbeiten", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "ACL-Regel bearbeiten", diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 190398287e62..e7ee6e834a6d 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -810,6 +810,7 @@ "label.drag.new.position": "Drag to new position", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/es.json b/ui/public/locales/es.json index c05967bf56c7..df225b90212f 100644 --- a/ui/public/locales/es.json +++ b/ui/public/locales/es.json @@ -670,6 +670,7 @@ "label.drag.new.position": "Arrastrar a una nueva ubicaci\u00f3n", "label.driver": "Controlador", "label.duration.in.sec": "Duraci\u00f3n (en seg)", +"label.dynamicscalingenabled": "Escalado din\u00e1mico habilitado", "label.edit": "Editar", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Editar regla ACL", diff --git a/ui/public/locales/fr_FR.json b/ui/public/locales/fr_FR.json index 447b864f29c7..138d515a96b1 100644 --- a/ui/public/locales/fr_FR.json +++ b/ui/public/locales/fr_FR.json @@ -659,6 +659,7 @@ "label.drag.new.position": "D\u00e9placer sur une autre position", "label.driver": "Pilote", "label.duration.in.sec": "Dur\u00e9e (en sec)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Modifier", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Modifier r\u00e8gle ACL", diff --git a/ui/public/locales/hu.json b/ui/public/locales/hu.json index 5a010ff1ee2c..46efd9049a16 100644 --- a/ui/public/locales/hu.json +++ b/ui/public/locales/hu.json @@ -658,6 +658,7 @@ "label.drag.new.position": "\u00daj helyre h\u00faz\u00e1s", "label.driver": "Driver", "label.duration.in.sec": "Id\u0151tartam (mp)", +"label.dynamicscalingenabled": "dinamikus méretezés engedélyezve", "label.edit": "Szerkeszt\u00e9s", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "ACL szab\u00e1ly szerkeszt\u00e9se", diff --git a/ui/public/locales/it_IT.json b/ui/public/locales/it_IT.json index a8308a0bc05e..da83f5ddd8f8 100644 --- a/ui/public/locales/it_IT.json +++ b/ui/public/locales/it_IT.json @@ -659,6 +659,7 @@ "label.drag.new.position": "Trascina nella nuova posizione", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Modifica", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/ja_JP.json b/ui/public/locales/ja_JP.json index 5b64375f80f2..89bb22be784e 100644 --- a/ui/public/locales/ja_JP.json +++ b/ui/public/locales/ja_JP.json @@ -658,6 +658,7 @@ "label.drag.new.position": "\u65b0\u3057\u3044\u4f4d\u7f6e\u306b\u30c9\u30e9\u30c3\u30b0", "label.driver": "Driver", "label.duration.in.sec": "\u6301\u7d9a\u6642\u9593(\u79d2)", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "\u7de8\u96c6", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "ACL \u898f\u5247\u306e\u7de8\u96c6", diff --git a/ui/public/locales/nb_NO.json b/ui/public/locales/nb_NO.json index 81cbbbe3668c..627a92ebdb35 100644 --- a/ui/public/locales/nb_NO.json +++ b/ui/public/locales/nb_NO.json @@ -658,6 +658,7 @@ "label.dpd": "D\u00f8d endepunkt-deteksjon", "label.drag.new.position": "Dra til ny posisjon", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Varighet (i sek.)", "label.edit": "Editer", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/nl_NL.json b/ui/public/locales/nl_NL.json index 07aae3063b00..89fcb701c44e 100644 --- a/ui/public/locales/nl_NL.json +++ b/ui/public/locales/nl_NL.json @@ -658,6 +658,7 @@ "label.dpd": "Dead Peer detectie", "label.drag.new.position": "Sleep naar nieuwe positie", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamisch schalen ingeschakeld\n", "label.duration.in.sec": "duur (in sec)", "label.edit": "Wijzig", "label.edit.acl.list": "Verander een ACL lijst", diff --git a/ui/public/locales/pl.json b/ui/public/locales/pl.json index 163f1a2a7274..179c1cec39fa 100644 --- a/ui/public/locales/pl.json +++ b/ui/public/locales/pl.json @@ -658,6 +658,7 @@ "label.dpd": "Dead Peer Detection", "label.drag.new.position": "Przenie\u015b w nowe miejsce", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Duration (in sec)", "label.edit": "Edytuj", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index 9dd3c63000e6..8b43e07fa9cb 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -657,6 +657,7 @@ "label.dpd": "Detec\u00e7\u00e3o de correspondente morto", "label.drag.new.position": "Arrastar para uma nova posi\u00e7\u00e3o", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Dura\u00e7\u00e3o (em seg)", "label.edit": "Editar", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/ru_RU.json b/ui/public/locales/ru_RU.json index 5fd7d81b7b8f..1fe07d11f98f 100644 --- a/ui/public/locales/ru_RU.json +++ b/ui/public/locales/ru_RU.json @@ -657,6 +657,7 @@ "label.dpd": "Dead Peer Detection", "label.drag.new.position": "\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Duration (in sec)", "label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/zh_CN.json b/ui/public/locales/zh_CN.json index 511a048b8424..dc0f9f9db64b 100644 --- a/ui/public/locales/zh_CN.json +++ b/ui/public/locales/zh_CN.json @@ -657,6 +657,7 @@ "label.dpd": "\u5931\u6548\u5bf9\u7b49\u4f53\u68c0\u6d4b", "label.drag.new.position": "\u62d6\u52a8\u5230\u65b0\u4f4d\u7f6e", "label.driver": "Driver", +"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "\u6301\u7eed\u65f6\u95f4 (\u79d2)", "label.edit": "\u7f16\u8f91", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index b8b2beff3d96..972c0c1fae56 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -31,7 +31,7 @@ export default { params: { isrecursive: 'true' }, columns: ['name', 'displaytext', 'cpunumber', 'cpuspeed', 'memory', 'domain', 'zone', 'order'], details: () => { - var fields = ['name', 'id', 'displaytext', 'offerha', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created'] + var fields = ['name', 'id', 'displaytext', 'offerha', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created', 'dynamicscalingenabled'] if (store.getters.apis.createServiceOffering && store.getters.apis.createServiceOffering.params.filter(x => x.name === 'storagepolicy').length > 0) { fields.splice(6, 0, 'vspherestoragepolicy') diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 0c535ac3c082..e6801b892032 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -511,8 +511,8 @@ - {{ $t('label.isdynamicallyscalable') }} - + {{ $t('label.dynamicscalingenabled') }} + diff --git a/ui/src/views/offering/AddComputeOffering.vue b/ui/src/views/offering/AddComputeOffering.vue index 060aee6c600e..c61d2d10a07f 100644 --- a/ui/src/views/offering/AddComputeOffering.vue +++ b/ui/src/views/offering/AddComputeOffering.vue @@ -534,7 +534,7 @@ - {{ $t('label.isdynamicallyscalable') }} + {{ $t('label.dynamicscalingenabled') }} From a397324b5b98bd5d09c33c86f662035e091ed1ef Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 1 Feb 2021 15:15:40 +0530 Subject: [PATCH 04/22] Added response param in UI for system service offering --- ui/src/config/section/offering.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index 972c0c1fae56..f495841e49b3 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -87,7 +87,7 @@ export default { permission: ['listServiceOfferings', 'listInfrastructure'], params: { issystem: 'true', isrecursive: 'true' }, columns: ['name', 'systemvmtype', 'cpunumber', 'cpuspeed', 'memory', 'storagetype', 'order'], - details: ['name', 'id', 'displaytext', 'systemvmtype', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created'], + details: ['name', 'id', 'displaytext', 'systemvmtype', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created', 'dynamicscalingenabled'], actions: [{ api: 'createServiceOffering', icon: 'plus', From 5794c4a23e87ba7e70270eb4ff720e56af161532 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 10:47:13 +0530 Subject: [PATCH 05/22] Filter service offerings based on dynamic scalable flag while listing offerings for scaling VM --- server/src/main/java/com/cloud/api/query/QueryManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index f204ead3055a..b200a4769220 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -2971,11 +2971,12 @@ private Pair, Integer> searchForServiceOfferingsInte // 1. Only return offerings with the same storage type than the storage pool where the VM's root volume is allocated sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, isRootVolumeUsingLocalStorage); - // 2.In case vm is running return only offerings greater than equal to current offering compute. + // 2.In case vm is running return only offerings greater than equal to current offering compute and offering's dynamic scalability should match if (vmInstance.getState() == VirtualMachine.State.Running) { sc.addAnd("cpu", Op.GTEQ, currentVmOffering.getCpu()); sc.addAnd("speed", Op.GTEQ, currentVmOffering.getSpeed()); sc.addAnd("ramSize", Op.GTEQ, currentVmOffering.getRamSize()); + sc.addAnd("dynamicallyScalable", Op.EQ, currentVmOffering.isDynamicallyScalable()); } } From 8f25bd1c19fce3cd673787a48d1c9e943c0a532e Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 10:56:57 +0530 Subject: [PATCH 06/22] Added tool tip during VM deployment --- ui/public/locales/en.json | 1 + ui/src/views/compute/DeployVM.vue | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index e7ee6e834a6d..9b5d0fe11b04 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -811,6 +811,7 @@ "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", "label.dynamicscalingenabled": "Dynamic Scaling Enabled", +"label.dynamicscalingenabled.tooltip": "VM can dynamically scale only when dynamic scalability is enabled on template, service offering and global setting", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index e6801b892032..ff7099ef200d 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -512,7 +512,7 @@ {{ $t('label.dynamicscalingenabled') }} - + From ea913091b248aa3325dcb600c93acb0b81cfef5d Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 13:02:43 +0530 Subject: [PATCH 07/22] Added dynamic scalable flag on template while updating stopped VM. Fixed some log messages --- .../src/main/java/com/cloud/vm/UserVmManagerImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 9f732a384709..e762b5acd59c 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1882,7 +1882,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); if (newServiceOffering.isDynamicallyScalable() != currentServiceOffering.isDynamicallyScalable()) { - throw new InvalidParameterValueException("Unable to Scale VM: since dynamicscalingenabled flag is not same for new service offering and old service offering"); + throw new InvalidParameterValueException("Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering"); } int newCpu = newServiceOffering.getCpu(); @@ -1936,7 +1936,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI // Check vm flag if (!vmInstance.isDynamicallyScalable()) { - throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling"); + throw new CloudRuntimeException("Unable to Scale the VM: " + vmInstance.getUuid() + " as VM is not configured to be dynamically scalable"); } // Check disable threshold for cluster is not crossed @@ -2780,11 +2780,15 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo isDynamicallyScalable = vm.isDynamicallyScalable(); } else { if (isDynamicallyScalable == true) { + VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId()); + if (!template.isDynamicallyScalable()) { + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since template is not dynamic scaling enabled"); + } if (!offering.isDynamicallyScalable()) { throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since service offering is not dynamic scaling enabled"); } if (!UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId())) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since global configuration \"enable.dynamic.scale.vm\" is false"); + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since corresponding global setting is false"); } } } From e3b2f505be1a614f99fe09b590fafc186b293bf4 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 13:47:02 +0530 Subject: [PATCH 08/22] Naming corrections for service offering response --- .../java/org/apache/cloudstack/api/ApiConstants.java | 2 +- .../admin/offering/CreateServiceOfferingCmd.java | 2 +- .../cloudstack/api/command/user/vm/DeployVMCmd.java | 2 +- .../api/response/ServiceOfferingResponse.java | 12 ++++++------ .../api/query/dao/ServiceOfferingJoinDaoImpl.java | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 006f58a28330..11fb44df0906 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -837,7 +837,7 @@ public class ApiConstants { public static final String CROSS_ZONES = "crossZones"; public static final String TEMPLATETYPE = "templatetype"; public static final String SOURCETEMPLATEID = "sourcetemplateid"; - public static final String DynamicScalingEnabled = "dynamicscalingenabled"; + public static final String DYNAMIC_SCALING_ENABLED = "dynamicscalingenabled"; public static final String POOL_TYPE ="pooltype"; 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 428309a3278b..253881e0959c 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,7 +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.DynamicScalingEnabled, + @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, 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 d6f3727128c7..1546c1c538b1 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,7 +235,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG @LogLevel(LogLevel.Log4jLevel.Off) private Map vAppNetworks; - @Parameter(name = ApiConstants.DynamicScalingEnabled, + @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, description = "true if virtual machine needs to be dynamically scalable") protected Boolean isDynamicScalingEnabled; diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 40be57c3975d..3e0113e65a75 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -204,9 +204,9 @@ public class ServiceOfferingResponse extends BaseResponse { @Param(description = "Root disk size in GB", since = "4.15") private Long rootDiskSize; - @SerializedName("dynamicscalingenabled") + @SerializedName(ApiConstants.DYNAMIC_SCALING_ENABLED) @Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory") - private Boolean dynamicscalingenabled; + private Boolean dynamicScalingEnabled; public ServiceOfferingResponse() { } @@ -479,11 +479,11 @@ public void setRootDiskSize(Long rootDiskSize) { this.rootDiskSize = rootDiskSize; } - public Boolean getDynamicscalingenabled() { - return dynamicscalingenabled; + public Boolean getDynamicScalingEnabled() { + return dynamicScalingEnabled; } - public void setDynamicscalingenabled(Boolean dynamicscalingenabled) { - this.dynamicscalingenabled = dynamicscalingenabled; + public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) { + this.dynamicScalingEnabled = dynamicScalingEnabled; } } diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 7692f5448373..fc1ddc7a7cb6 100644 --- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -113,7 +113,7 @@ public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offeringResponse.setObjectName("serviceoffering"); offeringResponse.setIscutomized(offering.isDynamic()); offeringResponse.setCacheMode(offering.getCacheMode()); - offeringResponse.setDynamicscalingenabled(offering.isDynamicallyScalable()); + offeringResponse.setDynamicScalingEnabled(offering.isDynamicallyScalable()); if (offeringDetails != null && !offeringDetails.isEmpty()) { String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY); From d63ca707640cfc06b7c6e8dfe50eb63459f01719 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 16:18:24 +0530 Subject: [PATCH 09/22] Changed name from dynamically scalable to dynamic scaling enabled for service offering VO and its usages --- .../java/com/cloud/offering/ServiceOffering.java | 2 +- .../api/command/user/vm/DeployVMCmd.java | 6 +++--- .../com/cloud/vm/VirtualMachineManagerImpl.java | 2 +- .../com/cloud/service/ServiceOfferingVO.java | 16 ++++++++-------- .../META-INF/db/schema-41510to41600.sql | 4 ++-- .../cloudstack/quota/vo/ServiceOfferingVO.java | 8 ++++---- .../KubernetesClusterStartWorker.java | 4 ++-- .../com/cloud/api/query/QueryManagerImpl.java | 2 +- .../query/dao/ServiceOfferingJoinDaoImpl.java | 2 +- .../api/query/vo/ServiceOfferingJoinVO.java | 12 ++++++------ .../java/com/cloud/vm/UserVmManagerImpl.java | 10 +++++----- 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/api/src/main/java/com/cloud/offering/ServiceOffering.java b/api/src/main/java/com/cloud/offering/ServiceOffering.java index 163762202b04..7bad77fef30e 100644 --- a/api/src/main/java/com/cloud/offering/ServiceOffering.java +++ b/api/src/main/java/com/cloud/offering/ServiceOffering.java @@ -117,5 +117,5 @@ public enum StorageType { boolean isDynamic(); - boolean isDynamicallyScalable(); + 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 1546c1c538b1..346d49ca6c5d 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 @@ -238,7 +238,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG @Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, description = "true if virtual machine needs to be dynamically scalable") - protected Boolean isDynamicScalingEnabled; + protected Boolean dynamicScalingEnabled; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -628,8 +628,8 @@ public Boolean getBootIntoSetup() { return bootIntoSetup; } - public Boolean getDynamicScalingEnabled() { - return isDynamicScalingEnabled == null ? Boolean.TRUE : isDynamicScalingEnabled; + public Boolean isDynamicScalingEnabled() { + return dynamicScalingEnabled == null ? Boolean.TRUE : 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 4c1ce803dcac..cc938a9974c1 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,7 @@ public boolean upgradeVmDb(final long vmId, final ServiceOffering newServiceOffe if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { removeCustomOfferingDetails(vmId); } - Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && newServiceOffering.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vmForUpdate.getDataCenterId()); + Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && newServiceOffering.isDynamicScalingEnabled() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vmForUpdate.getDataCenterId()); vmForUpdate.setDynamicallyScalable(dynamicScalingEnabled); return _vmDao.update(vmId, vmForUpdate); } diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java index c265bcd290d5..9f4f765a9cd8 100644 --- a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java @@ -75,8 +75,8 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering @Column(name = "deployment_planner") private String deploymentPlanner = null; - @Column(name = "dynamically_scalable") - private boolean dynamicallyScalable; + @Column(name = "dynamic_scaling_enabled") + private boolean dynamicScalingEnabled; // This is a delayed load value. If the value is null, // then this field has not been loaded yet. @@ -123,7 +123,7 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee this.vmType = vmType == null ? null : vmType.toString().toLowerCase(); this.hostTag = hostTag; this.deploymentPlanner = deploymentPlanner; - this.dynamicallyScalable = dynamicScalingEnabled; + this.dynamicScalingEnabled = dynamicScalingEnabled; } public ServiceOfferingVO(ServiceOfferingVO offering) { @@ -150,7 +150,7 @@ public ServiceOfferingVO(ServiceOfferingVO offering) { volatileVm = offering.isVolatileVm(); hostTag = offering.getHostTag(); vmType = offering.getSystemVmType(); - dynamicallyScalable = offering.isDynamicallyScalable(); + dynamicScalingEnabled = offering.isDynamicScalingEnabled(); } @Override @@ -298,11 +298,11 @@ public boolean isCustomCpuSpeedSupported() { } @Override - public boolean isDynamicallyScalable() { - return dynamicallyScalable; + public boolean isDynamicScalingEnabled() { + return dynamicScalingEnabled; } - public void setDynamicallyScalable(boolean dynamicallyScalable) { - this.dynamicallyScalable = dynamicallyScalable; + public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) { + this.dynamicScalingEnabled = dynamicScalingEnabled; } } diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql index 4c158d621493..d31a0f8c33b9 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql @@ -20,7 +20,7 @@ --; -- Adding dynamic scalable flag for service offering table -ALTER TABLE `cloud`.`service_offering` ADD COLUMN `dynamically_scalable` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT 'true(1) if VM needs to be dynamically scalable of cpu or memory'; +ALTER TABLE `cloud`.`service_offering` ADD COLUMN `dynamic_scaling_enabled` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT 'true(1) if VM needs to be dynamically scalable of cpu or memory'; DROP VIEW IF EXISTS `cloud`.`service_offering_view`; CREATE VIEW `cloud`.`service_offering_view` AS SELECT @@ -65,7 +65,7 @@ CREATE VIEW `cloud`.`service_offering_view` AS `service_offering`.`sort_key` AS `sort_key`, `service_offering`.`is_volatile` AS `is_volatile`, `service_offering`.`deployment_planner` AS `deployment_planner`, - `service_offering`.`dynamically_scalable` AS `dynamically_scalable`, + `service_offering`.`dynamic_scaling_enabled` AS `dynamic_scaling_enabled`, `vsphere_storage_policy`.`value` AS `vsphere_storage_policy`, GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id, GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid, diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java index 873aa38fea25..ab6b9311c69d 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java @@ -75,8 +75,8 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering @Column(name = "deployment_planner") private String deploymentPlanner = null; - @Column(name = "dynamically_scalable") - private boolean dynamicallyScalable; + @Column(name = "dynamic_scaling_enabled") + private boolean dynamicScalingEnabled; @Transient Map details = new HashMap(); @@ -289,7 +289,7 @@ public void setDynamicFlag(boolean isdynamic) { } @Override - public boolean isDynamicallyScalable() { - return dynamicallyScalable; + public boolean isDynamicScalingEnabled() { + return dynamicScalingEnabled; } } 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 a67375eb4c25..6021427bd32f 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 @@ -209,7 +209,7 @@ private UserVm createKubernetesMaster(final Network network, String serverIp) th logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); - Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && clusterTemplate.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); + 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(), @@ -264,7 +264,7 @@ private UserVm createKubernetesAdditionalMaster(final String joinIp, final int a logAndThrow(Level.ERROR, "Failed to read Kubernetes master configuration file", e); } String base64UserData = Base64.encodeBase64String(k8sMasterConfig.getBytes(StringUtils.getPreferredCharset())); - Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && clusterTemplate.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); + 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(), diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index b200a4769220..9e24e5c36c99 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -2976,7 +2976,7 @@ private Pair, Integer> searchForServiceOfferingsInte sc.addAnd("cpu", Op.GTEQ, currentVmOffering.getCpu()); sc.addAnd("speed", Op.GTEQ, currentVmOffering.getSpeed()); sc.addAnd("ramSize", Op.GTEQ, currentVmOffering.getRamSize()); - sc.addAnd("dynamicallyScalable", Op.EQ, currentVmOffering.isDynamicallyScalable()); + sc.addAnd("dynamicScalingEnabled", Op.EQ, currentVmOffering.isDynamicScalingEnabled()); } } diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index fc1ddc7a7cb6..55faa391df04 100644 --- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -113,7 +113,7 @@ public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offeringResponse.setObjectName("serviceoffering"); offeringResponse.setIscutomized(offering.isDynamic()); offeringResponse.setCacheMode(offering.getCacheMode()); - offeringResponse.setDynamicScalingEnabled(offering.isDynamicallyScalable()); + offeringResponse.setDynamicScalingEnabled(offering.isDynamicScalingEnabled()); if (offeringDetails != null && !offeringDetails.isEmpty()) { String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY); diff --git a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java index e549bacdfbbd..e9b2f2d79b66 100644 --- a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java +++ b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java @@ -193,8 +193,8 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit @Column(name = "root_disk_size") private Long rootDiskSize; - @Column(name = "dynamically_scalable") - private boolean dynamicallyScalable; + @Column(name = "dynamic_scaling_enabled") + private boolean dynamicScalingEnabled; public ServiceOfferingJoinVO() { } @@ -401,11 +401,11 @@ public Long getRootDiskSize() { return rootDiskSize ; } - public boolean isDynamicallyScalable() { - return dynamicallyScalable; + public boolean isDynamicScalingEnabled() { + return dynamicScalingEnabled; } - public void setDynamicallyScalable(boolean dynamicallyScalable) { - this.dynamicallyScalable = dynamicallyScalable; + public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) { + this.dynamicScalingEnabled = dynamicScalingEnabled; } } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index e762b5acd59c..b37252fda369 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1881,7 +1881,7 @@ private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingI _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); - if (newServiceOffering.isDynamicallyScalable() != currentServiceOffering.isDynamicallyScalable()) { + if (newServiceOffering.isDynamicScalingEnabled() != currentServiceOffering.isDynamicScalingEnabled()) { throw new InvalidParameterValueException("Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering"); } @@ -2784,7 +2784,7 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo if (!template.isDynamicallyScalable()) { throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since template is not dynamic scaling enabled"); } - if (!offering.isDynamicallyScalable()) { + if (!offering.isDynamicScalingEnabled()) { throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since service offering is not dynamic scaling enabled"); } if (!UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId())) { @@ -3969,11 +3969,11 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe private Boolean checkIfDynamicScalingCanBeEnabled(Boolean dynamicScalingEnabled, ServiceOfferingVO offering, VMTemplateVO template, Long zoneId) { if (dynamicScalingEnabled) { - if (!(offering.isDynamicallyScalable() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId))) { + 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"); } } - return dynamicScalingEnabled && offering.isDynamicallyScalable() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + return dynamicScalingEnabled && offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); } /** @@ -7506,7 +7506,7 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach final String uuidName = _uuidMgr.generateUuid(UserVm.class, null); final Host lastHost = powerState != VirtualMachine.PowerState.PowerOn ? host : null; - final Boolean dynamicScalingEnabled = serviceOffering.isDynamicallyScalable() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zone.getId()); + final Boolean dynamicScalingEnabled = serviceOffering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(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, From 667e741228ecf9673ccd00aa154e3f172c233d22 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 3 Feb 2021 16:25:55 +0530 Subject: [PATCH 10/22] Reverted 414 to 415 schema file empty line changes --- .../src/main/resources/META-INF/db/schema-41400to41500.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql index 055061f38b18..9ead785c0c43 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql @@ -842,4 +842,4 @@ ALTER TABLE `cloud_usage`.`cloud_usage` ADD COLUMN `is_hidden` smallint(1) NOT N UPDATE `cloud`.`data_center` JOIN (SELECT COUNT(1) AS count FROM `cloud`.`data_center` WHERE `sort_key` != 0) AS tbl_tmp SET `sort_key` = `id` WHERE count = 0; -- Fix description of volume.stats.interval which is in milliseconds not seconds -UPDATE `cloud`.`configuration` SET `description` = 'Interval (in milliseconds) to report volume statistics' WHERE `name` = 'volume.stats.interval'; \ No newline at end of file +UPDATE `cloud`.`configuration` SET `description` = 'Interval (in milliseconds) to report volume statistics' WHERE `name` = 'volume.stats.interval'; From 041105344dfcb4e2f73dd72ea91eec3f09ad0499 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 30 Apr 2021 12:41:10 +0530 Subject: [PATCH 11/22] Added marvin tests required for these changes --- test/integration/smoke/test_scale_vm.py | 211 ++++++++++++++++++++++++ tools/marvin/marvin/lib/base.py | 8 +- 2 files changed, 218 insertions(+), 1 deletion(-) diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index 64ab380b5414..05cd54b73e0c 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -107,6 +107,18 @@ def setUpClass(cls): value="true" ) + cls.small_offering_dynamic_scaling_disabled = ServiceOffering.create( + cls.apiclient, + cls.services["service_offerings"]["small"], + dynamicscalingenabled=False + ) + + cls.big_offering_dynamic_scaling_disabled = ServiceOffering.create( + cls.apiclient, + cls.services["service_offerings"]["small"], + dynamicscalingenabled=False + ) + # create a virtual machine cls.virtual_machine = VirtualMachine.create( cls.apiclient, @@ -117,6 +129,35 @@ def setUpClass(cls): mode=cls.services["mode"] ) + # create a virtual machine which cannot be dynamically scalable + cls.virtual_machine_with_service_offering_dynamic_scaling_disabled = VirtualMachine.create( + cls.apiclient, + cls.services["small"], + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.small_offering_dynamic_scaling_disabled.id, + mode=cls.services["mode"] + ) + + # create a virtual machine which cannot be dynamically scalable + cls.virtual_machine_not_dynamically_scalable = VirtualMachine.create( + cls.apiclient, + cls.services["small"], + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.small_offering.id, + mode=cls.services["mode"], + dynamicscalingenabled=False + ) + + cls._cleanup = [ + cls.small_offering, + cls.big_offering, + cls.small_offering_dynamic_scaling_disabled, + cls.big_offering_dynamic_scaling_disabled, + cls.account + ] + @classmethod def tearDownClass(cls): super(TestScaleVm,cls).tearDownClass() @@ -265,3 +306,173 @@ def test_01_scale_vm(self): "Check the state of VM" ) return + + @attr(tags=["advanced", "basic"], required_hardware="false") + def test_02_scale_vm(self): + """Test scale virtual machine which is created from a service offering for which dynamicscalingenabled is false. Scaling operation should fail. + """ + + # VirtualMachine should be updated to tell cloudstack + # it has PV tools + # available and successfully scaled. We will only mock + # that behaviour + # here but it is not expected in production since the VM + # scaling is not + # guaranteed until tools are installed, vm rebooted + + # If hypervisor is Vmware, then check if + # the vmware tools are installed and the process is running + # Vmware tools are necessary for scale VM operation + if self.hypervisor.lower() == "vmware": + sshClient = self.virtual_machine_with_service_offering_dynamic_scaling_disabled.get_ssh_client() + result = str( + sshClient.execute("service vmware-tools status")).lower() + self.debug("and result is: %s" % result) + if not "running" in result: + self.skipTest("Skipping scale VM operation because\ + VMware tools are not installed on the VM") + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id + ) + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + list_vm_response, + None, + "Check virtual machine is in listVirtualMachines" + ) + + vm_response = list_vm_response[0] + self.assertEqual( + vm_response.id, + self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id, + "Check virtual machine ID of scaled VM" + ) + + self.assertEqual( + vm_response.isdynamicallyscalable, + False, + "Check if VM is not dynamically scalable" + ) + + self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is disabled and VM state %s" % ( + self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id, + self.big_offering_dynamic_scaling_disabled.id, + self.virtual_machine.state + )) + + cmd = scaleVirtualMachine.scaleVirtualMachineCmd() + cmd.serviceofferingid = self.big_offering_dynamic_scaling_disabled.id + cmd.id = self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id + + try: + self.apiclient.scaleVirtualMachine(cmd) + except Exception as e: + if "LicenceRestriction" in str(e): + self.skipTest("Your XenServer License does not allow scaling") + else: + pass + else: + self.fail("Expected an exception to be thrown, failing") + + self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % ( + self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id, + self.big_offering.id, + self.virtual_machine.state + )) + + cmd = scaleVirtualMachine.scaleVirtualMachineCmd() + cmd.serviceofferingid = self.big_offering.id + cmd.id = self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id + + try: + self.apiclient.scaleVirtualMachine(cmd) + except Exception as e: + if "LicenceRestriction" in str(e): + self.skipTest("Your XenServer License does not allow scaling") + else: + pass + else: + self.fail("Expected an exception to be thrown, failing") + + return + + @attr(tags=["advanced", "basic"], required_hardware="false") + def test_03_scale_vm(self): + """Test scale virtual machine which is not dynamically scalable to a service offering. Scaling operation should fail. + """ + # Validate the following + # Scale up the vm which is not dynamically scalable and see if scaling operation fails + + # VirtualMachine should be updated to tell cloudstack + # it has PV tools + # available and successfully scaled. We will only mock + # that behaviour + # here but it is not expected in production since the VM + # scaling is not + # guaranteed until tools are installed, vm rebooted + + # If hypervisor is Vmware, then check if + # the vmware tools are installed and the process is running + # Vmware tools are necessary for scale VM operation + if self.hypervisor.lower() == "vmware": + sshClient = self.virtual_machine_not_dynamically_scalable.get_ssh_client() + result = str( + sshClient.execute("service vmware-tools status")).lower() + self.debug("and result is: %s" % result) + if not "running" in result: + self.skipTest("Skipping scale VM operation because\ + VMware tools are not installed on the VM") + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine_not_dynamically_scalable.id + ) + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + list_vm_response, + None, + "Check virtual machine is in listVirtualMachines" + ) + vm_response = list_vm_response[0] + self.assertEqual( + vm_response.id, + self.virtual_machine_not_dynamically_scalable.id, + "Check virtual machine ID of scaled VM" + ) + self.assertEqual( + vm_response.isdynamicallyscalable, + False, + "Check if VM is not dynamically scalable" + ) + + self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % ( + self.virtual_machine_not_dynamically_scalable.id, + self.big_offering.id, + self.virtual_machine.state + )) + + cmd = scaleVirtualMachine.scaleVirtualMachineCmd() + cmd.serviceofferingid = self.big_offering.id + cmd.id = self.virtual_machine_not_dynamically_scalable.id + + try: + self.apiclient.scaleVirtualMachine(cmd) + except Exception as e: + if "LicenceRestriction" in str(e): + self.skipTest("Your XenServer License does not allow scaling") + else: + pass + else: + self.fail("Expected an exception to be thrown, failing") + + return \ No newline at end of file diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 5a8db630a500..916af64d96cc 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -522,7 +522,7 @@ def create(cls, apiclient, services, templateid=None, accountid=None, method='GET', hypervisor=None, customcpunumber=None, customcpuspeed=None, custommemory=None, rootdisksize=None, rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={}, - properties=None, nicnetworklist=None, bootmode=None, boottype=None): + properties=None, nicnetworklist=None, bootmode=None, boottype=None, dynamicscalingenabled=None): """Create the instance""" cmd = deployVirtualMachine.deployVirtualMachineCmd() @@ -615,6 +615,9 @@ def create(cls, apiclient, services, templateid=None, accountid=None, if "dhcpoptionsnetworklist" in services: cmd.dhcpoptionsnetworklist = services["dhcpoptionsnetworklist"] + if dynamicscalingenabled is not None: + cmd.dynamicscalingenabled = dynamicscalingenabled + cmd.details = [{}] if customcpunumber: @@ -2293,6 +2296,9 @@ def create(cls, apiclient, services, tags=None, domainid=None, cacheMode=None, * if "offerha" in services: cmd.offerha = services["offerha"] + if "dynamicscalingenabled" in services: + cmd.dynamicscalingenabled = services["dynamicscalingenabled"] + # Service Offering private to that domain if domainid: cmd.domainid = domainid From a83173e8a676a9c61dd2d14fb75172deb9168260 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 5 Feb 2021 17:56:14 +0530 Subject: [PATCH 12/22] 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 253881e0959c..638319f02a07 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 346d49ca6c5d..789365fae58d 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 cc938a9974c1..41a7c8d627ca 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 boolean upgradeVmDb(final long vmId, final ServiceOffering newServiceOffe 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 6021427bd32f..307b4f13f2b7 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.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 @@ private UserVm createKubernetesMaster(final Network network, String serverIp) th 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 @@ private UserVm createKubernetesAdditionalMaster(final String joinIp, final int a 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 e4206efe5d84..ba720aebc3dc 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.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 @@ UserVm updateVirtualMachine(long id, String displayName, String group, Boolean h 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 b37252fda369..9fc2e56cbede 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 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe } } - 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 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe 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 UserVm restoreVirtualMachine(final Account caller, final long vmId, final 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 UserVm importVM(final DataCenter zone, final Host host, final VirtualMach 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, From 55ed16f219186a8d91078e90b3e3deadd231670e Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 8 Feb 2021 16:11:26 +0530 Subject: [PATCH 13/22] Fixed Boolean to boolean Added UI response parameter to system VMs --- .../main/java/com/cloud/vm/UserVmService.java | 6 ++--- .../java/com/cloud/vm/VirtualMachine.java | 2 +- .../api/command/user/vm/DeployVMCmd.java | 4 ++-- .../cloud/vm/VirtualMachineManagerImpl.java | 2 +- .../main/java/com/cloud/vm/VMInstanceVO.java | 5 ++-- .../cloud/entity/api/db/VMEntityVO.java | 2 +- .../main/java/com/cloud/vm/UserVmManager.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 24 +++++++++---------- ui/src/config/section/infra/systemVms.js | 2 +- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index da2591ecac88..0b48a4867c00 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -218,7 +218,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameter, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, + Map userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -300,7 +300,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, + Map userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -379,7 +379,7 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap, - Map templateOvfPropertiesMap, Boolean dynamicScalingEnabled) + Map templateOvfPropertiesMap, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; diff --git a/api/src/main/java/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java index 02f55377845a..79154cbee196 100644 --- a/api/src/main/java/com/cloud/vm/VirtualMachine.java +++ b/api/src/main/java/com/cloud/vm/VirtualMachine.java @@ -342,6 +342,6 @@ public boolean isUsedBySystem() { @Override boolean isDisplay(); - Boolean isDynamicallyScalable(); + boolean isDynamicallyScalable(); } 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 789365fae58d..733bddb45149 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 @@ -627,8 +627,8 @@ public Boolean getBootIntoSetup() { return bootIntoSetup; } - public Boolean isDynamicScalingEnabled() { - return dynamicScalingEnabled == null ? Boolean.TRUE : dynamicScalingEnabled; + public boolean isDynamicScalingEnabled() { + return dynamicScalingEnabled == null ? true : 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 41a7c8d627ca..2ca7f06eb743 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3917,7 +3917,7 @@ public boolean upgradeVmDb(final long vmId, final ServiceOffering newServiceOffe removeCustomOfferingDetails(vmId); } VMTemplateVO template = _templateDao.findById(vmForUpdate.getTemplateId()); - Boolean dynamicScalingEnabled = vmForUpdate.isDynamicallyScalable() && _userVmMgr.checkIfDynamicScalingCanBeEnabled(newServiceOffering, template, vmForUpdate.getDataCenterId()); + boolean dynamicScalingEnabled = _userVmMgr.checkIfDynamicScalingCanBeEnabled(vmForUpdate, newServiceOffering, template, vmForUpdate.getDataCenterId()); vmForUpdate.setDynamicallyScalable(dynamicScalingEnabled); return _vmDao.update(vmId, vmForUpdate); } diff --git a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java index 0e8dd4ee44a5..f60daec970a6 100644 --- a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java @@ -57,7 +57,8 @@ @Table(name = "vm_instance") @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32) -public class VMInstanceVO implements VirtualMachine, FiniteStateObject { +public class +VMInstanceVO implements VirtualMachine, FiniteStateObject { private static final Logger s_logger = Logger.getLogger(VMInstanceVO.class); @Id @TableGenerator(name = "vm_instance_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_instance_seq", allocationSize = 1) @@ -544,7 +545,7 @@ public void setDynamicallyScalable(boolean dynamicallyScalable) { this.dynamicallyScalable = dynamicallyScalable; } - public Boolean isDynamicallyScalable() { + public boolean isDynamicallyScalable() { return dynamicallyScalable; } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java index 494ffc6be230..67af516c33b5 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java @@ -565,7 +565,7 @@ public boolean isDisplay() { } @Override - public Boolean isDynamicallyScalable() { + public boolean isDynamicallyScalable() { return dynamicallyScalable; } diff --git a/server/src/main/java/com/cloud/vm/UserVmManager.java b/server/src/main/java/com/cloud/vm/UserVmManager.java index ba720aebc3dc..98b7cb2ad0d7 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManager.java +++ b/server/src/main/java/com/cloud/vm/UserVmManager.java @@ -127,6 +127,6 @@ UserVm updateVirtualMachine(long id, String displayName, String group, Boolean h HashMap> getVmNetworkStatistics(long hostId, String hostName, List vmIds); - Boolean checkIfDynamicScalingCanBeEnabled(ServiceOffering offering, VirtualMachineTemplate template, Long zoneId); + boolean checkIfDynamicScalingCanBeEnabled(VirtualMachine vm, 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 9fc2e56cbede..d85cd71b89b1 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3239,7 +3239,7 @@ public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOff Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParametes, String customId, Map> dhcpOptionMap, - Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3298,7 +3298,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, - Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, + Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3408,7 +3408,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair, Map requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List affinityGroupIdList, Map customParametrs, String customId, Map> dhcpOptionsMap, Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFPropertiesMap, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map userVmOVFPropertiesMap, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -3579,7 +3579,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap, Map datadiskTemplateToDiskOfferringMap, - Map userVmOVFPropertiesMap, Boolean dynamicScalingEnabled) throws InsufficientCapacityException, ResourceUnavailableException, + Map userVmOVFPropertiesMap, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, true, owner); @@ -3939,7 +3939,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe } } - dynamicScalingEnabled = dynamicScalingEnabled && checkIfDynamicScalingCanBeEnabled(offering, template, zone.getId()); + dynamicScalingEnabled = dynamicScalingEnabled && checkIfDynamicScalingCanBeEnabled(null, 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, @@ -3968,8 +3968,8 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe } @Override - public Boolean checkIfDynamicScalingCanBeEnabled(ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) { - Boolean canEnableDynamicScaling = offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + public boolean checkIfDynamicScalingCanBeEnabled(VirtualMachine vm, ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) { + boolean canEnableDynamicScaling = (vm != null? vm.isDynamicallyScalable():true) && 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"); } @@ -4055,7 +4055,7 @@ private UserVmVO commitUserVm(final boolean isImport, final DataCenter zone, fin final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map customParameters, final Map> extraDhcpOptionMap, final Map dataDiskTemplateToDiskOfferingMap, - final Map userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final Boolean dynamicScalingEnabled) throws InsufficientCapacityException { + final Map userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled) throws InsufficientCapacityException { return Transaction.execute(new TransactionCallbackWithException() { @Override public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { @@ -4246,7 +4246,7 @@ private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplat final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map customParameters, final Map> extraDhcpOptionMap, final Map dataDiskTemplateToDiskOfferingMap, - Map userVmOVFPropertiesMap, final Boolean dynamicScalingEnabled) throws InsufficientCapacityException { + Map userVmOVFPropertiesMap, final boolean dynamicScalingEnabled) throws InsufficientCapacityException { return commitUserVm(false, zone, null, null, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering, isIso, sshPublicKey, networkNicMap, @@ -5337,7 +5337,7 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE Long templateId = cmd.getTemplateId(); - Boolean dynamicScalingEnabled = cmd.getDynamicScalingEnabled(); + boolean dynamicScalingEnabled = cmd.isDynamicScalingEnabled(); VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId); // Make sure a valid template ID was specified @@ -7104,7 +7104,7 @@ public UserVm restoreVirtualMachine(final Account caller, final long vmId, final // 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()); + boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(vm, serviceOffering, newTemplate, vm.getDataCenterId()); vm.setDynamicallyScalable(dynamicScalingEnabled); _vmDao.update(vmId, vm); @@ -7512,7 +7512,7 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach final String uuidName = _uuidMgr.generateUuid(UserVm.class, null); final Host lastHost = powerState != VirtualMachine.PowerState.PowerOn ? host : null; - final Boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(serviceOffering, template, zone.getId()); + final Boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(null, 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, diff --git a/ui/src/config/section/infra/systemVms.js b/ui/src/config/section/infra/systemVms.js index 181b8e8dacea..cdde06805562 100644 --- a/ui/src/config/section/infra/systemVms.js +++ b/ui/src/config/section/infra/systemVms.js @@ -22,7 +22,7 @@ export default { docHelp: 'adminguide/systemvm.html', permission: ['listSystemVms'], columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'hostname', 'zonename'], - details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions'], + details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable'], actions: [ { api: 'startSystemVm', From 14d15aa9c2f8059749010ee85805f64342fcace2 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 8 Feb 2021 21:28:50 +0530 Subject: [PATCH 14/22] Formatting Changes --- engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java | 3 +-- .../main/java/com/cloud/hypervisor/HypervisorGuruBase.java | 4 +--- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java index f60daec970a6..aa2e7360bf4b 100644 --- a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java @@ -57,8 +57,7 @@ @Table(name = "vm_instance") @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32) -public class -VMInstanceVO implements VirtualMachine, FiniteStateObject { +public class VMInstanceVO implements VirtualMachine, FiniteStateObject { private static final Logger s_logger = Logger.getLogger(VMInstanceVO.class); @Id @TableGenerator(name = "vm_instance_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_instance_seq", allocationSize = 1) diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index 8e982f0cc19d..2a8b13e96ca1 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -256,9 +256,7 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { // Workaround to make sure the TO has the UUID we need for Niciri integration VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId()); - // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global) - Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable(); - to.setEnableDynamicallyScaleVm(isDynamicallyScalable); + to.setEnableDynamicallyScaleVm(vmInstance.isDynamicallyScalable()); to.setUuid(vmInstance.getUuid()); to.setVmData(vmProfile.getVmData()); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index d85cd71b89b1..1ca37258d39f 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3969,7 +3969,7 @@ private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffe @Override public boolean checkIfDynamicScalingCanBeEnabled(VirtualMachine vm, ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) { - boolean canEnableDynamicScaling = (vm != null? vm.isDynamicallyScalable():true) && offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId); + boolean canEnableDynamicScaling = (vm != null ? vm.isDynamicallyScalable() : true) && 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"); } From dcaa72ccabc46a18af23ae16e8a469c620a42fdd Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 10 Feb 2021 11:14:00 +0530 Subject: [PATCH 15/22] Set default value to true for dynamic scaling enabled column on ServiceOfferingVO --- .../src/main/java/com/cloud/service/ServiceOfferingVO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java index 9f4f765a9cd8..ff9481947a07 100644 --- a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java @@ -76,7 +76,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering private String deploymentPlanner = null; @Column(name = "dynamic_scaling_enabled") - private boolean dynamicScalingEnabled; + private boolean dynamicScalingEnabled = true; // This is a delayed load value. If the value is null, // then this field has not been loaded yet. From 1e84d8cf3774b1ca7862d2cfd806590e1d09a216 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Thu, 11 Feb 2021 11:30:06 +0530 Subject: [PATCH 16/22] Changes added to UI to show Scale VM icon to only VMs which are marked as dynamically scalable. --- ui/src/config/section/compute.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 3f97995cd160..4345b0118bce 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -286,7 +286,7 @@ export default { label: 'label.scale.vm', docHelp: 'adminguide/virtual_machines.html#how-to-dynamically-scale-cpu-and-ram', dataView: true, - show: (record) => { return ['Stopped'].includes(record.state) || (['Running'].includes(record.state) && record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC') }, + show: (record) => { return ['Stopped'].includes(record.state) || (['Running'].includes(record.state) && record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC' && record.isdynamicallyscalable) }, popup: true, component: () => import('@/views/compute/ScaleVM.vue') }, From cb693af78abe08827fc774869fbba9ecc5c49aac Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 30 Apr 2021 16:25:05 +0530 Subject: [PATCH 17/22] Updated marvin tests and removed redundant translations --- .../offering/CreateServiceOfferingCmd.java | 4 ++-- .../api/response/ServiceOfferingResponse.java | 2 +- .../com/cloud/service/ServiceOfferingVO.java | 2 +- .../configuration/ConfigurationManagerImpl.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 17 ++++++++++------- test/integration/smoke/test_scale_vm.py | 10 +++++----- ui/public/locales/ar.json | 1 - ui/public/locales/ca.json | 1 - ui/public/locales/fr_FR.json | 1 - ui/public/locales/it_IT.json | 1 - ui/public/locales/ja_JP.json | 1 - ui/public/locales/nb_NO.json | 1 - ui/public/locales/pl.json | 1 - ui/public/locales/pt_BR.json | 1 - ui/public/locales/ru_RU.json | 1 - ui/public/locales/zh_CN.json | 1 - 16 files changed, 20 insertions(+), 27 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 638319f02a07..b30156097f31 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 @@ -445,8 +445,8 @@ public Long getStoragePolicy() { return storagePolicy; } - public Boolean getDynamicScalingEnabled() { - return isDynamicScalingEnabled == null ? Boolean.TRUE : isDynamicScalingEnabled; + public boolean getDynamicScalingEnabled() { + return isDynamicScalingEnabled == null ? true : isDynamicScalingEnabled; } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 3e0113e65a75..59bd72ce88e6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -205,7 +205,7 @@ public class ServiceOfferingResponse extends BaseResponse { private Long rootDiskSize; @SerializedName(ApiConstants.DYNAMIC_SCALING_ENABLED) - @Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory") + @Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory", since = "4.16") private Boolean dynamicScalingEnabled; public ServiceOfferingResponse() { diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java index ff9481947a07..44f39a1050ba 100644 --- a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java @@ -110,7 +110,7 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, - VirtualMachine.Type vmType, String hostTag, String deploymentPlanner, Boolean dynamicScalingEnabled) { + VirtualMachine.Type vmType, String hostTag, String deploymentPlanner, boolean dynamicScalingEnabled) { super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true); this.cpu = cpu; this.ramSize = ramSize; diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 668acc1676c8..86bd210d3d2f 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2492,7 +2492,7 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, - final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID, final Boolean dynamicScalingEnabled) { + final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID, final boolean dynamicScalingEnabled) { // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 1ca37258d39f..ca8c474a94d1 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -7101,13 +7101,8 @@ public UserVm restoreVirtualMachine(final Account caller, final long vmId, final vm.setGuestOSId(template.getGuestOSId()); vm.setTemplateId(newTemplateId); } - // check if VM can be dynamically scalable with the new template - ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getServiceOfferingId()); - VMTemplateVO newTemplate = _templateDao.findById(newTemplateId); - boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(vm, serviceOffering, newTemplate, vm.getDataCenterId()); - vm.setDynamicallyScalable(dynamicScalingEnabled); - _vmDao.update(vmId, vm); - + // check and update VM if it can be dynamically scalable with the new template + updateVMDynamicallyScalabilityUsingTemplate(vm, newTemplateId); } else { newVol = volumeMgr.allocateDuplicateVolume(root, null); } @@ -7195,6 +7190,14 @@ public UserVm restoreVirtualMachine(final Account caller, final long vmId, final } + private void updateVMDynamicallyScalabilityUsingTemplate(UserVmVO vm, Long newTemplateId) { + ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getServiceOfferingId()); + VMTemplateVO newTemplate = _templateDao.findById(newTemplateId); + boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(vm, serviceOffering, newTemplate, vm.getDataCenterId()); + vm.setDynamicallyScalable(dynamicScalingEnabled); + _vmDao.update(vm.getId(), vm); + } + /** * Perform basic checkings to make sure restore is possible. If not, #InvalidParameterValueException is thrown. * diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index 05cd54b73e0c..6fb6ef3db348 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -160,6 +160,11 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): + Configurations.update( + cls.apiclient, + name="enable.dynamic.scale.vm", + value="false" + ) super(TestScaleVm,cls).tearDownClass() return @@ -173,11 +178,6 @@ def setUp(self): %s" % self.hypervisor) def tearDown(self): - Configurations.update( - self.apiclient, - name="enable.dynamic.scale.vm", - value="false" - ) # Clean up, terminate the created ISOs super(TestScaleVm,self).tearDown() return diff --git a/ui/public/locales/ar.json b/ui/public/locales/ar.json index eadfeef88b9b..bcb39769107a 100644 --- a/ui/public/locales/ar.json +++ b/ui/public/locales/ar.json @@ -659,7 +659,6 @@ "label.drag.new.position": "\u0627\u0633\u062d\u0628 \u0644\u0645\u0648\u0642\u0641 \u062c\u062f\u064a\u062f", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/ca.json b/ui/public/locales/ca.json index 959740d3b105..1e312e9965b2 100644 --- a/ui/public/locales/ca.json +++ b/ui/public/locales/ca.json @@ -659,7 +659,6 @@ "label.drag.new.position": "Arrosegar a la nova posici\u00f3", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/fr_FR.json b/ui/public/locales/fr_FR.json index 138d515a96b1..447b864f29c7 100644 --- a/ui/public/locales/fr_FR.json +++ b/ui/public/locales/fr_FR.json @@ -659,7 +659,6 @@ "label.drag.new.position": "D\u00e9placer sur une autre position", "label.driver": "Pilote", "label.duration.in.sec": "Dur\u00e9e (en sec)", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Modifier", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Modifier r\u00e8gle ACL", diff --git a/ui/public/locales/it_IT.json b/ui/public/locales/it_IT.json index da83f5ddd8f8..a8308a0bc05e 100644 --- a/ui/public/locales/it_IT.json +++ b/ui/public/locales/it_IT.json @@ -659,7 +659,6 @@ "label.drag.new.position": "Trascina nella nuova posizione", "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "Modifica", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/public/locales/ja_JP.json b/ui/public/locales/ja_JP.json index 89bb22be784e..5b64375f80f2 100644 --- a/ui/public/locales/ja_JP.json +++ b/ui/public/locales/ja_JP.json @@ -658,7 +658,6 @@ "label.drag.new.position": "\u65b0\u3057\u3044\u4f4d\u7f6e\u306b\u30c9\u30e9\u30c3\u30b0", "label.driver": "Driver", "label.duration.in.sec": "\u6301\u7d9a\u6642\u9593(\u79d2)", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.edit": "\u7de8\u96c6", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "ACL \u898f\u5247\u306e\u7de8\u96c6", diff --git a/ui/public/locales/nb_NO.json b/ui/public/locales/nb_NO.json index 627a92ebdb35..81cbbbe3668c 100644 --- a/ui/public/locales/nb_NO.json +++ b/ui/public/locales/nb_NO.json @@ -658,7 +658,6 @@ "label.dpd": "D\u00f8d endepunkt-deteksjon", "label.drag.new.position": "Dra til ny posisjon", "label.driver": "Driver", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Varighet (i sek.)", "label.edit": "Editer", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/pl.json b/ui/public/locales/pl.json index 179c1cec39fa..163f1a2a7274 100644 --- a/ui/public/locales/pl.json +++ b/ui/public/locales/pl.json @@ -658,7 +658,6 @@ "label.dpd": "Dead Peer Detection", "label.drag.new.position": "Przenie\u015b w nowe miejsce", "label.driver": "Driver", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Duration (in sec)", "label.edit": "Edytuj", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index 8b43e07fa9cb..9dd3c63000e6 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -657,7 +657,6 @@ "label.dpd": "Detec\u00e7\u00e3o de correspondente morto", "label.drag.new.position": "Arrastar para uma nova posi\u00e7\u00e3o", "label.driver": "Driver", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Dura\u00e7\u00e3o (em seg)", "label.edit": "Editar", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/ru_RU.json b/ui/public/locales/ru_RU.json index 1fe07d11f98f..5fd7d81b7b8f 100644 --- a/ui/public/locales/ru_RU.json +++ b/ui/public/locales/ru_RU.json @@ -657,7 +657,6 @@ "label.dpd": "Dead Peer Detection", "label.drag.new.position": "\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e", "label.driver": "Driver", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "Duration (in sec)", "label.edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c", "label.edit.acl.list": "Edit ACL List", diff --git a/ui/public/locales/zh_CN.json b/ui/public/locales/zh_CN.json index dc0f9f9db64b..511a048b8424 100644 --- a/ui/public/locales/zh_CN.json +++ b/ui/public/locales/zh_CN.json @@ -657,7 +657,6 @@ "label.dpd": "\u5931\u6548\u5bf9\u7b49\u4f53\u68c0\u6d4b", "label.drag.new.position": "\u62d6\u52a8\u5230\u65b0\u4f4d\u7f6e", "label.driver": "Driver", -"label.dynamicscalingenabled": "Dynamic Scaling Enabled", "label.duration.in.sec": "\u6301\u7eed\u65f6\u95f4 (\u79d2)", "label.edit": "\u7f16\u8f91", "label.edit.acl.list": "Edit ACL List", From 90da94d96090e1027d6d6fbd5579061d53f0369b Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 21 May 2021 13:52:49 +0530 Subject: [PATCH 18/22] Grey out enable dynamic scaling option on deploy VM wizard when service offering and template are not dynamically scalable --- ui/src/views/compute/DeployVM.vue | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index ff7099ef200d..0f61265f8975 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -516,7 +516,13 @@ - + + + { @@ -1189,6 +1205,9 @@ export default { this.instanceConfig = this.form.getFieldsValue() // ToDo: maybe initialize with some other defaults }) }, + isDynamicallyScalable () { + return this.serviceOffering && this.serviceOffering.dynamicscalingenabled && this.template && this.template.isdynamicallyscalable + }, async fetchDataByZone (zoneId) { this.fillValue('zoneid') this.options.zones = await this.fetchZones() From ced6630fead4ca1fda92fd1dd4d1c8a3b0992359 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 21 May 2021 14:06:03 +0530 Subject: [PATCH 19/22] Greyout Scale VM Icon on a running VM, if the VM is not configured to be dynamically scalable --- ui/src/components/view/ActionButton.vue | 4 +++- ui/src/config/section/compute.js | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/src/components/view/ActionButton.vue b/ui/src/components/view/ActionButton.vue index bf9f63b0fdd6..5202cc6001d2 100644 --- a/ui/src/components/view/ActionButton.vue +++ b/ui/src/components/view/ActionButton.vue @@ -39,7 +39,8 @@ action.showBadge && ( (!dataView && ((action.listView && ('show' in action ? action.show(resource, $store.getters) : true)) || (action.groupAction && selectedRowKeys.length > 0 && ('groupShow' in action ? action.show(resource, $store.getters) : true)))) || (dataView && action.dataView && ('show' in action ? action.show(resource, $store.getters) : true)) - )" > + )" + :disabled="'disabled' in action ? action.disabled(resource, $store.getters) : false" > 0 && ('groupShow' in action ? action.show(resource, $store.getters) : true)))) || (dataView && action.dataView && ('show' in action ? action.show(resource, $store.getters) : true)) )" + :disabled="'disabled' in action ? action.disabled(resource, $store.getters) : false" :type="action.icon === 'delete' ? 'danger' : (action.icon === 'plus' ? 'primary' : 'default')" :shape="!dataView && ['plus', 'user-add'].includes(action.icon) ? 'round' : 'circle'" style="margin-left: 5px" diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 4345b0118bce..db6ab88d7367 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -286,7 +286,8 @@ export default { label: 'label.scale.vm', docHelp: 'adminguide/virtual_machines.html#how-to-dynamically-scale-cpu-and-ram', dataView: true, - show: (record) => { return ['Stopped'].includes(record.state) || (['Running'].includes(record.state) && record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC' && record.isdynamicallyscalable) }, + show: (record) => { return ['Stopped'].includes(record.state) || (['Running'].includes(record.state) && record.hypervisor !== 'KVM' && record.hypervisor !== 'LXC') }, + disabled: (record) => { return !record.isdynamicallyscalable }, popup: true, component: () => import('@/views/compute/ScaleVM.vue') }, From 4b93c40676c1454ce5ae97e6bdcf1c719fb07ab5 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 24 May 2021 10:44:12 +0530 Subject: [PATCH 20/22] Add global setting value to the enable or disable the flag on UI --- ui/src/views/compute/DeployVM.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 0f61265f8975..bccd9287e675 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -726,7 +726,8 @@ export default { groups: [], keyboards: [], bootTypes: [], - bootModes: [] + bootModes: [], + dynamicScalingVmConfig: false }, rowCount: {}, loading: { @@ -908,6 +909,13 @@ export default { type: 'Routing' }, field: 'hostid' + }, + dynamicScalingVmConfig: { + list: 'listConfigurations', + options: { + zoneid: _.get(this.zone, 'id'), + name: 'enable.dynamic.scale.vm' + } } } }, @@ -986,6 +994,9 @@ export default { }, showSecurityGroupSection () { return (this.networks.length > 0 && this.zone.securitygroupsenabled) || (this.zone && this.zone.networktype === 'Basic') + }, + dynamicScalingVmConfigValue () { + return this.options.dynamicScalingVmConfig?.[0]?.value === 'true' } }, watch: { @@ -1206,7 +1217,7 @@ export default { }) }, isDynamicallyScalable () { - return this.serviceOffering && this.serviceOffering.dynamicscalingenabled && this.template && this.template.isdynamicallyscalable + return this.serviceOffering && this.serviceOffering.dynamicscalingenabled && this.template && this.template.isdynamicallyscalable && this.dynamicScalingVmConfigValue }, async fetchDataByZone (zoneId) { this.fillValue('zoneid') From 10d0953f4a2d139750af8f84852abb0b65c60eb3 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 26 May 2021 17:08:56 +0530 Subject: [PATCH 21/22] Grey out dynamic scale VM flag on Edit VM dialog if dynamic scaling is not enabled on template, service offering and global setting. --- .../api/command/user/vm/UpdateVMCmd.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 7 +-- ui/public/locales/en.json | 2 +- ui/src/views/compute/EditVM.vue | 44 ++++++++++++++++++- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index 3afee8ac8037..38d1a5d5dd4b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -89,7 +89,7 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction, @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, - description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory. This can be updated only when dynamic scaling is enabled on template, service offering and the corresponding global setting") protected Boolean isDynamicallyScalable; @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "new host name of the vm. The VM has to be stopped/started for this update to take affect", since = "4.4") diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index ca8c474a94d1..edd7813335a8 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -2782,13 +2782,14 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo if (isDynamicallyScalable == true) { VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId()); if (!template.isDynamicallyScalable()) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since template is not dynamic scaling enabled"); + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the VM since its template does not have dynamic scaling enabled"); } if (!offering.isDynamicScalingEnabled()) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since service offering is not dynamic scaling enabled"); + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the VM since its service offering does not have dynamic scaling enabled"); } if (!UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId())) { - throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled on the VM since corresponding global setting is false"); + s_logger.debug(String.format("Dynamic Scaling cannot be enabled for the VM %s since the global setting enable.dynamic.scale.vm is set to false", vm.getUuid())); + throw new InvalidParameterValueException("Dynamic Scaling cannot be enabled for the VM since corresponding global setting is set to false"); } } } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 9b5d0fe11b04..77334fb98767 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -811,7 +811,7 @@ "label.driver": "Driver", "label.duration.in.sec": "Duration (in sec)", "label.dynamicscalingenabled": "Dynamic Scaling Enabled", -"label.dynamicscalingenabled.tooltip": "VM can dynamically scale only when dynamic scalability is enabled on template, service offering and global setting", +"label.dynamicscalingenabled.tooltip": "VM can dynamically scale only when dynamic scaling is enabled on template, service offering and global setting", "label.edit": "Edit", "label.edit.acl.list": "Edit ACL List", "label.edit.acl.rule": "Edit ACL rule", diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue index c9f342ba3928..1aa654bfff53 100644 --- a/ui/src/views/compute/EditVM.vue +++ b/ui/src/views/compute/EditVM.vue @@ -72,7 +72,8 @@ + v-decorator="['isdynamicallyscalable']" + :disabled="!canDynamicScalingEnabled()" /> @@ -125,6 +126,9 @@ export default { }, data () { return { + serviceOffering: {}, + template: {}, + dynamicScalingVmConfig: false, loading: false, osTypes: { loading: false, @@ -151,6 +155,44 @@ export default { fetchData () { this.fetchOsTypes() this.fetchInstaceGroups() + this.fetchServiceOfferingData() + this.fetchTemplateData() + this.fetchDynamicScalingVmConfig() + }, + fetchServiceOfferingData () { + const params = {} + params.id = this.resource.serviceofferingid + params.isrecursive = true + var apiName = 'listServiceOfferings' + api(apiName, params).then(json => { + const offerings = json.listserviceofferingsresponse.serviceoffering + this.serviceOffering = offerings[0] + }) + }, + fetchTemplateData () { + const params = {} + console.log('templateid ' + this.resource.templateid) + params.id = this.resource.templateid + params.isrecursive = true + params.templatefilter = 'all' + var apiName = 'listTemplates' + api(apiName, params).then(json => { + const templateResponses = json.listtemplatesresponse.template + this.template = templateResponses[0] + }) + }, + fetchDynamicScalingVmConfig () { + const params = {} + params.name = 'enable.dynamic.scale.vm' + params.zoneid = this.resource.zoneid + var apiName = 'listConfigurations' + api(apiName, params).then(json => { + const configResponse = json.listconfigurationsresponse.configuration + this.dynamicScalingVmConfig = configResponse[0]?.value === 'true' + }) + }, + canDynamicScalingEnabled () { + return this.template.isdynamicallyscalable && this.serviceOffering.dynamicscalingenabled && this.dynamicScalingVmConfig }, fetchOsTypes () { this.osTypes.loading = true From d847caafc7b088e42887d9c5a51aa14e3033c774 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 28 May 2021 08:13:46 +0530 Subject: [PATCH 22/22] Fix test_scale.py for simulator environment --- test/integration/smoke/test_scale_vm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index 6fb6ef3db348..c9b1bf837ba3 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -67,6 +67,11 @@ def setUpClass(cls): if cls.template == FAILED: assert False, "get_template() failed to return template\ with description %s" % cls.services["ostype"] + cls.template = Template.update( + cls.template, + cls.apiclient, + isdynamicallyscalable='true' + ) else: cls.template = Template.register( cls.apiclient,