Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BE05E10DE9 for ; Fri, 29 Nov 2013 13:09:49 +0000 (UTC) Received: (qmail 44929 invoked by uid 500); 29 Nov 2013 13:09:48 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 44716 invoked by uid 500); 29 Nov 2013 13:09:41 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 44636 invoked by uid 99); 29 Nov 2013 13:09:39 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 29 Nov 2013 13:09:39 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 52CE59088D2; Fri, 29 Nov 2013 13:09:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: koushik@apache.org To: commits@cloudstack.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: git commit: updated refs/heads/4.3 to 72e0354 Date: Fri, 29 Nov 2013 13:09:39 +0000 (UTC) Updated Branches: refs/heads/4.3 814ae73dc -> 72e035466 CLOUDSTACK-5161 enable scaling and upgrading of a vm using custom offering Signed-off-by: Koushik Das Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/72e03546 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/72e03546 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/72e03546 Branch: refs/heads/4.3 Commit: 72e03546619f50fa24abc372eb35438ef02713f8 Parents: 814ae73 Author: Bharat Kumar Authored: Thu Nov 28 23:47:01 2013 +0530 Committer: Koushik Das Committed: Fri Nov 29 18:32:16 2013 +0530 ---------------------------------------------------------------------- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../admin/systemvm/ScaleSystemVMCmd.java | 23 +++ .../admin/systemvm/UpgradeSystemVMCmd.java | 23 +++ .../api/command/user/vm/ScaleVMCmd.java | 25 +++ .../api/command/user/vm/UpgradeVMCmd.java | 23 +++ .../api/response/ServiceOfferingResponse.java | 21 ++- .../src/com/cloud/vm/VirtualMachineManager.java | 4 +- .../com/cloud/vm/VirtualMachineManagerImpl.java | 9 +- .../cloud/entity/api/VMEntityManagerImpl.java | 1 + .../src/com/cloud/event/UsageEventVO.java | 6 +- .../com/cloud/service/ServiceOfferingVO.java | 17 +- .../cloud/service/dao/ServiceOfferingDao.java | 4 +- .../service/dao/ServiceOfferingDaoImpl.java | 29 ++-- .../src/com/cloud/storage/DiskOfferingVO.java | 16 ++ .../src/com/cloud/usage/UsageVMInstanceVO.java | 3 - .../query/dao/ServiceOfferingJoinDaoImpl.java | 1 + .../api/query/vo/ServiceOfferingJoinVO.java | 16 +- .../com/cloud/capacity/CapacityManagerImpl.java | 31 ++-- .../configuration/ConfigurationManagerImpl.java | 7 + .../com/cloud/server/ManagementServerImpl.java | 27 +++- server/src/com/cloud/vm/UserVmManager.java | 11 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 157 ++++++++++++++++--- server/test/com/cloud/vm/UserVmManagerTest.java | 6 +- usage/src/com/cloud/usage/UsageManagerImpl.java | 12 +- 24 files changed, 392 insertions(+), 81 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/ApiConstants.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 6f919c1..acb1423 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -71,6 +71,7 @@ public class ApiConstants { public static final String DISPLAY_VM = "displayvm"; public static final String DISPLAY_OFFERING = "displayoffering"; public static final String DISPLAY_VOLUME = "displayvolume"; + public static final String CUSTOM_PARAMETERS = "customparameters"; public static final String DNS1 = "dns1"; public static final String DNS2 = "dns2"; public static final String IP6_DNS1 = "ip6dns1"; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java index 212f129..2020622 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java @@ -39,6 +39,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "scaleSystemVm", responseObject=SystemVmResponse.class, description="Scale the service offering for a system vm (console proxy or secondary storage). " + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.") @@ -58,6 +63,9 @@ public class ScaleSystemVMCmd extends BaseAsyncCmd { required=true, description="the service offering ID to apply to the system vm") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -70,6 +78,21 @@ public class ScaleSystemVMCmd extends BaseAsyncCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java index 738b15d..531cddc 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java @@ -34,6 +34,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "changeServiceForSystemVm", responseObject=SystemVmResponse.class, description="Changes the service offering for a system vm (console proxy or secondary storage). " + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.") @@ -53,6 +58,9 @@ public class UpgradeSystemVMCmd extends BaseCmd { required=true, description="the service offering ID to apply to the system vm") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +73,21 @@ public class UpgradeSystemVMCmd extends BaseCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java index 44f5575..1716b61 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java @@ -29,7 +29,11 @@ import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; @APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=SuccessResponse.class) @@ -51,6 +55,9 @@ public class ScaleVMCmd extends BaseAsyncCmd { required=true, description="the ID of the service offering for the virtual machine") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS,type = BaseCmd.CommandType.MAP, description = "name value pairs of custom parameters for cpu,memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -63,6 +70,24 @@ public class ScaleVMCmd extends BaseAsyncCmd { return serviceOfferingId; } + //instead of reading a map directly we are using collections. + //it is because customParameters.values() cannot be cast to a map. + //it gives a exception + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java index 161131b..140931e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java @@ -34,6 +34,11 @@ import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + @APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " + "The virtual machine must be in a \"Stopped\" state for " + "this command to take effect.") @@ -53,6 +58,9 @@ public class UpgradeVMCmd extends BaseCmd { required=true, description="the service offering ID to apply to the virtual machine") private Long serviceOfferingId; + @Parameter(name=ApiConstants.CUSTOM_PARAMETERS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example customparameters[i].name=value") + private Map customParameters; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +73,21 @@ public class UpgradeVMCmd extends BaseCmd { return serviceOfferingId; } + public Map getCustomParameters() { + Map customparameterMap = new HashMap(); + if (customParameters != null && customParameters.size() !=0){ + Collection parameterCollection = customParameters.values(); + Iterator iter = parameterCollection.iterator(); + while (iter.hasNext()) { + HashMap value = (HashMap) iter.next(); + for (String key : value.keySet()) { + customparameterMap.put(key, value.get(key)); + } + } + } + return customparameterMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index e305ee9..1e12a67 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -39,13 +39,13 @@ public class ServiceOfferingResponse extends BaseResponse { private String displayText; @SerializedName("cpunumber") @Param(description="the number of CPU") - private int cpuNumber; + private Integer cpuNumber; @SerializedName("cpuspeed") @Param(description="the clock rate CPU speed in Mhz") - private int cpuSpeed; + private Integer cpuSpeed; @SerializedName("memory") @Param(description="the memory in MB") - private int memory; + private Integer memory; @SerializedName("created") @Param(description="the date this service offering was created") private Date created; @@ -104,6 +104,10 @@ public class ServiceOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.SERVICE_OFFERING_DETAILS) @Param(description = "additional key/value details tied with this service offering", since = "4.2.0") private Map details; + + @SerializedName("iscustomized") + @Param(description = "is true if the offering is customized", since = "4.3.0") + private Boolean isCustomized; public ServiceOfferingResponse(){ @@ -164,7 +168,7 @@ public class ServiceOfferingResponse extends BaseResponse { return cpuNumber; } - public void setCpuNumber(int cpuNumber) { + public void setCpuNumber(Integer cpuNumber) { this.cpuNumber = cpuNumber; } @@ -172,7 +176,7 @@ public class ServiceOfferingResponse extends BaseResponse { return cpuSpeed; } - public void setCpuSpeed(int cpuSpeed) { + public void setCpuSpeed(Integer cpuSpeed) { this.cpuSpeed = cpuSpeed; } @@ -180,7 +184,7 @@ public class ServiceOfferingResponse extends BaseResponse { return memory; } - public void setMemory(int memory) { + public void setMemory(Integer memory) { this.memory = memory; } @@ -288,4 +292,9 @@ public class ServiceOfferingResponse extends BaseResponse { this.details = details; } + public void setIscutomized(boolean iscutomized) { + this.isCustomized = iscutomized; + + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/api/src/com/cloud/vm/VirtualMachineManager.java ---------------------------------------------------------------------- diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index 00393bf..c982c2e 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -148,9 +148,9 @@ public interface VirtualMachineManager extends Manager { /** * @param vmInstance - * @param newServiceOfferingId + * @param newServiceOffering */ - void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId); + void checkIfCanUpgrade(VirtualMachine vmInstance, ServiceOffering newServiceOffering); /** * @param vmId http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index b92b41f..4e25493 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3004,10 +3004,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId) { - ServiceOfferingVO newServiceOffering = _offeringDao.findById(vmInstance.getId(), newServiceOfferingId); + public void checkIfCanUpgrade(VirtualMachine vmInstance, ServiceOffering newServiceOffering) { if (newServiceOffering == null) { - throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId); + throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOffering.getId()); } // Check that the VM is stopped / running @@ -3018,7 +3017,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } // Check if the service offering being upgraded to is what the VM is already running with - if (vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { + if (!newServiceOffering.isDynamic() && vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { if (s_logger.isInfoEnabled()) { s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + "service offering (" + newServiceOffering.getName() + ")"); } @@ -3720,7 +3719,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VMInstanceVO vm = _vmDao.findByUuid(vmUuid); long newServiceofferingId = vm.getServiceOfferingId(); - ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, newServiceofferingId); + ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), newServiceofferingId); HostVO hostVo = _hostDao.findById(vm.getHostId()); Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(hostVo.getClusterId()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java index e784295..fdccf89 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java @@ -147,6 +147,7 @@ public class VMEntityManagerImpl implements VMEntityManager { //FIXME: profile should work on VirtualMachineEntity VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid()); VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm); + vmProfile.setServiceOffering(_serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId())); DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null); if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/event/UsageEventVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/event/UsageEventVO.java b/engine/schema/src/com/cloud/event/UsageEventVO.java index 6fad8c9..8c3d3fb 100644 --- a/engine/schema/src/com/cloud/event/UsageEventVO.java +++ b/engine/schema/src/com/cloud/event/UsageEventVO.java @@ -31,7 +31,11 @@ import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="usage_event") public class UsageEventVO implements UsageEvent { - @Id + public enum DynamicParameters { + cpuSpeed, cpuNumber, memory + }; + + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id = -1; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/service/ServiceOfferingVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java index 66ab836..17b824b 100755 --- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java @@ -29,9 +29,6 @@ import com.cloud.vm.VirtualMachine; @DiscriminatorValue(value="Service") @PrimaryKeyJoinColumn(name="id") public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering { - public enum DynamicParameters { - cpuSpeed, cpuNumber, memory - }; @Column(name="cpu") private Integer cpu; @@ -132,6 +129,20 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering this.deploymentPlanner = deploymentPlanner; } + public ServiceOfferingVO(ServiceOfferingVO offering) { + super(offering.getId(), offering.getName(), offering.getDisplayText(), false, offering.getTags(), offering.isRecreatable(), offering.getUseLocalStorage(), offering.getSystemUse(), true, offering.getDomainId()); + this.cpu = offering.getCpu(); + this.ramSize = offering.getRamSize(); + this.speed = offering.getSpeed(); + this.rateMbps = offering.getRateMbps(); + this.multicastRateMbps = offering.getMulticastRateMbps(); + this.offerHA = offering.getOfferHA(); + this.limitCpuUse = offering.getLimitCpuUse(); + this.volatileVm = offering.getVolatileVm(); + this.hostTag = offering.getHostTag(); + this.vm_type = offering.getSystemVmType(); + } + @Override public boolean getOfferHA() { return offerHA; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java index c5c4cff..6e11e96 100644 --- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java +++ b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java @@ -36,6 +36,6 @@ public interface ServiceOfferingDao extends GenericDao void saveDetails(ServiceOfferingVO serviceOffering); ServiceOfferingVO findById(Long vmId, long serviceOfferingId); ServiceOfferingVO findByIdIncludingRemoved(Long vmId, long serviceOfferingId); - boolean isDynamic(long serviceOfferingId); - ServiceOfferingVO getcomputeOffering(long serviceOfferingId, Integer cpuCores, Integer cpuSpeed, Integer memory); + boolean isDynamic(long serviceOfferingId); + ServiceOfferingVO getcomputeOffering(ServiceOfferingVO serviceOffering, Map customParameters); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java index 917eaef..f4abd15 100644 --- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.persistence.EntityExistsException; +import com.cloud.event.UsageEventVO; import com.cloud.exception.InvalidParameterValueException; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.dao.UserVmDetailsDao; @@ -188,14 +189,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId); - offering.setCpu(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuNumber.name()))); - offering.setSpeed(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuSpeed.name()))); - offering.setRamSize(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.memory.name()))); - return offering; + return getcomputeOffering(offering, dynamicOffering); } return offering; } @@ -203,15 +202,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId); - offering.setCpu(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuNumber.name()))); - offering.setSpeed(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.cpuSpeed.name()))); - offering.setRamSize(Integer.parseInt(dynamicOffering.get(ServiceOfferingVO.DynamicParameters.memory.name()))); - return offering; - + return getcomputeOffering(offering, dynamicOffering); } return offering; } @@ -228,4 +224,19 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase customParameters) { + ServiceOfferingVO dummyoffering = new ServiceOfferingVO(serviceOffering); + dummyoffering.setDynamicFlag(true); + if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { + dummyoffering.setCpu(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()))); + } + if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { + dummyoffering.setSpeed(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))); + } + if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) { + dummyoffering.setRamSize(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name()))); + } + return dummyoffering; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/storage/DiskOfferingVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index b5b3451..3321cb4 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -184,6 +184,22 @@ public class DiskOfferingVO implements DiskOffering { state = State.Active; } + public DiskOfferingVO(long id, String name, String displayText, boolean mirrored, String tags, boolean recreatable, + boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) { + this.id = id; + type = Type.Service; + this.name = name; + this.displayText = displayText; + this.tags = tags; + this.recreatable = recreatable; + this.useLocalStorage = useLocalStorage; + this.systemUse = systemUse; + this.customized = customized; + this.domainId = domainId; + uuid = UUID.randomUUID().toString(); + state = State.Active; + } + @Override public State getState() { return state; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java index 1178cc8..3417521 100644 --- a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java +++ b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java @@ -27,9 +27,6 @@ import javax.persistence.TemporalType; @Entity @Table(name="usage_vm_instance") public class UsageVMInstanceVO { - public enum DynamicParameters { - cpuSpeed, cpuNumber, memory - }; @Column(name="usage_type") private int usageType; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 3bc6c78..2c6f0d4 100644 --- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -82,6 +82,7 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId()); String vmDetailCpu = vmDetails.get("cpuOvercommitRatio"); String vmDetailRam = vmDetails.get("memoryOvercommitRatio"); @@ -588,8 +591,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, } ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId()); if (so.isDynamic()) { - usedMemory += ((Integer.parseInt(vmDetails.get(ServiceOfferingVO.DynamicParameters.memory.name())) * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; - usedCpu += ((Integer.parseInt(vmDetails.get(ServiceOfferingVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(ServiceOfferingVO.DynamicParameters.cpuSpeed.name())))/cpuOvercommitRatio)*clusterCpuOvercommitRatio; + usedMemory += ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; + usedCpu += ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name())))/cpuOvercommitRatio)*clusterCpuOvercommitRatio; } else { usedMemory += ((so.getRamSize() * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; @@ -604,16 +607,24 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, for (VMInstanceVO vm : vmsByLastHostId) { long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime()) / 1000; if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) { - UserVmDetailVO vmDetailCpu = _userVmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio"); - UserVmDetailVO vmDetailRam = _userVmDetailsDao.findDetail(vm.getId(),"memoryOvercommitRatio"); + cpuOvercommitRatio = 1f; + ramOvercommitRatio = 1f; + Map vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId()); + String vmDetailCpu = vmDetails.get("cpuOvercommitRatio"); + String vmDetailRam = vmDetails.get("memoryOvercommitRatio"); if (vmDetailCpu != null ) { //if vmDetail_cpu is not null it means it is running in a overcommited cluster. - cpuOvercommitRatio = Float.parseFloat(vmDetailCpu.getValue()); - ramOvercommitRatio = Float.parseFloat(vmDetailRam.getValue()); + cpuOvercommitRatio = Float.parseFloat(vmDetailCpu); + ramOvercommitRatio = Float.parseFloat(vmDetailRam); } ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId()); - reservedMemory += ((so.getRamSize() * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; - reservedCpu += (so.getCpu() * so.getSpeed()/cpuOvercommitRatio)*clusterCpuOvercommitRatio; + if (so.isDynamic()) { + reservedMemory += ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; + reservedMemory += ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name())))/cpuOvercommitRatio)*clusterCpuOvercommitRatio; + }else { + reservedMemory += ((so.getRamSize() * 1024L * 1024L)/ramOvercommitRatio)*clusterRamOvercommitRatio; + reservedCpu += (so.getCpu() * so.getSpeed()/cpuOvercommitRatio)*clusterCpuOvercommitRatio; + } } else { // signal if not done already, that the VM has been stopped for skip.counting.hours, // hence capacity will not be reserved anymore. http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/src/com/cloud/configuration/ConfigurationManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 21651ad..9c45303 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2014,6 +2014,13 @@ ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, Co Integer cpuSpeed = cmd.getCpuSpeed(); Integer memory = cmd.getMemory(); + //restricting the createserviceoffering to allow setting all or none of the dynamic parameters to null + if (cpuNumber == null || cpuSpeed == null || memory == null) { + if (cpuNumber !=null || cpuSpeed !=null || memory !=null) { + throw new InvalidParameterValueException("For creating a custom compute offering cpu, cpu speed and memory all should be null"); + } + } + if ((cpuNumber != null) && ((cpuNumber.intValue() <=0) || (cpuNumber.intValue() > 2147483647))) { throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu number value between 1 and 2147483647"); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/src/com/cloud/server/ManagementServerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d083c11..1537f0e 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -42,6 +42,8 @@ import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -718,6 +720,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe AccountService _accountService; @Inject ConfigurationManager _configMgr; + @Inject + ServiceOfferingDao _offeringDao; @Inject DeploymentPlanningManager _dpMgr; @@ -3808,7 +3812,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (vmInstance.getHypervisorType() == HypervisorType.XenServer && vmInstance.getState().equals(State.Running)) { throw new InvalidParameterValueException("Dynamic Scaling operation is not permitted for this hypervisor on system vm"); } - boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId()); + boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId(), cmd.getCustomParameters()); if(result){ VirtualMachine vm = _vmInstanceDao.findById(cmd.getId()); return vm; @@ -3822,11 +3826,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public VirtualMachine upgradeSystemVM(UpgradeSystemVMCmd cmd) { Long systemVmId = cmd.getId(); Long serviceOfferingId = cmd.getServiceOfferingId(); - return upgradeStoppedSystemVm(systemVmId, serviceOfferingId); + return upgradeStoppedSystemVm(systemVmId, serviceOfferingId, cmd.getCustomParameters()); } - private VirtualMachine upgradeStoppedSystemVm(Long systemVmId, Long serviceOfferingId){ + private VirtualMachine upgradeStoppedSystemVm(Long systemVmId, Long serviceOfferingId, Map customparameters){ Account caller = CallContext.current().getCallingAccount(); VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(systemVmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); @@ -3837,10 +3841,25 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _accountMgr.checkAccess(caller, null, true, systemVm); // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(systemVm, serviceOfferingId); + ServiceOfferingVO newServiceOffering = _offeringDao.findById(serviceOfferingId); + ServiceOfferingVO currentServiceOffering = _offeringDao.findById(systemVmId,systemVm.getServiceOfferingId()); + if (newServiceOffering.isDynamic()){ + newServiceOffering.setDynamicFlag(true); + _userVmMgr.validateCustomParameters(newServiceOffering, customparameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customparameters); + } + _itMgr.checkIfCanUpgrade(systemVm, newServiceOffering); boolean result = _itMgr.upgradeVmDb(systemVmId, serviceOfferingId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + _userVmMgr.saveCustomOfferingDetails(systemVmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + _userVmMgr.removeCustomOfferingDetails(systemVmId); + } + if (result) { return _vmInstanceDao.findById(systemVmId); } else { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/src/com/cloud/vm/UserVmManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 485e633..1592910 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -20,6 +20,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.cloud.offering.ServiceOffering; +import com.cloud.service.ServiceOfferingVO; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.framework.config.ConfigKey; @@ -106,7 +108,7 @@ public interface UserVmManager extends UserVmService { Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; - boolean upgradeVirtualMachine(Long id, Long serviceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; + boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic); @@ -114,4 +116,11 @@ public interface UserVmManager extends UserVmService { UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, Boolean isDynamicallyScalable, HTTPMethod httpMethod)throws ResourceUnavailableException, InsufficientCapacityException; + //the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can + //find a common place for all the scaling and upgrading code of both user and systemvms. + void validateCustomParameters(ServiceOfferingVO serviceOffering, Map customParameters); + + public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering); + + public void removeCustomOfferingDetails(long vmId); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 485a345..ef9f936 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -268,6 +268,7 @@ import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import com.cloud.event.UsageEventVO; @Local(value = { UserVmManager.class, UserVmService.class }) public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable { @@ -769,6 +770,38 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override + public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map customParameters) { + if (customParameters.size() !=0 ) { + if (serviceOffering.getCpu() == null) { + String cpuNumber = customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()); + if ((cpuNumber == null) || (NumbersUtil.parseInt(cpuNumber, -1) <= 0 || NumbersUtil.parseInt(cpuNumber, -1) > 2147483647)) { + throw new InvalidParameterValueException("Invalid cpu cores value, specify a value between 1 and 2147483647"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { + throw new InvalidParameterValueException("The cpu cores of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + if (serviceOffering.getSpeed() == null) { + String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name()); + if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0 || NumbersUtil.parseInt(cpuSpeed, -1) > 2147483647 )) { + throw new InvalidParameterValueException("Invalid cpu speed value, specify a value between 1 and 2147483647"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { + throw new InvalidParameterValueException("The cpu speed of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + if (serviceOffering.getRamSize() == null) { + String memory = customParameters.get(UsageEventVO.DynamicParameters.memory.name()); + if (memory == null || (NumbersUtil.parseInt(memory, -1) < 32 || NumbersUtil.parseInt(memory, -1) > 2147483647)) { + throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and 2147483647 MB"); + } + } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())){ + throw new InvalidParameterValueException("The memory of this offering id:"+serviceOffering.getId()+" is not customizable. This is predefined in the template."); + } + } else { + throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering"); + } + } + + @Override @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "upgrading Vm") /* * TODO: cleanup eventually - Refactored API call @@ -790,7 +823,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(caller, null, true, vmInstance); // Check resource limits for CPU and Memory. + Map customParameters = cmd.getCustomParameters(); ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, cmd.getCustomParameters()); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); @@ -808,7 +847,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); // remove diskAndMemory VM snapshots List vmSnapshots = _vmSnapshotDao.findByVm(vmId); @@ -824,6 +863,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } _itMgr.upgradeVmDb(vmId, svcOffId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } // Increment or decrement CPU and Memory count accordingly. if (newCpu > currentCpu) { @@ -838,13 +884,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Generate usage event for VM upgrade - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_UPGRADE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), vmInstance.getHostName(), - vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(newServiceOffering, cmd.getCustomParameters(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE); return _vmDao.findById(vmInstance.getId()); } - private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId) throws ResourceAllocationException { + private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map customParameters) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); // Verify input parameters @@ -859,6 +904,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // Check resource limits for CPU and Memory. ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, customParameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); @@ -876,7 +926,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); // remove diskAndMemory VM snapshots List vmSnapshots = _vmSnapshotDao.findByVm(vmId); @@ -892,6 +942,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } _itMgr.upgradeVmDb(vmId, svcOffId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } // Increment or decrement CPU and Memory count accordingly. if (newCpu > currentCpu) { @@ -1170,18 +1227,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir Long newServiceOfferingId = cmd.getServiceOfferingId(); CallContext.current().setEventDetails("Vm Id: " + vmId); - boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId); + boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmd.getCustomParameters()); if(result){ UserVmVO vmInstance = _vmDao.findById(vmId); if(vmInstance.getState().equals(State.Stopped)){ // Generate usage event for VM upgrade - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_UPGRADE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), vmInstance.getHostName(), - vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(_offeringDao.findById(newServiceOfferingId), cmd.getCustomParameters(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE); } if(vmInstance.getState().equals(State.Running)){ // Generate usage event for Dynamic scaling of VM - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DYNAMIC_SCALE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), vmInstance.getHostName(), - vmInstance.getServiceOfferingId(), vmInstance.getTemplateId(), vmInstance.getHypervisorType().toString(), VirtualMachine.class.getName(), vmInstance.getUuid()); + generateUsageEvent(_offeringDao.findById(newServiceOfferingId), cmd.getCustomParameters(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE); } return vmInstance; } else { @@ -1226,22 +1281,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ + public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ // Verify input parameters VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); if (vmInstance.getState().equals(State.Stopped)) { - upgradeStoppedVirtualMachine(vmId, newServiceOfferingId); + upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters); return true; } if(vmInstance.getState().equals(State.Running)){ - return upgradeRunningVirtualMachine(vmId, newServiceOfferingId); + return upgradeRunningVirtualMachine(vmId, newServiceOfferingId, customParameters); } return false; } - private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ + private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId, Map customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException{ Account caller = CallContext.current().getCallingAccount(); VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); @@ -1251,11 +1306,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(caller, null, true, vmInstance); + //Check if its a scale "up" + ServiceOfferingVO newServiceOffering = (ServiceOfferingVO) _offeringDao.findById(newServiceOfferingId); + if (newServiceOffering.isDynamic()) { + newServiceOffering.setDynamicFlag(true); + validateCustomParameters(newServiceOffering, customParameters); + newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters); + } + // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, newServiceOfferingId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering); - //Check if its a scale "up" - ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, newServiceOfferingId); ServiceOffering currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); int newCpu = newServiceOffering.getCpu(); int newMemory = newServiceOffering.getRamSize(); @@ -1320,9 +1381,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // #3 scale the vm now _itMgr.upgradeVmDb(vmId, newServiceOfferingId); + if (newServiceOffering.isDynamic()) { + //save the custom values to the database. + saveCustomOfferingDetails(vmId, newServiceOffering); + } vmInstance = _vmInstanceDao.findById(vmId); _itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity); success = true; + if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } return success; }catch(InsufficientCapacityException e ){ s_logger.warn("Received exception while scaling ",e); @@ -1339,6 +1407,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (newCpu > currentCpu) { _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu)); } + if (newServiceOffering.isDynamic()) { + removeCustomOfferingDetails(vmId); + } if (newMemory > currentMemory) { _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory)); } @@ -1350,6 +1421,35 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return success; } + @Override + public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) { + //save the custom values to the database. + Map details = _uservmDetailsDao.listDetailsKeyPairs(vmId); + details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString()); + details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString()); + details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString()); + List detailList = new ArrayList(); + for (String key : details.keySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key)); + detailList.add(detailVO); + } + _uservmDetailsDao.saveDetails(detailList); + } + + @Override + public void removeCustomOfferingDetails(long vmId){ + Map details = _uservmDetailsDao.listDetailsKeyPairs(vmId); + details.remove(UsageEventVO.DynamicParameters.cpuNumber.name()); + details.remove(UsageEventVO.DynamicParameters.cpuSpeed.name()); + details.remove(UsageEventVO.DynamicParameters.memory.name()); + List detailList = new ArrayList(); + for (String key : details.keySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key)); + detailList.add(detailVO); + } + _uservmDetailsDao.saveDetails(detailList); + } + @Override public HashMap getVirtualMachineStatistics(long hostId, @@ -2757,10 +2857,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString())); - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); - details.add(new UserVmDetailVO(id, ServiceOfferingVO.DynamicParameters.memory.toString(), memory.toString())); - offering = _serviceOfferingDao.getcomputeOffering(serviceOffering.getId(), cpuNumber, cpuSpeed, memory); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString())); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString())); + details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.memory.toString(), memory.toString())); + offering.setCpu(cpuNumber); + offering.setRamSize(memory); + offering.setSpeed(cpuSpeed); offering.setDynamicFlag(true); } if (hostName != null) { @@ -2987,6 +3089,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir }); } + private void generateUsageEvent(ServiceOfferingVO serviceOffering, Map customParameters, UserVmVO vm, String eventType){ + if (!serviceOffering.isDynamic()) { + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); + } + else { + UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid(), customParameters); + } + } + private void validateUserData(String userData, HTTPMethod httpmethod) { byte[] decodedUserData = null; if (userData != null) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/server/test/com/cloud/vm/UserVmManagerTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 0a3ed3c..34090ef 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -113,6 +113,8 @@ public class UserVmManagerTest { @Mock ServiceOfferingDao _offeringDao; @Mock EntityManager _entityMgr; + @Mock + ServiceOfferingVO _offeringVo; @Mock ResourceLimitService _resourceLimitMgr; @Before @@ -360,13 +362,13 @@ public class UserVmManagerTest { doNothing().when(_accountMgr).checkAccess(_account, null, true, _templateMock); - doNothing().when(_itMgr).checkIfCanUpgrade(_vmMock, cmd.getServiceOfferingId()); + doNothing().when(_itMgr).checkIfCanUpgrade(_vmMock, _offeringVo); ServiceOffering so1 = getSvcoffering(512); ServiceOffering so2 = getSvcoffering(256); - when(_entityMgr.findById(eq(ServiceOffering.class), anyLong())).thenReturn(so1); + when(_offeringDao.findById(anyLong())).thenReturn((ServiceOfferingVO)so1); when(_offeringDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn((ServiceOfferingVO) so1); Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, UUID.randomUUID().toString()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/72e03546/usage/src/com/cloud/usage/UsageManagerImpl.java ---------------------------------------------------------------------- diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index ea04dd0..407237c 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -1074,14 +1074,14 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna Map usageDetails = _usageEventDetailsDao.findDetails(event.getId()); if (usageDetails != null && usageDetails.size() != 0) { - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name()) != null) { - cpuCores = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuNumber.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()) != null) { + cpuCores = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())); } - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name()) != null) { - cpuSpeed = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.cpuSpeed.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()) != null) { + cpuSpeed = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name())); } - if (usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name()) != null) { - memory = Long.parseLong(usageDetails.get(UsageVMInstanceVO.DynamicParameters.memory.name())); + if (usageDetails.get(UsageEventVO.DynamicParameters.memory.name()) != null) { + memory = Long.parseLong(usageDetails.get(UsageEventVO.DynamicParameters.memory.name())); } }