CLOUDSTACK-1645 : Resources limit is not validated with update compute offering [ Instances are updated to higher CPU/Memory resources though there are no resources available @ account/domain]
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/10561889 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/10561889 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/10561889 Branch: refs/heads/marvin-refactor Commit: 105618896bab9de790065c3913cc33eb878ead1b Parents: 98291d0 Author: Sanjay Tripathi <sanjay.tripa...@citrix.com> Authored: Wed Mar 13 12:51:49 2013 +0530 Committer: Min Chen <min.c...@citrix.com> Committed: Thu Mar 14 13:44:34 2013 -0700 ---------------------------------------------------------------------- api/src/com/cloud/vm/UserVmService.java | 3 +- .../api/command/user/vm/UpgradeVMCmd.java | 4 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 32 ++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/10561889/api/src/com/cloud/vm/UserVmService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index ea89eda..9d6b221 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -356,8 +356,9 @@ public interface UserVmService { * @param cmd * - the command specifying vmId and new serviceOfferingId * @return the vm + * @throws ResourceAllocationException */ - UserVm upgradeVirtualMachine(UpgradeVMCmd cmd); + UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException; UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/10561889/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 6719b8f..fb62000 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 @@ -22,12 +22,12 @@ import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -88,7 +88,7 @@ public class UpgradeVMCmd extends BaseCmd { } @Override - public void execute(){ + public void execute() throws ResourceAllocationException{ UserContext.current().setEventDetails("Vm Id: "+getId()); ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/10561889/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 88086ce..82a69bd 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -750,7 +750,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use /* * TODO: cleanup eventually - Refactored API call */ - public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) { + public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException { Long vmId = cmd.getId(); Long svcOffId = cmd.getServiceOfferingId(); Account caller = UserContext.current().getCaller(); @@ -764,6 +764,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _accountMgr.checkAccess(caller, null, true, vmInstance); + // Check resource limits for CPU and Memory. + ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); + + int newCpu = newServiceOffering.getCpu(); + int newMemory = newServiceOffering.getRamSize(); + int currentCpu = currentServiceOffering.getCpu(); + int currentMemory = currentServiceOffering.getRamSize(); + + if (newCpu > currentCpu) { + _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, + newCpu - currentCpu); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, + newMemory - currentMemory); + } + // Check that the specified service offering ID is valid _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); @@ -782,6 +800,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _itMgr.upgradeVmDb(vmId, svcOffId); + // Increment or decrement CPU and Memory count accordingly. + if (newCpu > currentCpu) { + _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu)); + } else if (currentCpu > newCpu) { + _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (currentCpu - newCpu)); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory)); + } else if (currentMemory > newMemory) { + _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (currentMemory - newMemory)); + } + return _vmDao.findById(vmInstance.getId()); }