New feature: Resource count (CPU/RAM) take only running vms into calculation (#3760)

* marvin: check resource count of more types

* New feature: add flag resource.count.running.vms.only to count resource consumption of only running vms

Stopped VMs do not use CPU/RAM actually.
A new global configuration resource.count.running.vms.only is added to determine whether resource (cpu/memory) of only running vms (including Starting/Stopping) will be taken into calculation of resource consumption.

* Add integration test for resource count of only running vms
This commit is contained in:
Wei Zhou 2020-01-30 10:36:50 +01:00 committed by GitHub
parent 518ed5379c
commit ac581d1546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1168 additions and 62 deletions

View File

@ -396,7 +396,7 @@ public interface UserVmService {
* @throws ResourceUnavailableException
* if the resources required the deploy the VM is not currently available.
*/
UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException;
UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;
/**
* Creates a vm group.

View File

@ -588,6 +588,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());

View File

@ -154,7 +154,7 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd {
}
@Override
public void execute() throws ResourceUnavailableException, ResourceAllocationException {
public void execute() {
try {
CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
@ -177,6 +177,12 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd {
} catch (ExecutionException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (InsufficientCapacityException ex) {
StringBuilder message = new StringBuilder(ex.getMessage());
if (ex instanceof InsufficientServerCapacityException) {

View File

@ -58,6 +58,9 @@ public interface VirtualMachineManager extends Manager {
ConfigKey<Boolean> VmConfigDriveOnPrimaryPool = new ConfigKey<>("Advanced", Boolean.class, "vm.configdrive.primarypool.enabled", "false",
"If config drive need to be created and hosted on primary storage pool. Currently only supported for KVM.", true);
ConfigKey<Boolean> ResoureCountRunningVMsonly = new ConfigKey<Boolean>("Advanced", Boolean.class, "resource.count.running.vms.only", "false",
"Count the resources of only running VMs in resource limitation.", true);
interface Topics {
String VM_POWER_STATE = "vm.powerstate";
}

View File

@ -122,6 +122,7 @@ import com.cloud.agent.manager.Commands;
import com.cloud.agent.manager.allocator.HostAllocator;
import com.cloud.alert.AlertManager;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.DataCenter;
@ -191,6 +192,7 @@ import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.utils.DateUtil;
import com.cloud.utils.Journal;
@ -302,6 +304,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
@Inject
private ResourceManager _resourceMgr;
@Inject
private ResourceLimitService _resourceLimitMgr;
@Inject
private VMSnapshotManager _vmSnapshotMgr;
@Inject
private ClusterDetailsDao _clusterDetailsDao;
@ -970,6 +974,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
// check resource count if ResoureCountRunningVMsonly.value() = true
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
resourceCountIncrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
boolean canRetry = true;
ExcludeList avoids = null;
try {
@ -1045,7 +1055,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
DeployDestination dest = null;
try {
@ -1272,6 +1281,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
} finally {
if (startedVm == null) {
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
resourceCountDecrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
if (canRetry) {
try {
changeState(vm, Event.OperationFailed, null, work, Step.Done);
@ -1817,7 +1829,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_workDao.update(work.getId(), work);
}
if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
boolean result = stateTransitTo(vm, Event.OperationSucceeded, null);
if (result) {
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
//update resource count if stop successfully
ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
resourceCountDecrement(vm.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
} else {
throw new CloudRuntimeException("unable to stop " + vm);
}
} catch (final NoTransitionException e) {
@ -4218,7 +4237,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait,
VmOpLockStateRetry,
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp};
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp,
ResoureCountRunningVMsonly };
}
public List<StoragePoolAllocator> getStoragePoolAllocators() {
@ -5338,4 +5358,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return workJob;
}
protected void resourceCountIncrement (long accountId, Long cpu, Long memory) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, cpu);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, memory);
}
protected void resourceCountDecrement (long accountId, Long cpu, Long memory) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, cpu);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory);
}
}

View File

@ -77,7 +77,7 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {
List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId);
public Long countAllocatedVMsForAccount(long accountId);
public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly);
Hashtable<Long, UserVmData> listVmDetails(Hashtable<Long, UserVmData> userVmData);

View File

@ -635,10 +635,13 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
}
@Override
public Long countAllocatedVMsForAccount(long accountId) {
public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly) {
SearchCriteria<Long> sc = CountByAccount.create();
sc.setParameters("account", accountId);
sc.setParameters("type", VirtualMachine.Type.User);
if (runningVMsonly)
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc.setParameters("displayVm", 1);
return customSearch(sc, null).get(0);

View File

@ -1376,6 +1376,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
} catch (final ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());

View File

@ -44,6 +44,8 @@ import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.alert.AlertManager;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource;
import com.cloud.configuration.Resource.ResourceOwnerType;
@ -100,6 +102,8 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@ -151,6 +155,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
private VlanDao _vlanDao;
@Inject
private SnapshotDataStoreDao _snapshotDataStoreDao;
@Inject
private UserVmJoinDao _userVmJoinDao;
protected GenericSearchBuilder<TemplateDataStoreVO, SumCount> templateSizeSearch;
protected GenericSearchBuilder<SnapshotDataStoreVO, SumCount> snapshotSizeSearch;
@ -872,7 +878,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
final Long newCount;
if (type == Resource.ResourceType.user_vm) {
newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
newCount = _userVmDao.countAllocatedVMsForAccount(accountId, VirtualMachineManager.ResoureCountRunningVMsonly.value());
} else if (type == Resource.ResourceType.volume) {
long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
newCount = _volumeDao.countAllocatedVolumesForAccount(accountId) - virtualRouterCount; // don't count the volumes of virtual router
@ -929,11 +935,51 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
}
public long countCpusForAccount(long accountId) {
return _resourceCountDao.countCpuNumberAllocatedToAccount(accountId);
long cputotal = 0;
// user vms
SearchBuilder<UserVmJoinVO> userVmSearch = _userVmJoinDao.createSearchBuilder();
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
userVmSearch.done();
SearchCriteria<UserVmJoinVO> sc1 = userVmSearch.create();
sc1.setParameters("accountId", accountId);
if (VirtualMachineManager.ResoureCountRunningVMsonly.value())
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc1.setParameters("displayVm", 1);
List<UserVmJoinVO> userVms = _userVmJoinDao.search(sc1,null);
for (UserVmJoinVO vm : userVms) {
cputotal += Long.valueOf(vm.getCpu());
}
return cputotal;
}
public long calculateMemoryForAccount(long accountId) {
return _resourceCountDao.countMemoryAllocatedToAccount(accountId);
long ramtotal = 0;
// user vms
SearchBuilder<UserVmJoinVO> userVmSearch = _userVmJoinDao.createSearchBuilder();
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
userVmSearch.done();
SearchCriteria<UserVmJoinVO> sc1 = userVmSearch.create();
sc1.setParameters("accountId", accountId);
if (VirtualMachineManager.ResoureCountRunningVMsonly.value())
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc1.setParameters("displayVm", 1);
List<UserVmJoinVO> userVms = _userVmJoinDao.search(sc1,null);
for (UserVmJoinVO vm : userVms) {
ramtotal += Long.valueOf(vm.getRamSize());
}
return ramtotal;
}
public long calculateSecondaryStorageForAccount(long accountId) {

View File

@ -30,6 +30,7 @@ import com.cloud.agent.api.VolumeStatsEntry;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.offering.ServiceOffering;
@ -99,10 +100,10 @@ public interface UserVmManager extends UserVmService {
boolean expunge(UserVmVO vm, long callerUserId, Account caller);
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
ConcurrentOperationException, ManagementServerException,

View File

@ -572,17 +572,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, displayVm, memory);
}
private void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
protected void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
}
}
private void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
protected void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
}
}
public class VmAndCountDetails {
long vmId;
@ -1016,12 +1020,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
int currentMemory = currentServiceOffering.getRamSize();
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
if (newCpu > currentCpu) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu);
}
if (newMemory > currentMemory) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory);
}
}
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
@ -1036,6 +1042,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
// Increment or decrement CPU and Memory count accordingly.
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
} else if (currentCpu > newCpu) {
@ -1046,6 +1053,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
} else if (currentMemory > newMemory) {
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
}
}
// Generate usage event for VM upgrade
UserVmVO userVm = _vmDao.findById(vmId);
@ -1123,12 +1131,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
int currentMemory = currentServiceOffering.getRamSize();
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
if (newCpu > currentCpu) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu);
}
if (newMemory > currentMemory) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory);
}
}
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
@ -1161,6 +1171,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
// Increment or decrement CPU and Memory count accordingly.
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
} else if (currentCpu > newCpu) {
@ -1171,6 +1182,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
} else if (currentMemory > newMemory) {
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
}
}
return _vmDao.findById(vmInstance.getId());
@ -2057,7 +2069,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
// accountId will not be exceeded
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
}
_haMgr.cancelDestroy(vm, vm.getHostId());
@ -2549,9 +2563,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
// Resource limit changes
ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
_resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm);
_resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu()));
_resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize()));
if (isDisplayVm) {
resourceCountIncrement(vmInstance.getAccountId(), true, new Long(offering.getCpu()), new Long(offering.getRamSize()));
} else {
resourceCountDecrement(vmInstance.getAccountId(), true, new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
// Usage
saveUsageEvent(vmInstance);
@ -2823,7 +2839,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), null, cmd.getDeploymentPlanner()).first();
}
@ -3522,7 +3538,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
}
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2));
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size);
@ -4237,7 +4255,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "starting Vm", async = true)
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
long vmId = cmd.getEntityId();
Long podId = null;
Long clusterId = null;
@ -4253,7 +4271,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private UserVm startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<Long, DiskOffering> diskOfferingMap, Map<VirtualMachineProfile.Param, Object> additonalParams, String deploymentPlannerToUse)
throws ResourceUnavailableException,
InsufficientCapacityException, ConcurrentOperationException {
InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
UserVmVO vm = _vmDao.findById(vmId);
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = null;
@ -4581,13 +4599,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Override
public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
return startVirtualMachine(vmId, null, null, hostId, additionalParams, deploymentPlannerToUse);
}
@Override
public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
// Input validation
final Account callerAccount = CallContext.current().getCallingAccount();
UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
@ -4613,6 +4631,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (owner.getState() == Account.State.disabled) {
throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
}
if (VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
// check if account/domain is with in resource limits to start a new vm
ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
resourceLimitCheck(owner, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
// check if vm is security group enabled
if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty()
@ -6123,7 +6146,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
removeInstanceFromInstanceGroup(cmd.getVmId());
// VV 2: check if account/domain is with in resource limits to create a new vm
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
// VV 3: check if volumes and primary storage space are with in resource limits
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
@ -6176,7 +6201,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
//update resource count of new account
if (! VirtualMachineManager.ResoureCountRunningVMsonly.value()) {
resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
//generate usage events to account for this change
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),

View File

@ -0,0 +1,927 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
""" tests for Resource count of only running vms in cloudstack 4.14.0.0
"""
# Import Local Modules
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import (validateList,
cleanup_resources)
from marvin.lib.base import (Account,
Domain,
Configurations,
Network,
NetworkOffering,
VirtualMachine,
Resources,
ServiceOffering,
Zone)
from marvin.lib.common import (get_domain,
get_zone,
get_template,
matchResourceCount,
isAccountResourceCountEqualToExpectedCount)
from marvin.codes import (PASS, FAILED, RESOURCE_CPU, RESOURCE_MEMORY)
import logging
import random
import time
class TestResourceCountRunningVMs(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.testClient = super(
TestResourceCountRunningVMs,
cls).getClsTestClient()
cls.apiclient = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig()
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
cls.zone = Zone(zone.__dict__)
cls._cleanup = []
cls.logger = logging.getLogger("TestResourceCountRunningVMs")
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
# Get Domain and templates
cls.domain = get_domain(cls.apiclient)
cls.template = get_template(cls.apiclient, cls.zone.id, hypervisor="KVM")
if cls.template == FAILED:
sys.exit(1)
cls.templatesize = (cls.template.size / (1024 ** 3))
cls.services['mode'] = cls.zone.networktype
# Create Account
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
accounts = Account.list(cls.apiclient, id=cls.account.id)
cls.expectedCpu = int(accounts[0].cputotal)
cls.expectedMemory = int(accounts[0].memorytotal)
if cls.zone.securitygroupsenabled:
cls.services["shared_network_offering"]["specifyVlan"] = 'True'
cls.services["shared_network_offering"]["specifyIpRanges"] = 'True'
cls.network_offering = NetworkOffering.create(
cls.apiclient,
cls.services["shared_network_offering"]
)
cls.network_offering.update(cls.apiclient, state='Enabled')
cls.account_network = Network.create(
cls.apiclient,
cls.services["network2"],
networkofferingid=cls.network_offering.id,
zoneid=cls.zone.id,
accountid=cls.account.name,
domainid=cls.account.domainid
)
else:
cls.network_offering = NetworkOffering.create(
cls.apiclient,
cls.services["isolated_network_offering"],
)
# Enable Network offering
cls.network_offering.update(cls.apiclient, state='Enabled')
# Create account network
cls.services["network"]["zoneid"] = cls.zone.id
cls.services["network"]["networkoffering"] = cls.network_offering.id
cls.account_network = Network.create(
cls.apiclient,
cls.services["network"],
cls.account.name,
cls.account.domainid
)
cls._cleanup.append(cls.account);
cls._cleanup.append(cls.network_offering)
@classmethod
def tearDownClass(self):
try:
cleanup_resources(self.apiclient, self._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.cleanup = []
return
def tearDown(self):
try:
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def verify_resource_count_cpu_memory(self, expectedCpu, expectedMemory, account=None):
if account is None:
account = self.account
response = matchResourceCount(
self.apiclient, expectedCpu,
RESOURCE_CPU,
accountid=account.id)
self.assertEqual(response[0], PASS, response[1])
response = matchResourceCount(
self.apiclient, expectedMemory,
RESOURCE_MEMORY,
accountid=account.id)
self.assertEqual(response[0], PASS, response[1])
result = isAccountResourceCountEqualToExpectedCount(
self.apiclient, account.domainid, account.name,
expectedCpu, RESOURCE_CPU)
self.assertFalse(result[0], result[1])
self.assertTrue(result[2], "Resource count of cpu does not match")
result = isAccountResourceCountEqualToExpectedCount(
self.apiclient, account.domainid, account.name,
expectedMemory, RESOURCE_MEMORY)
self.assertFalse(result[0], result[1])
self.assertTrue(result[2], "Resource count of memory does not match")
def update_account_resource_limitation(self, maxCpu, maxMemory):
Resources.updateLimit(self.apiclient,
resourcetype=RESOURCE_CPU,
max=maxCpu,
domainid=self.account.domainid,
account=self.account.name)
Resources.updateLimit(self.apiclient,
resourcetype=RESOURCE_MEMORY,
max=maxMemory,
domainid=self.account.domainid,
account=self.account.name)
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_01_resource_count_vm_with_normal_offering_in_all_states(self):
"""Create VM with normal offering. Take resources of vm in all states into calculation of resource count.
Steps:
# 1. update resource.count.running.vms.only to false
# 2. create normal service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram is not changed
# 5. update vm with displayvm=false, resource count decreases
# 6. update vm with displayvm=true, resource count increases
# 7. start vm, resource count of cpu/ram is not changed
# 8. reboot vm, resource count of cpu/ram is not changed
# 9. destroy vm, resource count of cpu/ram decreases
# 10. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="false" )
# Create small service offering
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["small"]
)
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_1 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
templateid=self.template.id,
zoneid=self.zone.id,
mode=self.zone.networktype
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_1.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_1.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_1.stop(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_1.update(self.apiclient, displayvm=False)
self.expectedCpu = self.expectedCpu - virtual_machine_1.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_1.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_1.update(self.apiclient, displayvm=True)
self.expectedCpu = self.expectedCpu + virtual_machine_1.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_1.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
virtual_machine_1.start(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# reboot vm
virtual_machine_1.reboot(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# destroy vm
virtual_machine_1.delete(self.apiclient, expunge=False)
self.expectedCpu = self.expectedCpu - virtual_machine_1.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_1.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_1.expunge(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_02_resource_count_vm_with_dynamic_offering_in_all_states(self):
"""Create VM with dynamic service offering. Take resources of vm in all states into calculation of resource count.
Steps:
# 1. update resource.count.running.vms.only to false
# 2. create dynamic service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram is not changed
# 5. update vm with displayvm=false, resource count decreases
# 6. update vm with displayvm=true, resource count increases
# 7. start vm, resource count of cpu/ram is not changed
# 8. reboot vm, resource count of cpu/ram is not changed
# 9. destroy vm, resource count of cpu/ram decreases
# 10. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="false" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_2 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
mode=self.zone.networktype
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_2.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_2.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_2.stop(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_2.update(self.apiclient, displayvm=False)
self.expectedCpu = self.expectedCpu - virtual_machine_2.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_2.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_2.update(self.apiclient, displayvm=True)
self.expectedCpu = self.expectedCpu + virtual_machine_2.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_2.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
virtual_machine_2.start(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# reboot vm
virtual_machine_2.reboot(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# destroy vm
virtual_machine_2.delete(self.apiclient, expunge=False)
self.expectedCpu = self.expectedCpu - virtual_machine_2.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_2.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_2.expunge(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_03_resource_count_vm_with_normal_offering_in_running_state(self):
"""Create VM with normal service offering. Take resources of vm in running state into calculation of resource count.
Steps:
# 1. update resource.count.running.vms.only to true
# 2. create normal service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram decreases
# 5. start vm, resource count of cpu/ram increases
# 6. reboot vm, resource count of cpu/ram is not changed
# 7. destroy vm, resource count of cpu/ram decreases
# 8. recover vm, resource count of cpu/ram is not changed
# 9. update vm with displayvm=false, resource count of cpu/ram is not changed
# 10. destroy vm with expunge = true, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="true" )
# Create service offering
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["small"]
)
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_3 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
templateid=self.template.id,
zoneid=self.zone.id,
mode=self.zone.networktype
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_3.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_3.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_3.stop(self.apiclient)
self.expectedCpu = self.expectedCpu - virtual_machine_3.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_3.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
virtual_machine_3.start(self.apiclient)
self.expectedCpu = self.expectedCpu + virtual_machine_3.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_3.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# reboot vm
virtual_machine_3.reboot(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# destroy vm
virtual_machine_3.delete(self.apiclient, expunge=False)
self.expectedCpu = self.expectedCpu - virtual_machine_3.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_3.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# recover vm
virtual_machine_3.recover(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_3.update(self.apiclient, displayvm=False)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_3.delete(self.apiclient, expunge=True)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_04_resource_count_vm_with_dynamic_offering_in_running_state(self):
"""Create VM with dynamic service offering. Take resources of vm in running state into calculation of resource count.
Steps:
# 1. update resource.count.running.vms.only to true
# 2. create dynamic service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram decreases
# 5. start vm, resource count of cpu/ram increases
# 6. reboot vm, resource count of cpu/ram is not changed
# 7. destroy vm, resource count of cpu/ram decreases
# 8. recover vm, resource count of cpu/ram is not changed
# 9. update vm with displayvm=false, resource count of cpu/ram is not changed
# 10. destroy vm with expunge = true, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="true" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_4 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
mode=self.zone.networktype
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_4.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_4.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_4.stop(self.apiclient)
self.expectedCpu = self.expectedCpu - virtual_machine_4.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_4.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
virtual_machine_4.start(self.apiclient)
self.expectedCpu = self.expectedCpu + virtual_machine_4.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_4.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# reboot vm
virtual_machine_4.reboot(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# destroy vm
virtual_machine_4.delete(self.apiclient, expunge=False)
self.expectedCpu = self.expectedCpu - virtual_machine_4.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_4.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# recover vm
virtual_machine_4.recover(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# update vm with displayvm=false
virtual_machine_4.update(self.apiclient, displayvm=False)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_4.delete(self.apiclient, expunge=True)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_05_resource_count_vm_with_dynamic_offering_in_running_state_failed_cases(self):
"""Create VM with dynamic service offering. Take resources of vm in running state into calculation of resource count. Test failed cases
Steps:
# 1. update resource.count.running.vms.only to true
# 2. create dynamic service offering
# 3. update account cpu/ram limitation to current value
# 4. deploy vm (startvm=false), resource count of cpu/ram is not changed
# 5. start vm, it should fail
# 6. increase cpu limitation, start vm, it should fail
# 7. increase memory limitation, start vm, it should succeed. resource count of cpu/ram increases
# 8. restore vm, it should succeed. resource count of cpu/ram is not changed
# 9. destroy vm, resource count of cpu/ram decreases
# 10. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="true" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# update resource limitation
self.update_account_resource_limitation(self.expectedCpu, self.expectedMemory)
# deploy vm (startvm=false)
try:
virtual_machine_5 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
startvm=False,
mode=self.zone.networktype
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
try:
virtual_machine_5.start(self.apiclient)
self.fail("Start VM should fail as there is not enough cpu")
except Exception:
self.debug("Start VM failed as expected")
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# increase cpu limitation, and start vm
self.update_account_resource_limitation(self.expectedCpu + virtual_machine_5.cpunumber, self.expectedMemory)
try:
virtual_machine_5.start(self.apiclient)
self.fail("Start VM should fail as there is not enough memory")
except Exception:
self.debug("Start VM failed as expected")
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# increase memory limitation, and start vm
self.update_account_resource_limitation(self.expectedCpu + virtual_machine_5.cpunumber, self.expectedMemory + virtual_machine_5.memory)
try:
virtual_machine_5.start(self.apiclient)
self.debug("Start VM succeed as expected")
except Exception:
self.fail("Start VM should succeed as there is enough cpu and memory")
self.expectedCpu = self.expectedCpu + virtual_machine_5.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_5.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# restore running vm
virtual_machine_5.restore(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_5.delete(self.apiclient, expunge=True)
self.expectedCpu = self.expectedCpu - virtual_machine_5.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_5.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_06_resource_count_vm_with_dynamic_offering_in_all_states_failed_cases(self):
"""Create VM with dynamic service offering. Take resources of vm in all states into calculation of resource count. Test failed cases
Steps:
# 1. update resource.count.running.vms.only to false
# 2. create dynamic service offering
# 3. update account cpu/ram limitation to current value
# 4. deploy vm (startvm=false), it should fail
# 5. increase cpu limitation, deploy vm, it should fail
# 6. increase memory limitation, deploy vm, it should succeed. resource count of cpu/ram increases
# 7. start vm, resource count of cpu/ram is not changed
# 8. restore vm, it should succeed. resource count of cpu/ram is not changed
# 9. destroy vm, resource count of cpu/ram decreases
# 10. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="false" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# update resource limitation
self.update_account_resource_limitation(self.expectedCpu, self.expectedMemory)
# deploy vm (startvm=false)
try:
virtual_machine_6 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
startvm=False,
mode=self.zone.networktype
)
self.fail("Deploy VM should fail as there is not enough cpu")
except Exception as e:
self.debug("Deploy VM failed as expected")
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# increase cpu limitation, and deploy vm
self.update_account_resource_limitation(self.expectedCpu + 1, self.expectedMemory)
try:
virtual_machine_6 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
startvm=False,
mode=self.zone.networktype
)
self.fail("Deploy VM should fail as there is not enough memory")
except Exception as e:
self.debug("Deploy VM failed as expected")
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# increase memory limitation, and deploy vm
self.update_account_resource_limitation(self.expectedCpu + 1, self.expectedMemory + 256)
try:
virtual_machine_6 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id,
startvm=False,
mode=self.zone.networktype
)
self.debug("Deploy VM succeed as expected")
except Exception:
self.fail("Deploy VM should succeed as there is enough cpu and memory")
self.expectedCpu = self.expectedCpu + virtual_machine_6.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_6.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# start vm
virtual_machine_6.start(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# restore running vm
virtual_machine_6.restore(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# expunge vm
virtual_machine_6.delete(self.apiclient, expunge=True)
self.expectedCpu = self.expectedCpu - virtual_machine_6.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_6.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_07_resource_count_vm_in_running_state_and_move_and_upgrade(self):
"""Create VM with dynamic service offering. Take resources of vm in running state into calculation. Move vm to another account and upgrade it.
Steps:
# 1. update resource.count.running.vms.only to true
# 2. create dynamic service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram decreases
# 5. create another account
# 6. move vm to new account. resource count of cpu/ram of current account is not changed. resource count of cpu/ram of new account is not changed.
# 7. create another service offering.
# 8. upgrade vm. resource count of cpu/ram of new account is not changed.
# 9. start vm, resource count of cpu/ram of new account increases with cpu/ram of new service offering.
# 10. destroy vm, resource count of cpu/ram decreases
# 11. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="true" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_7 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_7.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_7.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_7.stop(self.apiclient)
self.expectedCpu = self.expectedCpu - virtual_machine_7.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_7.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# create another account
self.account2 = Account.create(
self.apiclient,
self.services["account2"],
admin=True,
domainid=self.domain.id
)
accounts = Account.list(self.apiclient, id=self.account2.id)
self.account2Cpu = int(accounts[0].cputotal)
self.account2Memory = int(accounts[0].memorytotal)
# move vm to new account. resource count of cpu/ram of current account is not changed. resource count of cpu/ram of new account is not changed.
oldcpunumber = virtual_machine_7.cpunumber
oldmemory = virtual_machine_7.memory
virtual_machine_7.assign_virtual_machine(self.apiclient, self.account2.name, self.account2.domainid)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# create another service offering
self.service_offering_big = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["big"]
)
self.cleanup.append(self.service_offering_big)
# upgrade vm
virtual_machine_7.change_service_offering(self.apiclient, self.service_offering_big.id)
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# start vm, resource count of cpu/ram of new account increases with cpu/ram of new service offering.
virtual_machine_7.start(self.apiclient)
self.account2Cpu = self.account2Cpu + self.service_offering_big.cpunumber
self.account2Memory = self.account2Memory + self.service_offering_big.memory
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# expunge vm
virtual_machine_7.delete(self.apiclient, expunge=True)
self.account2Cpu = self.account2Cpu - self.service_offering_big.cpunumber
self.account2Memory = self.account2Memory - self.service_offering_big.memory
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
@attr(tags=["advanced", "advancedsg"], required_hardware="false")
def test_08_resource_count_vm_in_all_states_and_move_and_upgrade(self):
"""Create VM with dynamic service offering. Take resources of vm in all states into calculation. Move vm to another account and upgrade it.
Steps:
# 1. update resource.count.running.vms.only to true
# 2. create dynamic service offering
# 3. deploy vm, resource count of cpu/ram increases
# 4. stop vm, resource count of cpu/ram is not changed
# 5. create another account
# 6. move vm to new account. resource count of cpu/ram of current account decreases. resource count of cpu/ram of new account increases.
# 7. create another service offering.
# 8. upgrade vm. resource count of cpu/ram of new account is changed.
# 9. start vm, resource count of cpu/ram is not changed
# 10. destroy vm, resource count of cpu/ram decreases
# 11. expunge vm, resource count of cpu/ram is not changed
"""
Configurations.update(self.apiclient,
name="resource.count.running.vms.only",
value="false" )
# Create dynamic service offering
self.services["service_offering"]["cpunumber"] = ""
self.services["service_offering"]["cpuspeed"] = ""
self.services["service_offering"]["memory"] = ""
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"])
self.cleanup.append(self.service_offering)
# deploy vm
try:
virtual_machine_8 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
customcpunumber=1,
customcpuspeed=100,
custommemory=256,
templateid=self.template.id,
zoneid=self.zone.id
)
except Exception as e:
self.fail("Exception while deploying virtual machine: %s" % e)
self.expectedCpu = self.expectedCpu + virtual_machine_8.cpunumber
self.expectedMemory = self.expectedMemory + virtual_machine_8.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# stop vm
virtual_machine_8.stop(self.apiclient)
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
# create another account
self.account2 = Account.create(
self.apiclient,
self.services["account2"],
admin=True,
domainid=self.domain.id
)
self.cleanup.append(self.account2)
accounts = Account.list(self.apiclient, id=self.account2.id)
self.account2Cpu = int(accounts[0].cputotal)
self.account2Memory = int(accounts[0].memorytotal)
# move vm to new account. resource count of cpu/ram of current account decreases. resource count of cpu/ram of new account increases.
oldcpunumber = virtual_machine_8.cpunumber
oldmemory = virtual_machine_8.memory
virtual_machine_8.assign_virtual_machine(self.apiclient, self.account2.name, self.account2.domainid)
self.expectedCpu = self.expectedCpu - virtual_machine_8.cpunumber
self.expectedMemory = self.expectedMemory - virtual_machine_8.memory
self.verify_resource_count_cpu_memory(self.expectedCpu, self.expectedMemory);
self.account2Cpu = self.account2Cpu + virtual_machine_8.cpunumber
self.account2Memory = self.account2Memory + virtual_machine_8.memory
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# create another service offering
self.service_offering_big = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["big"]
)
self.cleanup.append(self.service_offering_big)
# upgrade vm
virtual_machine_8.change_service_offering(self.apiclient, self.service_offering_big.id)
self.account2Cpu = self.account2Cpu + self.service_offering_big.cpunumber - oldcpunumber
self.account2Memory = self.account2Memory + self.service_offering_big.memory - oldmemory
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# start vm
virtual_machine_8.start(self.apiclient)
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);
# expunge vm
virtual_machine_8.delete(self.apiclient, expunge=True)
self.account2Cpu = self.account2Cpu - self.service_offering_big.cpunumber
self.account2Memory = self.account2Memory - self.service_offering_big.memory
self.verify_resource_count_cpu_memory(self.account2Cpu, self.account2Memory, account=self.account2);

View File

@ -102,6 +102,14 @@ USER = 0
XEN_SERVER = "XenServer"
ADMIN_ACCOUNT = 'ADMIN_ACCOUNT'
USER_ACCOUNT = 'USER_ACCOUNT'
RESOURCE_USER_VM = 0
RESOURCE_PUBLIC_IP = 1
RESOURCE_VOLUME = 2
RESOURCE_SNAPSHOT = 3
RESOURCE_TEMPLATE = 4
RESOURCE_PROJECT = 5
RESOURCE_NETWORK = 6
RESOURCE_VPC = 7
RESOURCE_CPU = 8
RESOURCE_MEMORY = 9
RESOURCE_PRIMARY_STORAGE = 10

View File

@ -63,6 +63,9 @@ from marvin.sshClient import SshClient
from marvin.codes import (PASS, FAILED, ISOLATED_NETWORK, VPC_NETWORK,
BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE,
RESOURCE_PRIMARY_STORAGE, RESOURCE_SECONDARY_STORAGE,
RESOURCE_USER_VM, RESOURCE_PUBLIC_IP, RESOURCE_VOLUME,
RESOURCE_SNAPSHOT, RESOURCE_TEMPLATE, RESOURCE_PROJECT,
RESOURCE_NETWORK, RESOURCE_VPC,
RESOURCE_CPU, RESOURCE_MEMORY, PUBLIC_TRAFFIC,
GUEST_TRAFFIC, MANAGEMENT_TRAFFIC, STORAGE_TRAFFIC,
VMWAREDVS)
@ -1392,6 +1395,20 @@ def matchResourceCount(apiclient, expectedCount, resourceType,
resourceCount = resourceholderlist[0].cputotal
elif resourceType == RESOURCE_MEMORY:
resourceCount = resourceholderlist[0].memorytotal
elif resourceType == RESOURCE_USER_VM:
resourceCount = resourceholderlist[0].vmtotal
elif resourceType == RESOURCE_PUBLIC_IP:
resourceCount = resourceholderlist[0].iptotal
elif resourceType == RESOURCE_VOLUME:
resourceCount = resourceholderlist[0].volumetotal
elif resourceType == RESOURCE_SNAPSHOT:
resourceCount = resourceholderlist[0].snapshottotal
elif resourceType == RESOURCE_TEMPLATE:
resourceCount = resourceholderlist[0].templatetotal
elif resourceType == RESOURCE_NETWORK:
resourceCount = resourceholderlist[0].networktotal
elif resourceType == RESOURCE_VPC:
resourceCount = resourceholderlist[0].vpctotal
assert str(resourceCount) == str(expectedCount),\
"Resource count %s should match with the expected resource count %s" %\
(resourceCount, expectedCount)
@ -1452,7 +1469,36 @@ def isDomainResourceCountEqualToExpectedCount(apiclient, domainid, expectedcount
isExceptionOccured = True
return [isExceptionOccured, reasonForException, isResourceCountEqual]
if resourcetype == RESOURCE_PRIMARY_STORAGE or resourcetype == RESOURCE_SECONDARY_STORAGE:
resourcecount = (response[0].resourcecount / (1024**3))
else:
resourcecount = response[0].resourcecount
if resourcecount == expectedcount:
isResourceCountEqual = True
return [isExceptionOccured, reasonForException, isResourceCountEqual]
def isAccountResourceCountEqualToExpectedCount(apiclient, domainid, account, expectedcount,
resourcetype):
"""Get the resource count of specific account and match
it with the expected count
Return list [isExceptionOccured, reasonForException, isResourceCountEqual]"""
isResourceCountEqual = False
isExceptionOccured = False
reasonForException = None
try:
response = Resources.updateCount(apiclient, domainid=domainid, account=account,
resourcetype=resourcetype)
except Exception as e:
reasonForException = "Failed while updating resource count: %s" % e
isExceptionOccured = True
return [isExceptionOccured, reasonForException, isResourceCountEqual]
if resourcetype == RESOURCE_PRIMARY_STORAGE or resourcetype == RESOURCE_SECONDARY_STORAGE:
resourcecount = (response[0].resourcecount / (1024**3))
else:
resourcecount = response[0].resourcecount
if resourcecount == expectedcount:
isResourceCountEqual = True
return [isExceptionOccured, reasonForException, isResourceCountEqual]