Updated Branches: refs/heads/scaleupvm 6bf8ff623 -> bffc09c61
CLOUDSTACK-658 - Adding capacity related changes Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/bffc09c6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/bffc09c6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/bffc09c6 Branch: refs/heads/scaleupvm Commit: bffc09c61aec8dd59788c1cb7c89474fdee60991 Parents: 6bf8ff6 Author: Nitin Mehta <nitin.me...@citrix.com> Authored: Mon Mar 18 20:09:23 2013 +0530 Committer: Nitin Mehta <nitin.me...@citrix.com> Committed: Mon Mar 18 20:09:23 2013 +0530 ---------------------------------------------------------------------- api/src/com/cloud/agent/api/ScaleVmCommand.java | 6 +- api/src/com/cloud/vm/VirtualMachine.java | 5 - server/src/com/cloud/vm/UserVmManagerImpl.java | 39 +++--- server/src/com/cloud/vm/VirtualMachineManager.java | 2 +- .../com/cloud/vm/VirtualMachineManagerImpl.java | 104 ++++++++------- 5 files changed, 81 insertions(+), 75 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bffc09c6/api/src/com/cloud/agent/api/ScaleVmCommand.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/agent/api/ScaleVmCommand.java b/api/src/com/cloud/agent/api/ScaleVmCommand.java index e5078d5..35d22ad 100644 --- a/api/src/com/cloud/agent/api/ScaleVmCommand.java +++ b/api/src/com/cloud/agent/api/ScaleVmCommand.java @@ -40,14 +40,14 @@ public class ScaleVmCommand extends Command { } public ScaleVmCommand(String vmName, int cpus, - Integer speed, long minRam, long maxRam) { + Integer speed, long minRam, long maxRam, boolean limitCpuUse) { super(); this.vmName = vmName; this.cpus = cpus; - //this.speed = speed; + this.speed = speed; this.minRam = minRam; this.maxRam = maxRam; - this.vm = new VirtualMachineTO(1L, vmName, null, cpus, null, minRam, maxRam, null, null, false, false, null); + this.vm = new VirtualMachineTO(1L, vmName, null, cpus, speed, minRam, maxRam, null, null, false, false, null); /*vm.setName(vmName); vm.setCpus(cpus); vm.setRam(minRam, maxRam);*/ http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bffc09c6/api/src/com/cloud/vm/VirtualMachine.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index ef22672..8f807d4 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -41,7 +41,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I Destroyed(false, "VM is marked for destroy."), Expunging(true, "VM is being expunged."), Migrating(true, "VM is being migrated. host id holds to from host"), - Reconfiguring(true, "VM is being reconfigured to a new service offering"), Error(false, "VM is in error"), Unknown(false, "VM state is unknown."), Shutdowned(false, "VM is shutdowned from inside"); @@ -96,9 +95,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping); s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running); - s_fsm.addTransition(State.Running, VirtualMachine.Event.ReconfiguringRequested, State.Reconfiguring); - s_fsm.addTransition(State.Reconfiguring, VirtualMachine.Event.OperationSucceeded, State.Running); - s_fsm.addTransition(State.Reconfiguring, VirtualMachine.Event.OperationFailed, State.Running); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running); @@ -181,7 +177,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I AgentReportMigrated, RevertRequested, SnapshotRequested, - ReconfiguringRequested }; public enum Type { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bffc09c6/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 e38231c..6e9cd43 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -339,7 +339,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use @Inject protected SecurityGroupDao _securityGroupDao; @Inject - protected CapacityManager _capacityMgr;; + protected CapacityManager _capacityMgr; @Inject protected VMInstanceDao _vmInstanceDao; @Inject @@ -1043,7 +1043,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws InvalidParameterValueException { Long vmId = cmd.getId(); - Long newSvcOffId = cmd.getServiceOfferingId(); + Long newServiceOfferingId = cmd.getServiceOfferingId(); Account caller = UserContext.current().getCaller(); // Verify input parameters @@ -1055,14 +1055,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _accountMgr.checkAccess(caller, null, true, vmInstance); // Check that the specified service offering ID is valid - _itMgr.checkIfCanUpgrade(vmInstance, newSvcOffId); + _itMgr.checkIfCanUpgrade(vmInstance, newServiceOfferingId); //Check if its a scale "up" - ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newSvcOffId); + ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newServiceOfferingId); ServiceOffering oldServiceOffering = _configMgr.getServiceOffering(vmInstance.getServiceOfferingId()); if(newServiceOffering.getSpeed() <= oldServiceOffering.getSpeed() && newServiceOffering.getRamSize() <= oldServiceOffering.getRamSize()){ - throw new InvalidParameterValueException("Only scaling up the vm is supported"); + throw new InvalidParameterValueException("Only scaling up the vm is supported, new service offering should have both cpu and memory greater than the old values"); } // Dynamically upgrade the running vms @@ -1073,38 +1073,41 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use try{ // #1 Check existing host has capacity boolean existingHostHasCapacity = _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), newServiceOffering.getSpeed() - oldServiceOffering.getSpeed(), - (newServiceOffering.getRamSize() - oldServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); + (newServiceOffering.getRamSize() - oldServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); // TO DO fill it with mem. // #2 migrate the vm if host doesn't have capacity if (!existingHostHasCapacity){ - vmInstance = _itMgr.scale(vmInstance.getType(), vmInstance, newSvcOffId); - }else{ - vmInstance.setSameHost(existingHostHasCapacity); + vmInstance = _itMgr.findHostAndMigrate(vmInstance.getType(), vmInstance, newServiceOfferingId); } // #3 scale the vm now - vmInstance = _itMgr.reConfigureVm(vmInstance, newServiceOffering, existingHostHasCapacity); + _itMgr.upgradeVmDb(vmId, newServiceOfferingId); + vmInstance = _vmInstanceDao.findById(vmId); + vmInstance = _itMgr.reConfigureVm(vmInstance, oldServiceOffering, existingHostHasCapacity); success = true; + return _vmDao.findById(vmInstance.getId()); }catch(InsufficientCapacityException e ){ - s_logger.warn("Recieved exception while scaling ",e); + s_logger.warn("Received exception while scaling ",e); } catch (ResourceUnavailableException e) { - s_logger.warn("Recieved exception while scaling ",e); + s_logger.warn("Received exception while scaling ",e); } catch (ConcurrentOperationException e) { - s_logger.warn("Recieved exception while scaling ",e); + s_logger.warn("Received exception while scaling ",e); } catch (VirtualMachineMigrationException e) { - s_logger.warn("Recieved exception while scaling ",e); + s_logger.warn("Received exception while scaling ",e); } catch (ManagementServerException e) { - s_logger.warn("Recieved exception while scaling ",e); + s_logger.warn("Received exception while scaling ",e); + }finally{ + if(!success){ + _itMgr.upgradeVmDb(vmId, oldServiceOffering.getId()); // rollback + } } } if (!success) return null; } - //Update the DB. - _itMgr.upgradeVmDb(vmId, newSvcOffId); - return _vmDao.findById(vmInstance.getId()); + } @Override http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bffc09c6/server/src/com/cloud/vm/VirtualMachineManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index b81d533..4a30d97 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -190,7 +190,7 @@ public interface VirtualMachineManager extends Manager { VMInstanceVO reConfigureVm(VMInstanceVO vm, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException; - VMInstanceVO scale(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, + VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bffc09c6/server/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 7631c2d..c845830 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -36,6 +36,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.capacity.CapacityManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -175,6 +176,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Inject protected UserVmDao _userVmDao; @Inject + protected CapacityManager _capacityMgr; + @Inject protected NicDao _nicsDao; @Inject protected AccountManager _accountMgr; @@ -2659,7 +2662,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public VMInstanceVO scale(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) + public VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException { VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm); @@ -2730,53 +2733,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public VMInstanceVO reConfigureVm(VMInstanceVO vm , ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException { - ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), - newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize()); - - Long dstHostId = vm.getHostId(); - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Reconfiguring, vm.getType(), vm.getId()); - work.setStep(Step.Prepare); - work.setResourceType(ItWorkVO.ResourceType.Host); - work.setResourceId(vm.getHostId()); - work = _workDao.persist(work); - boolean success = false; - try { - vm.setNewSvcOfferingId(newServiceOffering.getId()); // Capacity update should be delta (new - old) offering - changeState(vm, Event.ReconfiguringRequested, dstHostId, work, Step.Reconfiguring); - - Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd); - if (!reconfigureAnswer.getResult()) { - s_logger.error("Unable to reconfigure due to " + reconfigureAnswer.getDetails()); - return null; - } - - changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Done); - success = true; - } catch (OperationTimedoutException e) { - throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId); - } catch (AgentUnavailableException e) { - throw e; - } catch (NoTransitionException e) { - s_logger.info("Unable to change the state : " + e.getMessage()); - throw new ConcurrentOperationException("Unable to change the state : " + e.getMessage()); - }finally{ - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - if(!success){ - try { - stateTransitTo(vm, Event.OperationFailed, vm.getHostId()); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - } - } - - return vm; - - } - - @Override public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long oldSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException { s_logger.info("Migrating " + vm + " to " + dest); @@ -2881,10 +2837,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } try { + long newServiceOfferingId = vm.getServiceOfferingId(); vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) { throw new ConcurrentOperationException("Unable to change the state for " + vm); } + vm.setServiceOfferingId(newServiceOfferingId); } catch (NoTransitionException e1) { throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage()); } @@ -2928,6 +2886,56 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _workDao.update(work.getId(), work); } } + @Override + public VMInstanceVO reConfigureVm(VMInstanceVO vm , ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException { + + long newServiceofferingId = vm.getServiceOfferingId(); + ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newServiceofferingId); + ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), + newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); + + Long dstHostId = vm.getHostId(); + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); + work.setStep(Step.Prepare); + work.setResourceType(ItWorkVO.ResourceType.Host); + work.setResourceId(vm.getHostId()); + work = _workDao.persist(work); + boolean success = false; + try { + if(reconfiguringOnExistingHost){ + vm.setServiceOfferingId(oldServiceOffering.getId()); + _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); //release the old capacity + vm.setServiceOfferingId(newServiceofferingId); + _capacityMgr.allocateVmCapacity(vm, false); // lock the new capacity + } + //vm.setNewSvcOfferingId(newServiceOffering.getId()); // Capacity update should be delta (new - old) offering + //changeState(vm, Event.ReconfiguringRequested, dstHostId, work, Step.Reconfiguring); + + Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd); + if (!reconfigureAnswer.getResult()) { + s_logger.error("Unable to reconfigure due to " + reconfigureAnswer.getDetails()); + return null; + } + + //changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Done); + success = true; + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId); + } catch (AgentUnavailableException e) { + throw e; + } finally{ + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + if(!success){ + _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); // release the new capacity + vm.setServiceOfferingId(oldServiceOffering.getId()); + _capacityMgr.allocateVmCapacity(vm, false); // allocate the old capacity + } + } + + return vm; + + } }