mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fixup resource limit checks (#8935)
This commit is contained in:
parent
89231106ff
commit
cfdb33a052
@ -239,13 +239,35 @@ public interface ResourceLimitService {
|
||||
void updateTaggedResourceLimitsAndCountsForAccounts(List<AccountResponse> responses, String tag);
|
||||
void updateTaggedResourceLimitsAndCountsForDomains(List<DomainResponse> responses, String tag);
|
||||
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||
|
||||
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering) throws ResourceAllocationException;
|
||||
|
||||
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
|
||||
void updateVmResourceCountForTemplateChange(long accountId, Boolean display, ServiceOffering offering, VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate);
|
||||
|
||||
void updateVmResourceCountForServiceOfferingChange(long accountId, Boolean display, Long currentCpu, Long newCpu, Long currentMemory,
|
||||
Long newMemory,
|
||||
ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate template);
|
||||
|
||||
void updateVolumeResourceCountForDiskOfferingChange(long accountId, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentDiskOffering, DiskOffering newDiskOffering);
|
||||
|
||||
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
|
||||
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
|
||||
void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
|
||||
|
||||
void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException;
|
||||
|
||||
void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException;
|
||||
void incrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||
void decrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||
|
||||
@ -110,7 +110,7 @@ public interface UserVmService {
|
||||
UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, ExecutionException, ConcurrentOperationException, ResourceUnavailableException,
|
||||
InsufficientCapacityException, ResourceAllocationException;
|
||||
|
||||
UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
|
||||
UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException;
|
||||
|
||||
UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
@ -490,7 +490,7 @@ public interface UserVmService {
|
||||
|
||||
VirtualMachine vmStorageMigration(Long vmId, Map<String, String> volumeToPool);
|
||||
|
||||
UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
|
||||
UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException;
|
||||
|
||||
UserVm restoreVirtualMachine(Account caller, long vmId, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws InsufficientCapacityException, ResourceUnavailableException;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -113,7 +114,7 @@ public class RebootVMCmd extends BaseAsyncCmd implements UserCmd {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
|
||||
UserVm result;
|
||||
result = _userVmService.rebootVirtualMachine(this);
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
@ -254,7 +255,7 @@ public interface VirtualMachineManager extends Manager {
|
||||
*/
|
||||
boolean unmanage(String vmUuid);
|
||||
|
||||
UserVm restoreVirtualMachine(long vmId, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
UserVm restoreVirtualMachine(long vmId, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
|
||||
|
||||
boolean checkIfVmHasClusterWideVolumes(Long vmId);
|
||||
|
||||
|
||||
@ -2978,7 +2978,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
ListResponse<StoragePoolResponse> response = new ListResponse<>();
|
||||
|
||||
List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(storagePools.first().toArray(new StoragePoolJoinVO[storagePools.first().size()]));
|
||||
Map<String, Long> poolUuidToIdMap = storagePools.first().stream().collect(Collectors.toMap(StoragePoolJoinVO::getUuid, StoragePoolJoinVO::getId));
|
||||
Map<String, Long> poolUuidToIdMap = storagePools.first().stream().collect(Collectors.toMap(StoragePoolJoinVO::getUuid, StoragePoolJoinVO::getId, (a, b) -> a));
|
||||
for (StoragePoolResponse poolResponse : poolResponses) {
|
||||
DataStore store = dataStoreManager.getPrimaryDataStore(poolResponse.getId());
|
||||
if (store != null) {
|
||||
@ -3821,9 +3821,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
|
||||
if (!storageTags.isEmpty() && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.value()) {
|
||||
for (String tag : storageTags) {
|
||||
diskOfferingSearch.and(tag, diskOfferingSearch.entity().getTags(), Op.EQ);
|
||||
diskOfferingSearch.and("storageTag" + tag, diskOfferingSearch.entity().getTags(), Op.FIND_IN_SET);
|
||||
}
|
||||
diskOfferingSearch.done();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3935,18 +3934,24 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
srvOffrDomainDetailSearch.entity().getName(), serviceOfferingSearch.entity().setString(ApiConstants.DOMAIN_ID));
|
||||
}
|
||||
|
||||
List<String> hostTags = getHostTagsFromTemplateForServiceOfferingsListing(caller, templateId);
|
||||
if (currentVmOffering != null) {
|
||||
List<String> hostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
||||
hostTags.addAll(com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag()));
|
||||
}
|
||||
|
||||
if (!hostTags.isEmpty()) {
|
||||
|
||||
serviceOfferingSearch.and().op("hostTag", serviceOfferingSearch.entity().getHostTag(), Op.NULL);
|
||||
serviceOfferingSearch.or().op();
|
||||
|
||||
serviceOfferingSearch.or();
|
||||
boolean flag = true;
|
||||
for(String tag : hostTags) {
|
||||
serviceOfferingSearch.and(tag, serviceOfferingSearch.entity().getHostTag(), Op.EQ);
|
||||
if (flag) {
|
||||
flag = false;
|
||||
serviceOfferingSearch.op("hostTag" + tag, serviceOfferingSearch.entity().getHostTag(), Op.FIND_IN_SET);
|
||||
} else {
|
||||
serviceOfferingSearch.and("hostTag" + tag, serviceOfferingSearch.entity().getHostTag(), Op.FIND_IN_SET);
|
||||
}
|
||||
serviceOfferingSearch.cp().cp().done();
|
||||
}
|
||||
serviceOfferingSearch.cp().cp();
|
||||
}
|
||||
|
||||
SearchCriteria<ServiceOfferingVO> sc = serviceOfferingSearch.create();
|
||||
@ -4063,41 +4068,19 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sc.setJoinParameters("domainDetailSearchNormalUser", "domainIdIN", domainIds.toArray());
|
||||
}
|
||||
|
||||
List<String> hostTags = getHostTagsFromTemplateForServiceOfferingsListing(caller, templateId);
|
||||
|
||||
if (currentVmOffering != null) {
|
||||
|
||||
if (diskOffering != null) {
|
||||
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
|
||||
if (!storageTags.isEmpty() && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.value()) {
|
||||
for (String tag : storageTags) {
|
||||
sc.setJoinParameters("diskOfferingSearch", tag, tag);
|
||||
sc.setJoinParameters("diskOfferingSearch", "storageTag" + tag, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> offeringHostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
||||
if (!offeringHostTags.isEmpty()) {
|
||||
hostTags.addAll(offeringHostTags);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(hostTags)) {
|
||||
SearchBuilder<ServiceOfferingJoinVO> hostTagsSearchBuilder = _srvOfferingJoinDao.createSearchBuilder();
|
||||
for (String tag : hostTags) {
|
||||
hostTagsSearchBuilder.and(tag, hostTagsSearchBuilder.entity().getHostTag(), Op.FIND_IN_SET);
|
||||
sc.setParameters("hostTag" + tag, tag);
|
||||
}
|
||||
hostTagsSearchBuilder.done();
|
||||
|
||||
SearchCriteria<ServiceOfferingJoinVO> hostTagsSearchCriteria = hostTagsSearchBuilder.create();
|
||||
for(String tag : hostTags) {
|
||||
hostTagsSearchCriteria.setParameters(tag, tag);
|
||||
}
|
||||
|
||||
SearchCriteria<ServiceOfferingJoinVO> finalHostTagsSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
||||
finalHostTagsSearchCriteria.addOr("hostTag", Op.NULL);
|
||||
finalHostTagsSearchCriteria.addOr("hostTag", Op.SC, hostTagsSearchCriteria);
|
||||
|
||||
sc.addAnd("hostTagsConstraint", SearchCriteria.Op.SC, finalHostTagsSearchCriteria);
|
||||
}
|
||||
|
||||
Pair<List<ServiceOfferingVO>, Integer> uniquePair = _srvOfferingDao.searchAndCount(sc, searchFilter);
|
||||
|
||||
@ -35,6 +35,7 @@ import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.Ternary;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
@ -1112,6 +1113,13 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
}
|
||||
|
||||
protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, String tag, final boolean increment, final long delta) {
|
||||
if (delta == 0) {
|
||||
return true;
|
||||
} else if (delta < 0) {
|
||||
logger.warn("Resource count delta is negative, delta = {} for Account = {} Type = {} tag = {}",
|
||||
delta, accountId, type, tag);
|
||||
return true;
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
String convertedDelta = String.valueOf(delta);
|
||||
if (type == ResourceType.secondary_storage || type == ResourceType.primary_storage){
|
||||
@ -1231,6 +1239,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
accountRC.setCount((newCount == null) ? 0 : newCount);
|
||||
_resourceCountDao.update(accountRC.getId(), accountRC);
|
||||
}
|
||||
} else if (newCount != null) {
|
||||
_resourceCountDao.persist(new ResourceCountVO(type, newCount, accountId, ResourceOwnerType.Account, tag));
|
||||
}
|
||||
|
||||
// No need to log message for primary and secondary storage because both are recalculating the
|
||||
@ -1631,6 +1641,30 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering
|
||||
) throws ResourceAllocationException {
|
||||
Ternary<Set<String>, Set<String>, Set<String>> updatedResourceLimitStorageTags = getResourceLimitStorageTagsForDiskOfferingChange(display, currentOffering, newOffering);
|
||||
if (updatedResourceLimitStorageTags == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> sameTags = updatedResourceLimitStorageTags.first();
|
||||
Set<String> newTags = updatedResourceLimitStorageTags.second();
|
||||
|
||||
if (newSize > currentSize) {
|
||||
for (String tag : sameTags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.primary_storage, tag, newSize - currentSize);
|
||||
}
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.volume, tag, 1L);
|
||||
checkResourceLimitWithTag(owner, ResourceType.primary_storage, tag, newSize);
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering) {
|
||||
@ -1671,6 +1705,144 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVmResourceCountForTemplateChange(long accountId, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate
|
||||
) {
|
||||
updateVmResourceCountForServiceOfferingAndTemplateChange(accountId, display, null, null, null, null,
|
||||
offering, offering, currentTemplate, newTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVmResourceCountForServiceOfferingChange(long accountId, Boolean display, Long currentCpu, Long newCpu,Long currentMemory, Long newMemory,
|
||||
ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template
|
||||
) {
|
||||
updateVmResourceCountForServiceOfferingAndTemplateChange(accountId, display, currentCpu, newCpu, currentMemory, newMemory, currentOffering,
|
||||
newOffering != null ? newOffering : currentOffering, template, template);
|
||||
}
|
||||
|
||||
private Ternary<Set<String>, Set<String>, Set<String>> getResourceLimitHostTagsForVmServiceOfferingAndTemplateChange(
|
||||
Boolean display, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate
|
||||
) {
|
||||
Set<String> currentOfferingTags = new HashSet<>(getResourceLimitHostTagsForResourceCountOperation(display, currentOffering, currentTemplate));
|
||||
if (currentOffering.getId() == newOffering.getId() && currentTemplate.getId() == newTemplate.getId()) {
|
||||
return new Ternary<>(currentOfferingTags, new HashSet<>(), new HashSet<>());
|
||||
}
|
||||
Set<String> newOfferingTags = new HashSet<>(getResourceLimitHostTagsForResourceCountOperation(display, newOffering, newTemplate));
|
||||
|
||||
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());;
|
||||
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||
return new Ternary<>(sameTags, newTags, removedTags);
|
||||
}
|
||||
|
||||
private void updateVmResourceCountForServiceOfferingAndTemplateChange(long accountId, Boolean display, Long currentCpu,
|
||||
Long newCpu, Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate
|
||||
) {
|
||||
Ternary<Set<String>, Set<String>, Set<String>> updatedResourceLimitHostTags = getResourceLimitHostTagsForVmServiceOfferingAndTemplateChange(display, currentOffering, newOffering, currentTemplate, newTemplate);
|
||||
if (updatedResourceLimitHostTags == null) {
|
||||
return;
|
||||
}
|
||||
if (currentCpu == null) {
|
||||
currentCpu = currentOffering.getCpu() != null ? Long.valueOf(currentOffering.getCpu()) : 0L;
|
||||
}
|
||||
if (newCpu == null) {
|
||||
newCpu = newOffering.getCpu() != null ? Long.valueOf(newOffering.getCpu()) : 0L;
|
||||
}
|
||||
if (currentMemory == null) {
|
||||
currentMemory = currentOffering.getRamSize() != null ? Long.valueOf(currentOffering.getRamSize()) : 0L;
|
||||
}
|
||||
if (newMemory == null) {
|
||||
newMemory = newOffering.getRamSize() != null ? Long.valueOf(newOffering.getRamSize()) : 0L;
|
||||
}
|
||||
|
||||
Set<String> sameTags = updatedResourceLimitHostTags.first();
|
||||
Set<String> newTags = updatedResourceLimitHostTags.second();
|
||||
Set<String> removedTags = updatedResourceLimitHostTags.third();
|
||||
|
||||
if (!newCpu.equals(currentCpu) || !newMemory.equals(currentMemory)) {
|
||||
for (String tag : sameTags) {
|
||||
if (newCpu - currentCpu > 0) {
|
||||
incrementResourceCountWithTag(accountId, ResourceType.cpu, tag, newCpu - currentCpu);
|
||||
} else if (newCpu - currentCpu < 0) {
|
||||
decrementResourceCountWithTag(accountId, ResourceType.cpu, tag, currentCpu - newCpu);
|
||||
}
|
||||
|
||||
if (newMemory - currentMemory > 0) {
|
||||
incrementResourceCountWithTag(accountId, ResourceType.memory, tag, newMemory - currentMemory);
|
||||
} else if (newMemory - currentMemory < 0) {
|
||||
decrementResourceCountWithTag(accountId, ResourceType.memory, tag, currentMemory - newMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String tag : removedTags) {
|
||||
decrementResourceCountWithTag(accountId, ResourceType.user_vm, tag, 1L);
|
||||
decrementResourceCountWithTag(accountId, ResourceType.cpu, tag, currentCpu);
|
||||
decrementResourceCountWithTag(accountId, ResourceType.memory, tag, currentMemory);
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
incrementResourceCountWithTag(accountId, ResourceType.user_vm, tag, 1L);
|
||||
incrementResourceCountWithTag(accountId, ResourceType.cpu, tag, newCpu);
|
||||
incrementResourceCountWithTag(accountId, ResourceType.memory, tag, newMemory);
|
||||
}
|
||||
}
|
||||
|
||||
private Ternary<Set<String>, Set<String>, Set<String>> getResourceLimitStorageTagsForDiskOfferingChange(
|
||||
Boolean display, DiskOffering currentOffering, DiskOffering newOffering
|
||||
) {
|
||||
Set<String> currentOfferingTags = new HashSet<>(getResourceLimitStorageTagsForResourceCountOperation(display, currentOffering));
|
||||
if (newOffering == null || currentOffering.getId() == newOffering.getId()) {
|
||||
return new Ternary<>(currentOfferingTags, new HashSet<>(), new HashSet<>());
|
||||
}
|
||||
Set<String> newOfferingTags = new HashSet<>(getResourceLimitStorageTagsForResourceCountOperation(display, newOffering));
|
||||
if (currentOfferingTags.isEmpty() && newOfferingTags.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Set<String> sameTags = currentOfferingTags.stream().filter(newOfferingTags::contains).collect(Collectors.toSet());;
|
||||
Set<String> newTags = newOfferingTags.stream().filter(tag -> !currentOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||
Set<String> removedTags = currentOfferingTags.stream().filter(tag -> !newOfferingTags.contains(tag)).collect(Collectors.toSet());
|
||||
return new Ternary<>(sameTags, newTags, removedTags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVolumeResourceCountForDiskOfferingChange(long accountId, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering
|
||||
) {
|
||||
Ternary<Set<String>, Set<String>, Set<String>> updatedResourceLimitStorageTags = getResourceLimitStorageTagsForDiskOfferingChange(display, currentOffering, newOffering);
|
||||
if (updatedResourceLimitStorageTags == null) {
|
||||
return;
|
||||
}
|
||||
Set<String> sameTags = updatedResourceLimitStorageTags.first();
|
||||
Set<String> newTags = updatedResourceLimitStorageTags.second();
|
||||
Set<String> removedTags = updatedResourceLimitStorageTags.third();
|
||||
|
||||
if (!newSize.equals(currentSize)) {
|
||||
for (String tag : sameTags) {
|
||||
if (newSize - currentSize > 0) {
|
||||
incrementResourceCountWithTag(accountId, ResourceType.primary_storage, tag, newSize - currentSize);
|
||||
} else if (newSize - currentSize < 0) {
|
||||
decrementResourceCountWithTag(accountId, ResourceType.primary_storage, tag, currentSize - newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String tag : removedTags) {
|
||||
decrementResourceCountWithTag(accountId, ResourceType.volume, tag, 1L);
|
||||
decrementResourceCountWithTag(accountId, ResourceType.primary_storage, tag, currentSize);
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
incrementResourceCountWithTag(accountId, ResourceType.volume, tag, 1L);
|
||||
incrementResourceCountWithTag(accountId, ResourceType.primary_storage, tag, newSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering) {
|
||||
if (size == null) {
|
||||
@ -1768,6 +1940,66 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException {
|
||||
checkVmResourceLimitsForServiceOfferingAndTemplateChange(owner, display, null, null,
|
||||
null, null, offering, offering, currentTemplate, newTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory,
|
||||
ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template
|
||||
) throws ResourceAllocationException {
|
||||
checkVmResourceLimitsForServiceOfferingAndTemplateChange(owner, display, currentCpu, newCpu, currentMemory, newMemory, currentOffering,
|
||||
newOffering != null ? newOffering : currentOffering, template, template);
|
||||
}
|
||||
|
||||
private void checkVmResourceLimitsForServiceOfferingAndTemplateChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate
|
||||
) throws ResourceAllocationException {
|
||||
Ternary<Set<String>, Set<String>, Set<String>> updatedResourceLimitHostTags = getResourceLimitHostTagsForVmServiceOfferingAndTemplateChange(display, currentOffering, newOffering, currentTemplate, newTemplate);
|
||||
if (updatedResourceLimitHostTags == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCpu == null) {
|
||||
currentCpu = currentOffering.getCpu() != null ? Long.valueOf(currentOffering.getCpu()) : 0L;
|
||||
}
|
||||
if (newCpu == null) {
|
||||
newCpu = newOffering.getCpu() != null ? Long.valueOf(newOffering.getCpu()) : 0L;
|
||||
}
|
||||
if (currentMemory == null) {
|
||||
currentMemory = currentOffering.getRamSize() != null ? Long.valueOf(currentOffering.getRamSize()) : 0L;
|
||||
}
|
||||
if (newMemory == null) {
|
||||
newMemory = newOffering.getRamSize() != null ? Long.valueOf(newOffering.getRamSize()) : 0L;
|
||||
}
|
||||
|
||||
Set<String> sameTags = updatedResourceLimitHostTags.first();
|
||||
Set<String> newTags = updatedResourceLimitHostTags.second();
|
||||
|
||||
if (newCpu - currentCpu > 0 || newMemory - currentMemory > 0) {
|
||||
for (String tag : sameTags) {
|
||||
if (newCpu - currentCpu > 0) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.cpu, tag, newCpu - currentCpu);
|
||||
}
|
||||
|
||||
if (newMemory - currentMemory > 0) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.memory, tag, newMemory - currentMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.user_vm, tag, 1L);
|
||||
checkResourceLimitWithTag(owner, ResourceType.cpu, tag, newCpu);
|
||||
checkResourceLimitWithTag(owner, ResourceType.memory, tag, newMemory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitHostTagsForResourceCountOperation(display, serviceOffering, template);
|
||||
|
||||
@ -1240,57 +1240,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
|
||||
long currentSize = volume.getSize();
|
||||
|
||||
// if the caller is looking to change the size of the volume
|
||||
if (currentSize != newSize) {
|
||||
if (volume.getInstanceId() != null) {
|
||||
// Check that VM to which this volume is attached does not have VM snapshots
|
||||
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
|
||||
throw new InvalidParameterValueException("A volume that is attached to a VM with any VM snapshots cannot be resized.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!validateVolumeSizeInBytes(newSize)) {
|
||||
throw new InvalidParameterValueException("Requested size out of range");
|
||||
}
|
||||
|
||||
Long storagePoolId = volume.getPoolId();
|
||||
|
||||
if (storagePoolId != null) {
|
||||
StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
|
||||
|
||||
if (storagePoolVO.isManaged() && !List.of(
|
||||
Storage.StoragePoolType.PowerFlex,
|
||||
Storage.StoragePoolType.FiberChannel).contains(storagePoolVO.getPoolType())) {
|
||||
Long instanceId = volume.getInstanceId();
|
||||
|
||||
if (instanceId != null) {
|
||||
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
|
||||
|
||||
if (vmInstanceVO.getHypervisorType() == HypervisorType.KVM && vmInstanceVO.getState() != State.Stopped) {
|
||||
throw new CloudRuntimeException("This kind of KVM disk cannot be resized while it is connected to a VM that's not in the Stopped state.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's make certain they (think they) know what they're doing if they
|
||||
* want to shrink by forcing them to provide the shrinkok parameter.
|
||||
* This will be checked again at the hypervisor level where we can see
|
||||
* the actual disk size.
|
||||
*/
|
||||
if (currentSize > newSize && !shrinkOk) {
|
||||
throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume."
|
||||
+ "Need to sign off by supplying the shrinkok parameter with value of true.");
|
||||
}
|
||||
|
||||
if (newSize > currentSize) {
|
||||
/* Check resource limit for this account on primary storage resource */
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(),
|
||||
new Long(newSize - currentSize).longValue());
|
||||
}
|
||||
}
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, diskOffering, newDiskOffering);
|
||||
|
||||
// Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
|
||||
// the requested change
|
||||
@ -1310,6 +1260,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
|
||||
_volsDao.update(volume.getId(), volume);
|
||||
_resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
|
||||
diskOffering, newDiskOffering);
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
|
||||
return volume;
|
||||
@ -1420,6 +1372,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
final VolumeVO volume = _volsDao.findById(volumeId);
|
||||
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
Long currentDiskOfferingId = volume.getDiskOfferingId();
|
||||
boolean isManaged = storagePool.isManaged();
|
||||
|
||||
if (!storageMgr.storagePoolHasEnoughSpaceForResize(storagePool, currentSize, newSize)) {
|
||||
@ -1546,11 +1499,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
|
||||
/* Update resource count for the account on primary storage resource */
|
||||
DiskOffering diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
|
||||
if (!shrinkOk) {
|
||||
_resourceLimitMgr.incrementVolumePrimaryStorageResourceCount(volume.getAccountId(), volume.isDisplayVolume(), newSize - currentSize, diskOffering);
|
||||
} else {
|
||||
_resourceLimitMgr.decrementVolumePrimaryStorageResourceCount(volume.getAccountId(), volume.isDisplayVolume(), currentSize - newSize, diskOffering);
|
||||
}
|
||||
DiskOffering currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentDiskOfferingId);
|
||||
_resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize, currentDiskOffering, diskOffering);
|
||||
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
|
||||
@ -2032,7 +1982,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
newMaxIops = updateNewMaxIops[0];
|
||||
newHypervisorSnapshotReserve = updateNewHypervisorSnapshotReserve[0];
|
||||
long currentSize = volume.getSize();
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk);
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, existingDiskOffering, newDiskOffering);
|
||||
|
||||
/* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
|
||||
// We need to publish this event to usage_volume table
|
||||
@ -2050,6 +2000,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
|
||||
_volsDao.update(volume.getId(), volume);
|
||||
_resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
|
||||
existingDiskOffering, newDiskOffering);
|
||||
|
||||
if (currentSize != newSize) {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
|
||||
@ -2303,10 +2256,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
}
|
||||
|
||||
private void validateVolumeResizeWithSize(VolumeVO volume, long currentSize, Long newSize, boolean shrinkOk) throws ResourceAllocationException {
|
||||
private void validateVolumeResizeWithSize(VolumeVO volume, long currentSize, Long newSize, boolean shrinkOk,
|
||||
DiskOfferingVO existingDiskOffering, DiskOfferingVO newDiskOffering) throws ResourceAllocationException {
|
||||
|
||||
// if the caller is looking to change the size of the volume
|
||||
if (currentSize != newSize) {
|
||||
if (newSize != null && currentSize != newSize) {
|
||||
if (volume.getInstanceId() != null) {
|
||||
// Check that VM to which this volume is attached does not have VM snapshots
|
||||
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
|
||||
@ -2323,7 +2277,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
if (storagePoolId != null) {
|
||||
StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
|
||||
|
||||
if (storagePoolVO.isManaged()) {
|
||||
if (storagePoolVO.isManaged() && !List.of(
|
||||
Storage.StoragePoolType.PowerFlex,
|
||||
Storage.StoragePoolType.FiberChannel).contains(storagePoolVO.getPoolType())) {
|
||||
Long instanceId = volume.getInstanceId();
|
||||
|
||||
if (instanceId != null) {
|
||||
@ -2348,18 +2304,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
logger.warn(message);
|
||||
throw new InvalidParameterValueException(message);
|
||||
}
|
||||
}
|
||||
if (currentSize > newSize && !shrinkOk) {
|
||||
if (!shrinkOk) {
|
||||
throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume."
|
||||
+ "Need to sign off by supplying the shrinkok parameter with value of true.");
|
||||
}
|
||||
|
||||
if (newSize > currentSize) {
|
||||
/* Check resource limit for this account on primary storage resource */
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(),
|
||||
new Long(newSize - currentSize).longValue());
|
||||
}
|
||||
}
|
||||
/* Check resource limit for this account */
|
||||
_resourceLimitMgr.checkVolumeResourceLimitForDiskOfferingChange(_accountMgr.getAccount(volume.getAccountId()),
|
||||
volume.isDisplayVolume(), currentSize, newSize != null ? newSize : currentSize,
|
||||
existingDiskOffering, newDiskOffering);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH;
|
||||
import static com.cloud.storage.Volume.IOPS_LIMIT;
|
||||
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
|
||||
import static org.apache.cloudstack.api.ApiConstants.MAX_IOPS;
|
||||
import static org.apache.cloudstack.api.ApiConstants.MIN_IOPS;
|
||||
@ -56,6 +57,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import com.cloud.kubernetes.cluster.KubernetesClusterHelper;
|
||||
import com.cloud.network.dao.NsxProviderDao;
|
||||
import com.cloud.network.element.NsxProviderVO;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.utils.exception.ExceptionProxyObject;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
@ -1350,12 +1352,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||
}
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.checkVmMemoryResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newMemory - currentMemory));
|
||||
}
|
||||
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
|
||||
}
|
||||
|
||||
// Check that the specified service offering ID is valid
|
||||
@ -1372,16 +1370,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
// Increment or decrement CPU and Memory count accordingly.
|
||||
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.incrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||
} else if (currentCpu > newCpu) {
|
||||
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(currentCpu - newCpu));
|
||||
}
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.incrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newMemory - currentMemory));
|
||||
} else if (currentMemory > newMemory) {
|
||||
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(currentMemory - newMemory));
|
||||
}
|
||||
_resourceLimitMgr.updateVmResourceCountForServiceOfferingChange(owner.getAccountId(), vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
|
||||
}
|
||||
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
@ -2063,13 +2053,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
|
||||
// Check resource limits
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||
}
|
||||
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.checkVmMemoryResourceLimit(caller, vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||
}
|
||||
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
|
||||
|
||||
// Dynamically upgrade the running vms
|
||||
boolean success = false;
|
||||
@ -2099,14 +2084,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
boolean existingHostHasCapacity = false;
|
||||
|
||||
// Increment CPU and Memory count accordingly.
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.incrementVmCpuResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||
}
|
||||
|
||||
if (memoryDiff > 0) {
|
||||
_resourceLimitMgr.incrementVmMemoryResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||
}
|
||||
|
||||
_resourceLimitMgr.updateVmResourceCountForServiceOfferingChange(caller.getAccountId(), vmInstance.isDisplay(),
|
||||
(long) currentCpu, (long) newCpu, (long) currentMemory, (long) newMemory,
|
||||
currentServiceOffering, newServiceOffering, template);
|
||||
// #1 Check existing host has capacity
|
||||
if (!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId()))) {
|
||||
existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu, newSpeed)
|
||||
@ -2135,13 +2115,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
} finally {
|
||||
if (!success) {
|
||||
// Decrement CPU and Memory count accordingly.
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.decrementVmCpuResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||
}
|
||||
|
||||
if (memoryDiff > 0) {
|
||||
_resourceLimitMgr.decrementVmMemoryResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||
}
|
||||
_resourceLimitMgr.updateVmResourceCountForServiceOfferingChange(caller.getAccountId(), vmInstance.isDisplay(),
|
||||
(long) newCpu, (long) currentCpu, (long) newMemory, (long) currentMemory,
|
||||
newServiceOffering, currentServiceOffering, template);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2201,8 +2177,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
if (customParameters.containsKey(MIN_IOPS)) {
|
||||
minIopsInNewDiskOffering = Long.parseLong(customParameters.get(MIN_IOPS));
|
||||
}
|
||||
if (customParameters.containsKey(MAX_IOPS)) {
|
||||
minIopsInNewDiskOffering = Long.parseLong(customParameters.get(MAX_IOPS));
|
||||
|
||||
if (customParameters.containsKey(IOPS_LIMIT)) {
|
||||
maxIopsInNewDiskOffering = Long.parseLong(customParameters.get(IOPS_LIMIT));
|
||||
} else if (customParameters.containsKey(MAX_IOPS)) {
|
||||
maxIopsInNewDiskOffering = Long.parseLong(customParameters.get(MAX_IOPS));
|
||||
}
|
||||
if (customParameters.containsKey(ApiConstants.AUTO_MIGRATE)) {
|
||||
autoMigrate = Boolean.parseBoolean(customParameters.get(ApiConstants.AUTO_MIGRATE));
|
||||
@ -3281,7 +3260,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
|
||||
public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Long vmId = cmd.getId();
|
||||
|
||||
@ -7830,7 +7809,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
public UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException {
|
||||
// Input validation
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
@ -7884,12 +7863,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
return restoreVMInternal(caller, vm, newTemplateId, rootDiskOfferingId, expunge, details);
|
||||
}
|
||||
|
||||
public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException {
|
||||
return _itMgr.restoreVirtualMachine(vm.getId(), newTemplateId, rootDiskOfferingId, expunge, details);
|
||||
}
|
||||
|
||||
|
||||
public UserVm restoreVMInternal(Account caller, UserVmVO vm) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
public UserVm restoreVMInternal(Account caller, UserVmVO vm) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException {
|
||||
return restoreVMInternal(caller, vm, null, null, false, null);
|
||||
}
|
||||
|
||||
@ -7981,7 +7960,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
|
||||
VMTemplateVO template = getRestoreVirtualMachineTemplate(caller, newTemplateId, rootVols, vm);
|
||||
checkRestoreVmFromTemplate(vm, template);
|
||||
DiskOffering diskOffering = rootDiskOfferingId != null ? _diskOfferingDao.findById(rootDiskOfferingId) : null;
|
||||
try {
|
||||
checkRestoreVmFromTemplate(vm, template, rootVols, diskOffering, details);
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("Failed to restore VM " + vm.getUuid() + " due to " + e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to restore VM " + vm.getUuid() + " due to " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (needRestart) {
|
||||
try {
|
||||
@ -7994,7 +7979,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
}
|
||||
|
||||
DiskOffering diskOffering = rootDiskOfferingId != null ? _diskOfferingDao.findById(rootDiskOfferingId) : null;
|
||||
for (VolumeVO root : rootVols) {
|
||||
if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ) {
|
||||
_volumeService.validateDestroyVolume(root, caller, expunge, false);
|
||||
@ -8034,7 +8018,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
// 1. Save usage event and update resource count for user vm volumes
|
||||
try {
|
||||
_resourceLimitMgr.incrementVolumeResourceCount(newVol.getAccountId(), newVol.isDisplay(), newVol.getSize(), _diskOfferingDao.findById(newVol.getDiskOfferingId()));
|
||||
_resourceLimitMgr.incrementVolumeResourceCount(userVm.getAccountId(), newVol.isDisplay(),
|
||||
newVol.getSize(), diskOffering != null ? diskOffering : _diskOfferingDao.findById(newVol.getDiskOfferingId()));
|
||||
} catch (final CloudRuntimeException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
@ -8061,6 +8046,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
_volsDao.detachVolume(root.getId());
|
||||
_volumeService.destroyVolume(root.getId(), caller, expunge, false);
|
||||
|
||||
if (currentTemplate.getId() != template.getId() && VirtualMachine.Type.User.equals(vm.type) && !VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||
_resourceLimitMgr.updateVmResourceCountForTemplateChange(vm.getAccountId(), vm.isDisplay(), serviceOffering, currentTemplate, template);
|
||||
}
|
||||
|
||||
// For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
|
||||
if (vm.getHypervisorType() == HypervisorType.VMware) {
|
||||
VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
|
||||
@ -8179,7 +8169,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
* @param template template
|
||||
* @throws InvalidParameterValueException if restore is not possible
|
||||
*/
|
||||
private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template) {
|
||||
private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template, List<VolumeVO> volumes, DiskOffering newDiskOffering, Map<String,String> details) throws ResourceAllocationException {
|
||||
TemplateDataStoreVO tmplStore;
|
||||
if (!template.isDirectDownload()) {
|
||||
tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
|
||||
@ -8192,6 +8182,27 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
throw new InvalidParameterValueException("Cannot restore the vm as the bypassed template " + template.getUuid() + " isn't available in the zone");
|
||||
}
|
||||
}
|
||||
|
||||
AccountVO owner = _accountDao.findByIdIncludingRemoved(vm.getAccountId());
|
||||
if (vm.getTemplateId() != template.getId()) {
|
||||
ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||
VMTemplateVO currentTemplate = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||
_resourceLimitMgr.checkVmResourceLimitsForTemplateChange(owner, vm.isDisplay(), serviceOffering, currentTemplate, template);
|
||||
}
|
||||
|
||||
Long newSize = newDiskOffering != null ? newDiskOffering.getDiskSize() : null;
|
||||
if (MapUtils.isNotEmpty(details) && StringUtils.isNumeric(details.get(VmDetailConstants.ROOT_DISK_SIZE))) {
|
||||
newSize = Long.parseLong(details.get(VmDetailConstants.ROOT_DISK_SIZE)) * GiB_TO_BYTES;
|
||||
}
|
||||
if (newDiskOffering != null || newSize != null) {
|
||||
for (Volume vol : volumes) {
|
||||
if (newDiskOffering != null || !vol.getSize().equals(newSize)) {
|
||||
DiskOffering currentOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
|
||||
_resourceLimitMgr.checkVolumeResourceLimitForDiskOfferingChange(owner, vol.isDisplay(),
|
||||
vol.getSize(), newSize, currentOffering, newDiskOffering);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleManagedStorage(UserVmVO vm, VolumeVO root) {
|
||||
|
||||
@ -1296,7 +1296,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVMNoVM() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVMNoVM() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.lenient().doReturn(accountMock).when(callContextMock).getCallingAccount();
|
||||
|
||||
@ -1309,7 +1309,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testRestoreVMWithVolumeSnapshots() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVMWithVolumeSnapshots() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.lenient().doReturn(accountMock).when(callContextMock).getCallingAccount();
|
||||
Mockito.lenient().doNothing().when(accountManager).checkAccess(accountMock, null, true, userVmVoMock);
|
||||
@ -1323,7 +1323,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineNoOwner() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineNoOwner() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
@ -1336,7 +1336,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testRestoreVirtualMachineOwnerDisabled() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineOwnerDisabled() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
@ -1350,7 +1350,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testRestoreVirtualMachineNotInRightState() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineNotInRightState() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long newTemplateId = 2l;
|
||||
@ -1365,7 +1365,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineNoRootVolume() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineNoRootVolume() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
@ -1386,7 +1386,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineMoreThanOneRootVolume() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineMoreThanOneRootVolume() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
@ -1413,7 +1413,7 @@ public class UserVmManagerImplTest {
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testRestoreVirtualMachineWithVMSnapshots() throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
public void testRestoreVirtualMachineWithVMSnapshots() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
long userId = 1l;
|
||||
long accountId = 2l;
|
||||
long currentTemplateId = 1l;
|
||||
|
||||
@ -272,6 +272,12 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering) {
|
||||
|
||||
@ -282,6 +288,25 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVmResourceCountForTemplateChange(long accountId, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVmResourceCountForServiceOfferingChange(long accountId, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate template) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVolumeResourceCountForDiskOfferingChange(long accountId, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentDiskOffering, DiskOffering newDiskOffering) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering) {
|
||||
|
||||
@ -307,6 +332,20 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate template) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate,
|
||||
VirtualMachineTemplate newTemplate) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user