mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-658 - Adding capacity related changes
This commit is contained in:
parent
6bf8ff623d
commit
bffc09c61a
|
|
@ -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);*/
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -2729,53 +2732,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 {
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue