mirror of https://github.com/apache/cloudstack.git
[22.0] Address limit checks for VM, CPU, memory, volume, and primary storage
This commit is contained in:
parent
f7f0e75122
commit
9c0c8da706
|
|
@ -82,7 +82,7 @@ public interface ProjectService {
|
|||
|
||||
Project updateProject(long id, String name, String displayText, String newOwnerName, Long userId, Role newRole) throws ResourceAllocationException;
|
||||
|
||||
boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType);
|
||||
boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) throws ResourceAllocationException;
|
||||
|
||||
boolean deleteAccountFromProject(long projectId, String accountName);
|
||||
|
||||
|
|
@ -100,6 +100,6 @@ public interface ProjectService {
|
|||
|
||||
Project findByProjectAccountIdIncludingRemoved(long projectAccountId);
|
||||
|
||||
boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole);
|
||||
boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) throws ResourceAllocationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.cloud.exception.ResourceAllocationException;
|
|||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
|
||||
public interface ResourceLimitService {
|
||||
|
||||
|
|
@ -252,12 +253,12 @@ public interface ResourceLimitService {
|
|||
List<String> getResourceLimitStorageTags(DiskOffering diskOffering);
|
||||
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 checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
List<String> getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering);
|
||||
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering) throws ResourceAllocationException;
|
||||
DiskOffering currentOffering, DiskOffering newOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
|
|
@ -274,20 +275,18 @@ public interface ResourceLimitService {
|
|||
|
||||
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 checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Reserver> reservations) 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;
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException;
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate, List<Reserver> reservations) 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);
|
||||
void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException;
|
||||
void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||
void decrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.account;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
|
|
@ -106,7 +107,7 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public void execute() throws ResourceAllocationException {
|
||||
if (accountName == null && email == null) {
|
||||
throw new InvalidParameterValueException("Either accountName or email is required");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
|
|
@ -111,7 +112,7 @@ public class AddUserToProjectCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public void execute() throws ResourceAllocationException {
|
||||
validateInput();
|
||||
boolean result = _projectService.addUserToProject(getProjectId(), getUsername(), getEmail(), getProjectRoleId(), getRoleType());
|
||||
if (result) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,14 @@
|
|||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.resourcelimit;
|
||||
package org.apache.cloudstack.resourcelimit;
|
||||
|
||||
/**
|
||||
* Interface implemented by <code>CheckedReservation</code>.
|
||||
* </br></br>
|
||||
* This is defined in <code>cloud-api</code> to allow methods declared in modules that do not depend on <code>cloud-server</code>
|
||||
* to receive <code>CheckedReservations</code> as parameters.
|
||||
*/
|
||||
public interface Reserver extends AutoCloseable {
|
||||
|
||||
void close();
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.test;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
|
@ -149,6 +150,8 @@ public class AddAccountToProjectCmdTest extends TestCase {
|
|||
addAccountToProjectCmd.execute();
|
||||
} catch (InvalidParameterValueException exception) {
|
||||
Assert.assertEquals("Either accountName or email is required", exception.getLocalizedMessage());
|
||||
} catch (ResourceAllocationException exception) {
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5222,9 +5222,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
private void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) {
|
||||
Map<String, String> details = vmInstanceDetailsDao.listDetailsKeyPairs(vmId);
|
||||
details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
|
||||
details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
|
||||
details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
|
||||
|
||||
// We need to restore only the customizable parameters. If we save a parameter that is not customizable and attempt
|
||||
// to restore a VM snapshot, com.cloud.vm.UserVmManagerImpl.validateCustomParameters will fail.
|
||||
ServiceOffering unfilledOffering = _serviceOfferingDao.findByIdIncludingRemoved(serviceOffering.getId());
|
||||
if (unfilledOffering.getCpu() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
|
||||
}
|
||||
if (unfilledOffering.getSpeed() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
|
||||
}
|
||||
if (unfilledOffering.getRamSize() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
|
||||
}
|
||||
|
||||
List<VMInstanceDetailVO> detailList = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry: details.entrySet()) {
|
||||
VMInstanceDetailVO detailVO = new VMInstanceDetailVO(vmId, entry.getKey(), entry.getValue(), true);
|
||||
|
|
|
|||
|
|
@ -3123,9 +3123,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
CallContext.current().setEventDetails("Network Id: " + network.getId());
|
||||
CallContext.current().putContextParameter(Network.class, network.getUuid());
|
||||
return network;
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import javax.naming.ConfigurationException;
|
|||
|
||||
import com.cloud.deploy.DeploymentClusterPlanner;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
|
|
@ -82,6 +83,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
|||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||
import org.apache.cloudstack.resourcedetail.DiskOfferingDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.secret.PassphraseVO;
|
||||
import org.apache.cloudstack.secret.dao.PassphraseDao;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
|
|
@ -1942,14 +1944,20 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
template == null ? null : template.getSize(),
|
||||
vol.getPassphraseId() != null);
|
||||
|
||||
if (newSize != vol.getSize()) {
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findByIdIncludingRemoved(vol.getDiskOfferingId());
|
||||
if (newSize == vol.getSize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findByIdIncludingRemoved(vol.getDiskOfferingId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
VMInstanceVO vm = vol.getInstanceId() != null ? vmInstanceDao.findById(vol.getInstanceId()) : null;
|
||||
if (vm == null || vm.getType() == VirtualMachine.Type.User) {
|
||||
// Update resource count for user vm volumes when volume is attached
|
||||
if (newSize > vol.getSize()) {
|
||||
_resourceLimitMgr.checkPrimaryStorageResourceLimit(_accountMgr.getActiveAccountById(vol.getAccountId()),
|
||||
vol.isDisplay(), newSize - vol.getSize(), diskOffering);
|
||||
vol.isDisplay(), newSize - vol.getSize(), diskOffering, reservations);
|
||||
_resourceLimitMgr.incrementVolumePrimaryStorageResourceCount(vol.getAccountId(), vol.isDisplay(),
|
||||
newSize - vol.getSize(), diskOffering);
|
||||
} else {
|
||||
|
|
@ -1957,9 +1965,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
vol.getSize() - newSize, diskOffering);
|
||||
}
|
||||
}
|
||||
vol.setSize(newSize);
|
||||
_volsDao.persist(vol);
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
vol.setSize(newSize);
|
||||
_volsDao.persist(vol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_USER_ADD, eventDescription = "adding user to project", async = true)
|
||||
public boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) {
|
||||
public boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) throws ResourceAllocationException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
Project project = getProject(projectId);
|
||||
|
|
@ -614,8 +614,6 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
logger.warn("Failed to add user to project: {}", project);
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -814,7 +812,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true)
|
||||
public boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) {
|
||||
public boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) throws ResourceAllocationException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
//check that the project exists
|
||||
|
|
@ -892,8 +890,6 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
logger.warn("Failed to add account {} to project {}", accountName, project);
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@ package com.cloud.resourcelimit;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.reservation.ReservationVO;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.user.ResourceReservation;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
|
@ -48,12 +51,15 @@ public class CheckedReservation implements Reserver {
|
|||
ReservationDao reservationDao;
|
||||
|
||||
ResourceLimitService resourceLimitService;
|
||||
private final Account account;
|
||||
private Account account;
|
||||
private Long domainId;
|
||||
private final ResourceType resourceType;
|
||||
private Long amount;
|
||||
private ResourceType resourceType;
|
||||
private Long resourceId;
|
||||
private Long reservationAmount;
|
||||
private List<String> reservationTags;
|
||||
private Long existingAmount;
|
||||
private List<String> existingLimitTags;
|
||||
private List<ResourceReservation> reservations;
|
||||
private List<String> resourceLimitTags;
|
||||
|
||||
private String getContextParameterKey() {
|
||||
return getResourceReservationContextParameterKey(resourceType);
|
||||
|
|
@ -100,9 +106,25 @@ public class CheckedReservation implements Reserver {
|
|||
this.reservations.add(reservation);
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, ResourceType resourceType, List<String> resourceLimitTags, Long amount,
|
||||
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, resourceType, null, resourceLimitTags, amount, reservationDao, resourceLimitService);
|
||||
// TODO: refactor these into a Builder to avoid having so many constructors
|
||||
public CheckedReservation(Account account, ResourceType resourceType, List<String> resourceLimitTags, Long reservationAmount,
|
||||
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, resourceType, null, resourceLimitTags, null, reservationAmount, null, reservationDao, resourceLimitService);
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, ResourceType resourceType, Long resourceId, List<String> reservedTags,
|
||||
List<String> existingTags, Long reservationAmount, Long existingAmount, ReservationDao reservationDao,
|
||||
ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, null, resourceType, resourceId, reservedTags, existingTags, reservationAmount, existingAmount, reservationDao, resourceLimitService);
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, Long domainId, ResourceType resourceType, Long resourceId, List<String> reservedTags,
|
||||
Long reservationAmount, ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, domainId, resourceType, resourceId, reservedTags, null, reservationAmount, null, reservationDao, resourceLimitService);
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, ResourceType resourceType, Long resourceId, List<String> reservedTags, Long reservationAmount, ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, null, resourceType, resourceId, reservedTags, null, reservationAmount, null, reservationDao, resourceLimitService);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,36 +132,43 @@ public class CheckedReservation implements Reserver {
|
|||
* - create DB entry for reservation
|
||||
* - hold the id of this record as a ticket for implementation
|
||||
*
|
||||
* @param amount positive number of the resource type to reserve
|
||||
* @param reservationAmount positive number of the resource type to reserve
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
public CheckedReservation(Account account, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount,
|
||||
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, account.getDomainId(), resourceType, resourceId, resourceLimitTags, amount, reservationDao, resourceLimitService);
|
||||
}
|
||||
public CheckedReservation(Account account, Long domainId, ResourceType resourceType, Long resourceId, List<String> reservedTags,
|
||||
List<String> existingTags, Long reservationAmount, Long existingAmount, ReservationDao reservationDao,
|
||||
ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
|
||||
if (ObjectUtils.allNull(account, domainId)) {
|
||||
logger.debug("Not reserving any {} resources, as no account/domain was provided.", resourceType);
|
||||
return;
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, Long domainId, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount,
|
||||
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this.reservationDao = reservationDao;
|
||||
this.resourceLimitService = resourceLimitService;
|
||||
this.account = account;
|
||||
|
||||
this.domainId = domainId;
|
||||
if (domainId == null) {
|
||||
this.domainId = account.getDomainId();
|
||||
domainId = account.getDomainId();
|
||||
}
|
||||
this.domainId = domainId;
|
||||
|
||||
this.resourceType = resourceType;
|
||||
this.amount = amount;
|
||||
this.reservationAmount = reservationAmount;
|
||||
this.existingAmount = existingAmount;
|
||||
this.reservations = new ArrayList<>();
|
||||
this.resourceLimitTags = resourceLimitTags;
|
||||
|
||||
if (this.amount != null && this.amount != 0) {
|
||||
if (amount > 0) {
|
||||
this.reservationTags = getTagsWithoutNull(reservedTags);
|
||||
this.existingLimitTags = getTagsWithoutNull(existingTags);
|
||||
|
||||
// TODO: refactor me
|
||||
if (this.reservationAmount != null && this.reservationAmount != 0) {
|
||||
if (reservationAmount > 0) {
|
||||
setGlobalLock();
|
||||
if (quotaLimitLock.lock(TRY_TO_GET_LOCK_TIME)) {
|
||||
try {
|
||||
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, resourceLimitTags, amount);
|
||||
adjustCountToNotConsiderExistingAmount();
|
||||
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, reservationTags, reservationAmount);
|
||||
CallContext.current().putContextParameter(getContextParameterKey(), getIds());
|
||||
} catch (NullPointerException npe) {
|
||||
throw new CloudRuntimeException("not enough means to check limits", npe);
|
||||
|
|
@ -150,7 +179,7 @@ public class CheckedReservation implements Reserver {
|
|||
throw new ResourceAllocationException(String.format("unable to acquire resource reservation \"%s\"", quotaLimitLock.getName()), resourceType);
|
||||
}
|
||||
} else {
|
||||
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, resourceLimitTags, amount);
|
||||
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, reservationTags, reservationAmount);
|
||||
}
|
||||
} else {
|
||||
logger.debug("not reserving any amount of resources for {} in domain {}, type: {}, tag: {}",
|
||||
|
|
@ -158,6 +187,20 @@ public class CheckedReservation implements Reserver {
|
|||
}
|
||||
}
|
||||
|
||||
protected List<String> getTagsWithoutNull(List<String> tags) {
|
||||
if (tags == null) {
|
||||
return null;
|
||||
}
|
||||
return tags.stream().filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected void adjustCountToNotConsiderExistingAmount() throws ResourceAllocationException {
|
||||
if (existingAmount == null || existingAmount == 0) {
|
||||
return;
|
||||
}
|
||||
checkLimitAndPersistReservations(account, domainId, resourceType, resourceId, existingLimitTags, -1 * existingAmount);
|
||||
}
|
||||
|
||||
public CheckedReservation(Account account, ResourceType resourceType, Long amount, ReservationDao reservationDao,
|
||||
ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||
this(account, resourceType, null, amount, reservationDao, resourceLimitService);
|
||||
|
|
@ -183,11 +226,11 @@ public class CheckedReservation implements Reserver {
|
|||
}
|
||||
|
||||
public String getResourceLimitTagsAsString() {
|
||||
return CollectionUtils.isNotEmpty(resourceLimitTags) ? StringUtils.join(resourceLimitTags) : null;
|
||||
return CollectionUtils.isNotEmpty(reservationTags) ? StringUtils.join(reservationTags) : null;
|
||||
}
|
||||
|
||||
public Long getReservedAmount() {
|
||||
return amount;
|
||||
return reservationAmount;
|
||||
}
|
||||
|
||||
public List<ResourceReservation> getReservations() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
package com.cloud.resourcelimit;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ReservationHelper {
|
||||
|
||||
public static void closeAll(List<Reserver> reservations) throws CloudRuntimeException {
|
||||
for (Reserver reservation : reservations) {
|
||||
reservation.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,6 +53,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.reservation.ReservationVO;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
|
|
@ -175,6 +176,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
@Inject
|
||||
private ReservationDao reservationDao;
|
||||
@Inject
|
||||
private ResourceLimitService resourceLimitService;
|
||||
@Inject
|
||||
protected SnapshotDao _snapshotDao;
|
||||
@Inject
|
||||
protected BackupDao backupDao;
|
||||
|
|
@ -1744,54 +1747,53 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException {
|
||||
public void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitStorageTagsForResourceCountOperation(display, diskOffering);
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
for (String tag : tags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.volume, tag);
|
||||
if (size != null) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.primary_storage, tag, size);
|
||||
}
|
||||
|
||||
CheckedReservation volumeReservation = new CheckedReservation(owner, ResourceType.volume, tags, 1L, reservationDao, resourceLimitService);
|
||||
reservations.add(volumeReservation);
|
||||
|
||||
if (size != null) {
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, tags, size, reservationDao, resourceLimitService);
|
||||
reservations.add(primaryStorageReservation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException {
|
||||
public void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitStorageTagsForResourceCountOperation(display, diskOffering);
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
if (size != null) {
|
||||
for (String tag : tags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.primary_storage, tag, size);
|
||||
}
|
||||
}
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, tags, size, reservationDao, resourceLimitService);
|
||||
reservations.add(primaryStorageReservation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering
|
||||
DiskOffering currentOffering, DiskOffering newOffering, List<Reserver> reservations
|
||||
) 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);
|
||||
}
|
||||
List<String> currentTags = getResourceLimitStorageTagsForResourceCountOperation(true, currentOffering);
|
||||
List<String> tagsAfterUpdate = getResourceLimitStorageTagsForResourceCountOperation(true, newOffering);
|
||||
if (currentTags.isEmpty() && tagsAfterUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.volume, tag, 1L);
|
||||
checkResourceLimitWithTag(owner, ResourceType.primary_storage, tag, newSize);
|
||||
}
|
||||
CheckedReservation volumeReservation = new CheckedReservation(owner, ResourceType.volume, null, tagsAfterUpdate,
|
||||
currentTags, 1L, 1L, reservationDao, resourceLimitService);
|
||||
reservations.add(volumeReservation);
|
||||
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, null,
|
||||
tagsAfterUpdate, currentTags, newSize, currentSize, reservationDao, resourceLimitService);
|
||||
reservations.add(primaryStorageReservation);
|
||||
}
|
||||
|
||||
@DB
|
||||
|
|
@ -2018,20 +2020,27 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException {
|
||||
public void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitHostTagsForResourceCountOperation(display, serviceOffering, template);
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CheckedReservation vmReservation = new CheckedReservation(owner, ResourceType.user_vm, tags, 1L, reservationDao, resourceLimitService);
|
||||
reservations.add(vmReservation);
|
||||
|
||||
Long cpu = serviceOffering.getCpu() != null ? Long.valueOf(serviceOffering.getCpu()) : 0L;
|
||||
CheckedReservation cpuReservation = new CheckedReservation(owner, ResourceType.cpu, tags, cpu, reservationDao, resourceLimitService);
|
||||
reservations.add(cpuReservation);
|
||||
|
||||
Long ram = serviceOffering.getRamSize() != null ? Long.valueOf(serviceOffering.getRamSize()) : 0L;
|
||||
CheckedReservation memReservation = new CheckedReservation(owner, ResourceType.memory, tags, ram, reservationDao, resourceLimitService);
|
||||
reservations.add(memReservation);
|
||||
|
||||
Long gpu = serviceOffering.getGpuCount() != null ? Long.valueOf(serviceOffering.getGpuCount()) : 0L;
|
||||
for (String tag : tags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.user_vm, tag);
|
||||
checkResourceLimitWithTag(owner, ResourceType.cpu, tag, cpu);
|
||||
checkResourceLimitWithTag(owner, ResourceType.memory, tag, ram);
|
||||
checkResourceLimitWithTag(owner, ResourceType.gpu, tag, gpu);
|
||||
}
|
||||
CheckedReservation gpuReservation = new CheckedReservation(owner, ResourceType.gpu, tags, gpu, reservationDao, resourceLimitService);
|
||||
reservations.add(gpuReservation);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2081,83 +2090,60 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException {
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
checkVmResourceLimitsForServiceOfferingAndTemplateChange(owner, display, null, null,
|
||||
null, null, offering, offering, currentTemplate, newTemplate);
|
||||
null, null, offering, offering, currentTemplate, newTemplate, reservations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory,
|
||||
ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template
|
||||
ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List<Reserver> reservations
|
||||
) throws ResourceAllocationException {
|
||||
checkVmResourceLimitsForServiceOfferingAndTemplateChange(owner, display, currentCpu, newCpu, currentMemory, newMemory, currentOffering,
|
||||
newOffering != null ? newOffering : currentOffering, template, template);
|
||||
newOffering != null ? newOffering : currentOffering, template, template, reservations);
|
||||
}
|
||||
|
||||
private void checkVmResourceLimitsForServiceOfferingAndTemplateChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate, List<Reserver> reservations
|
||||
) throws ResourceAllocationException {
|
||||
Ternary<Set<String>, Set<String>, Set<String>> updatedResourceLimitHostTags = getResourceLimitHostTagsForVmServiceOfferingAndTemplateChange(display, currentOffering, newOffering, currentTemplate, newTemplate);
|
||||
if (updatedResourceLimitHostTags == null) {
|
||||
List<String> currentTags = getResourceLimitHostTagsForResourceCountOperation(true, currentOffering, currentTemplate);
|
||||
List<String> tagsAfterUpdate = getResourceLimitHostTagsForResourceCountOperation(true, newOffering, newTemplate);
|
||||
if (currentTags.isEmpty() && tagsAfterUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CheckedReservation vmReservation = new CheckedReservation(owner, ResourceType.user_vm, null, tagsAfterUpdate,
|
||||
currentTags, 1L, 1L, reservationDao, resourceLimitService);
|
||||
reservations.add(vmReservation);
|
||||
|
||||
if (currentCpu == null) {
|
||||
currentCpu = currentOffering.getCpu() != null ? Long.valueOf(currentOffering.getCpu()) : 0L;
|
||||
}
|
||||
if (newCpu == null) {
|
||||
newCpu = newOffering.getCpu() != null ? Long.valueOf(newOffering.getCpu()) : 0L;
|
||||
}
|
||||
CheckedReservation cpuReservation = new CheckedReservation(owner, ResourceType.cpu, null, tagsAfterUpdate,
|
||||
currentTags, newCpu, currentCpu, reservationDao, resourceLimitService);
|
||||
reservations.add(cpuReservation);
|
||||
|
||||
if (currentMemory == null) {
|
||||
currentMemory = currentOffering.getRamSize() != null ? Long.valueOf(currentOffering.getRamSize()) : 0L;
|
||||
}
|
||||
if (newMemory == null) {
|
||||
newMemory = newOffering.getRamSize() != null ? Long.valueOf(newOffering.getRamSize()) : 0L;
|
||||
}
|
||||
CheckedReservation memReservation = new CheckedReservation(owner, ResourceType.memory, null, tagsAfterUpdate,
|
||||
currentTags, newMemory, currentMemory, reservationDao, resourceLimitService);
|
||||
reservations.add(memReservation);
|
||||
|
||||
Long currentGpu = currentOffering.getGpuCount() != null ? Long.valueOf(currentOffering.getGpuCount()) : 0L;
|
||||
Long newGpu = newOffering.getGpuCount() != null ? Long.valueOf(newOffering.getGpuCount()) : 0L;
|
||||
|
||||
Set<String> sameTags = updatedResourceLimitHostTags.first();
|
||||
Set<String> newTags = updatedResourceLimitHostTags.second();
|
||||
|
||||
if (newCpu - currentCpu > 0 || newMemory - currentMemory > 0 || newGpu - currentGpu > 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);
|
||||
}
|
||||
|
||||
if (newGpu - currentGpu > 0) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.gpu, tag, newGpu - currentGpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String tag : newTags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.user_vm, tag, 1L);
|
||||
checkResourceLimitWithTag(owner, ResourceType.cpu, tag, newCpu);
|
||||
checkResourceLimitWithTag(owner, ResourceType.memory, tag, newMemory);
|
||||
checkResourceLimitWithTag(owner, ResourceType.gpu, tag, newGpu);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitHostTagsForResourceCountOperation(display, serviceOffering, template);
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
if (cpu == null) {
|
||||
cpu = serviceOffering.getCpu() != null ? Long.valueOf(serviceOffering.getCpu()) : 0L;
|
||||
}
|
||||
for (String tag : tags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.cpu, tag, cpu);
|
||||
}
|
||||
CheckedReservation gpuReservation = new CheckedReservation(owner, ResourceType.gpu, null, tagsAfterUpdate,
|
||||
currentTags, newGpu, currentGpu, reservationDao, resourceLimitService);
|
||||
reservations.add(gpuReservation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2188,20 +2174,6 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException {
|
||||
List<String> tags = getResourceLimitHostTagsForResourceCountOperation(display, serviceOffering, template);
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
if (memory == null) {
|
||||
memory = serviceOffering.getRamSize() != null ? Long.valueOf(serviceOffering.getRamSize()) : 0L;
|
||||
}
|
||||
for (String tag : tags) {
|
||||
checkResourceLimitWithTag(owner, ResourceType.memory, tag, memory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) {
|
||||
List<String> tags = getResourceLimitHostTagsForResourceCountOperation(display, serviceOffering, template);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
|
@ -94,6 +95,7 @@ import org.apache.cloudstack.resourcedetail.DiskOfferingDetailVO;
|
|||
import org.apache.cloudstack.resourcedetail.SnapshotPolicyDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||
import org.apache.cloudstack.resourcedetail.dao.SnapshotPolicyDetailsDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
import org.apache.cloudstack.storage.command.AttachAnswer;
|
||||
import org.apache.cloudstack.storage.command.AttachCommand;
|
||||
|
|
@ -445,9 +447,17 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
Long diskOfferingId = cmd.getDiskOfferingId();
|
||||
String imageStoreUuid = cmd.getImageStoreUuid();
|
||||
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId);
|
||||
VolumeVO volume;
|
||||
|
||||
VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, format, diskOfferingId, Volume.State.Allocated);
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId, reservations);
|
||||
volume = persistVolume(owner, zoneId, volumeName, url, format, diskOfferingId, Volume.State.Allocated);
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
|
||||
VolumeInfo vol = volFactory.getVolume(volume.getId());
|
||||
|
||||
|
|
@ -487,7 +497,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
final Long diskOfferingId = cmd.getDiskOfferingId();
|
||||
String imageStoreUuid = cmd.getImageStoreUuid();
|
||||
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId);
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId, reservations);
|
||||
|
||||
return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
|
||||
@Override
|
||||
|
|
@ -557,9 +569,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
return response;
|
||||
}
|
||||
});
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format, Long diskOfferingId) throws ResourceAllocationException {
|
||||
private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format, Long diskOfferingId, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
// permission check
|
||||
Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
|
||||
|
|
@ -570,7 +586,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
_accountMgr.checkAccess(caller, null, true, volumeOwner);
|
||||
|
||||
// Check that the resource limit for volumes won't be exceeded
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(volumeOwner, true, null, diskOffering);
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(volumeOwner, true, null, diskOffering, reservations);
|
||||
|
||||
// Verify that zone exists
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
|
|
@ -948,8 +964,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
if (tags.size() == 1 && tags.get(0) == null) {
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
try (CheckedReservation volumeReservation = new CheckedReservation(owner, ResourceType.volume, null, tags, 1L, reservationDao, _resourceLimitMgr);
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, null, tags, size, reservationDao, _resourceLimitMgr)) {
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(owner, displayVolume, size, diskOffering, reservations);
|
||||
|
||||
// Verify that zone exists
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
|
|
@ -972,9 +990,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
|
||||
return commitVolume(cmd.getSnapshotId(), caller, owner, displayVolume, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, userSpecifiedName,
|
||||
_uuidMgr.generateUuid(Volume.class, cmd.getCustomId()), details);
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1300,7 +1317,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
if (dataStore != null && dataStore.getDriver() instanceof PrimaryDataStoreDriver) {
|
||||
newSize = ((PrimaryDataStoreDriver) dataStore.getDriver()).getVolumeSizeRequiredOnPool(newSize, null, isEncryptionRequired);
|
||||
}
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, diskOffering, newDiskOffering);
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, diskOffering, newDiskOffering, reservations);
|
||||
|
||||
// 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
|
||||
|
|
@ -1428,6 +1448,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
|
||||
return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null,
|
||||
shrinkOk);
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateNoVmSnapshots(VolumeVO volume) {
|
||||
|
|
@ -1884,12 +1908,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
throw new InvalidParameterValueException("Please specify a volume in Destroy state.");
|
||||
}
|
||||
|
||||
DiskOffering diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(), volume.getSize());
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("primary storage resource limit check failed", e);
|
||||
throw new InvalidParameterValueException(e.getMessage());
|
||||
}
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(_accountMgr.getAccount(volume.getAccountId()), volume.isDisplayVolume(), volume.getSize(), diskOffering, reservations);
|
||||
|
||||
try {
|
||||
_volsDao.detachVolume(volume.getId());
|
||||
|
|
@ -1901,6 +1924,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
_resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(),
|
||||
volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("primary storage resource limit check failed", e);
|
||||
throw new InvalidParameterValueException(e.getMessage());
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
|
||||
publishVolumeCreationUsageEvent(volume);
|
||||
|
||||
|
|
@ -2130,7 +2159,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
newSize = ((PrimaryDataStoreDriver) dataStore.getDriver()).getVolumeSizeRequiredOnPool(newSize, null, newDiskOffering.getEncrypt());
|
||||
}
|
||||
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, existingDiskOffering, newDiskOffering);
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, existingDiskOffering, newDiskOffering, reservations);
|
||||
|
||||
/* 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
|
||||
|
|
@ -2220,6 +2251,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
}
|
||||
|
||||
return volume;
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStorageWithTheNewDiskOffering(VolumeVO volume, DiskOfferingVO newDiskOffering) {
|
||||
|
|
@ -2425,7 +2460,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
}
|
||||
|
||||
private void validateVolumeResizeWithSize(VolumeVO volume, long currentSize, Long newSize, boolean shrinkOk,
|
||||
DiskOfferingVO existingDiskOffering, DiskOfferingVO newDiskOffering) throws ResourceAllocationException {
|
||||
DiskOfferingVO existingDiskOffering, DiskOfferingVO newDiskOffering, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
// if the caller is looking to change the size of the volume
|
||||
if (newSize != null && currentSize != newSize) {
|
||||
|
|
@ -2489,7 +2524,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
/* Check resource limit for this account */
|
||||
_resourceLimitMgr.checkVolumeResourceLimitForDiskOfferingChange(_accountMgr.getAccount(volume.getAccountId()),
|
||||
volume.isDisplayVolume(), currentSize, newSize != null ? newSize : currentSize,
|
||||
existingDiskOffering, newDiskOffering);
|
||||
existingDiskOffering, newDiskOffering, reservations);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2668,7 +2703,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
|
||||
checkForBackups(vm, true);
|
||||
|
||||
checkRightsToAttach(caller, volumeToAttach, vm);
|
||||
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
|
||||
|
||||
StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
|
||||
if (logger.isTraceEnabled() && volumeToAttachStoragePool != null) {
|
||||
|
|
@ -2692,6 +2727,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
throw new InvalidParameterValueException("Volume's disk offering has encryption enabled, but volume encryption is not supported for hypervisor type " + rootDiskHyperType);
|
||||
}
|
||||
|
||||
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
|
||||
List<String> resourceLimitStorageTags = _resourceLimitMgr.getResourceLimitStorageTagsForResourceCountOperation(true, diskOffering);
|
||||
Long requiredPrimaryStorageSpace = getRequiredPrimaryStorageSizeForVolumeAttach(resourceLimitStorageTags, volumeToAttach);
|
||||
|
||||
try (CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, resourceLimitStorageTags, requiredPrimaryStorageSpace, reservationDao, _resourceLimitMgr)) {
|
||||
|
||||
_jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
|
||||
|
||||
if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
||||
|
|
@ -2699,9 +2740,21 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
} else {
|
||||
return getVolumeAttachJobResult(vmId, volumeId, deviceId);
|
||||
}
|
||||
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("primary storage resource limit check failed", e);
|
||||
throw new InvalidParameterValueException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable private Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
|
||||
protected Long getRequiredPrimaryStorageSizeForVolumeAttach(List<String> resourceLimitStorageTags, VolumeInfo volumeToAttach) {
|
||||
if (CollectionUtils.isEmpty(resourceLimitStorageTags) || Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
|
||||
return 0L;
|
||||
}
|
||||
return volumeToAttach.getSize();
|
||||
}
|
||||
|
||||
@Nullable protected Volume getVolumeAttachJobResult(Long vmId, Long volumeId, Long deviceId) {
|
||||
Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
|
||||
|
||||
Volume vol = null;
|
||||
|
|
@ -2750,21 +2803,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
}
|
||||
}
|
||||
|
||||
private void checkRightsToAttach(Account caller, VolumeInfo volumeToAttach, UserVmVO vm) {
|
||||
_accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
|
||||
|
||||
Account owner = _accountDao.findById(volumeToAttach.getAccountId());
|
||||
|
||||
if (!Arrays.asList(Volume.State.Allocated, Volume.State.Ready).contains(volumeToAttach.getState())) {
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("primary storage resource limit check failed", e);
|
||||
throw new InvalidParameterValueException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForVMSnapshots(Long vmId, UserVmVO vm) {
|
||||
// if target VM has associated VM snapshots
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
|
|
@ -4328,7 +4366,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
_accountMgr.checkAccess(caller, null, true, oldAccount);
|
||||
_accountMgr.checkAccess(caller, null, true, newAccount);
|
||||
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(newAccount, true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
_resourceLimitMgr.checkVolumeResourceLimit(newAccount, true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()), reservations);
|
||||
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
|
|
@ -4338,6 +4378,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
});
|
||||
|
||||
return volume;
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateVolumeAccount(Account oldAccount, VolumeVO volume, Account newAccount) {
|
||||
|
|
|
|||
|
|
@ -2031,16 +2031,13 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
|
|||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.snapshot);
|
||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), storeResourceType, volume.getSize());
|
||||
return snapshot;
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ResourceAllocationException) {
|
||||
if (snapshotType != Type.MANUAL) {
|
||||
String msg = String.format("Snapshot resource limit exceeded for account id : %s. Failed to create recurring snapshots", owner.getId());
|
||||
logger.warn(msg);
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, msg + ". Please, use updateResourceLimit to increase the limit");
|
||||
}
|
||||
throw (ResourceAllocationException) e;
|
||||
} catch (ResourceAllocationException e) {
|
||||
if (snapshotType != Type.MANUAL) {
|
||||
String msg = String.format("Snapshot resource limit exceeded for account id : %s. Failed to create recurring snapshots", owner.getId());
|
||||
logger.warn(msg);
|
||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, msg + ". Please, use updateResourceLimit to increase the limit");
|
||||
}
|
||||
throw new CloudRuntimeException(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.secstorage.dao.SecondaryStorageHeuristicDao;
|
||||
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
|
|
@ -150,6 +151,7 @@ import com.cloud.hypervisor.HypervisorGuru;
|
|||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.ImageStoreUploadMonitorImpl;
|
||||
|
|
@ -199,6 +201,7 @@ import com.cloud.utils.EncryptionUtil;
|
|||
import com.cloud.utils.EnumUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
|
|
@ -301,6 +304,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||
private VMTemplateDetailsDao _tmpltDetailsDao;
|
||||
@Inject
|
||||
private HypervisorGuruManager _hvGuruMgr;
|
||||
@Inject
|
||||
ReservationDao reservationDao;
|
||||
|
||||
private List<TemplateAdapter> _adapters;
|
||||
|
||||
|
|
@ -350,14 +355,30 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||
@ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
|
||||
public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException {
|
||||
TemplateAdapter adapter = getAdapter(HypervisorType.None);
|
||||
TemplateProfile profile = adapter.prepare(cmd);
|
||||
VMTemplateVO template = adapter.create(profile);
|
||||
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
|
||||
|
||||
if (template != null) {
|
||||
CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
|
||||
return template;
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create ISO");
|
||||
// Secondary storage resource count is not incremented for BareMetalTemplateAdapter
|
||||
// Note: checking the file size before registering will require the Management Server host to have access to the Internet and a DNS server
|
||||
// If it does not, UriUtils.getRemoteSize will return 0L.
|
||||
long secondaryStorageUsage = adapter instanceof HypervisorTemplateAdapter && !cmd.isDirectDownload() ?
|
||||
UriUtils.getRemoteSize(cmd.getUrl(), StorageManager.DataStoreDownloadFollowRedirects.value()) : 0L;
|
||||
|
||||
try (CheckedReservation templateReservation = new CheckedReservation(owner, ResourceType.template, null, null, 1L, reservationDao, _resourceLimitMgr);
|
||||
CheckedReservation secondaryStorageReservation = new CheckedReservation(owner, ResourceType.secondary_storage, null, null, secondaryStorageUsage, reservationDao, _resourceLimitMgr)) {
|
||||
TemplateProfile profile = adapter.prepare(cmd);
|
||||
VMTemplateVO template = adapter.create(profile);
|
||||
|
||||
// Secondary storage resource usage will be incremented in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
|
||||
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
|
||||
if (secondaryStorageUsage > 0) {
|
||||
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, secondaryStorageUsage);
|
||||
}
|
||||
if (template != null) {
|
||||
CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
|
||||
return template;
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create ISO");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,17 +398,32 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||
}
|
||||
|
||||
TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
|
||||
TemplateProfile profile = adapter.prepare(cmd);
|
||||
VMTemplateVO template = adapter.create(profile);
|
||||
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
|
||||
|
||||
if (template != null) {
|
||||
CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
|
||||
if (cmd instanceof RegisterVnfTemplateCmd) {
|
||||
vnfTemplateManager.persistVnfTemplate(template.getId(), (RegisterVnfTemplateCmd) cmd);
|
||||
long secondaryStorageUsage = adapter instanceof HypervisorTemplateAdapter && !cmd.isDirectDownload() ?
|
||||
UriUtils.getRemoteSize(cmd.getUrl(), StorageManager.DataStoreDownloadFollowRedirects.value()) : 0L;
|
||||
|
||||
try (CheckedReservation templateReservation = new CheckedReservation(owner, ResourceType.template, null, null, 1L, reservationDao, _resourceLimitMgr);
|
||||
CheckedReservation secondaryStorageReservation = new CheckedReservation(owner, ResourceType.secondary_storage, null, null, secondaryStorageUsage, reservationDao, _resourceLimitMgr)) {
|
||||
TemplateProfile profile = adapter.prepare(cmd);
|
||||
VMTemplateVO template = adapter.create(profile);
|
||||
|
||||
// Secondary storage resource usage will be incremented in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
|
||||
// for HypervisorTemplateAdapter
|
||||
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
|
||||
if (secondaryStorageUsage > 0) {
|
||||
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, secondaryStorageUsage);
|
||||
}
|
||||
|
||||
if (template != null) {
|
||||
CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
|
||||
if (cmd instanceof RegisterVnfTemplateCmd) {
|
||||
vnfTemplateManager.persistVnfTemplate(template.getId(), (RegisterVnfTemplateCmd) cmd);
|
||||
}
|
||||
return template;
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create a template");
|
||||
}
|
||||
return template;
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create a template");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import javax.naming.ConfigurationException;
|
|||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
|
|
@ -136,6 +137,7 @@ import org.apache.cloudstack.framework.messagebus.PublishScope;
|
|||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
import org.apache.cloudstack.storage.command.DeleteCommand;
|
||||
import org.apache.cloudstack.storage.command.DettachCommand;
|
||||
|
|
@ -1391,9 +1393,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template, reservations);
|
||||
}
|
||||
|
||||
// Check that the specified service offering ID is valid
|
||||
|
|
@ -1416,6 +1421,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2109,9 +2117,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
// Check resource limits
|
||||
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
|
||||
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template, reservations);
|
||||
|
||||
// Dynamically upgrade the running vms
|
||||
boolean success = false;
|
||||
|
|
@ -2183,6 +2193,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
}
|
||||
return success;
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateDiskOfferingChecks(ServiceOfferingVO currentServiceOffering, ServiceOfferingVO newServiceOffering) {
|
||||
|
|
@ -2368,10 +2382,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
|
||||
// accountId will not be exceeded
|
||||
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), serviceOffering, template);
|
||||
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), serviceOffering, template, reservations);
|
||||
}
|
||||
|
||||
_haMgr.cancelDestroy(vm, vm.getHostId());
|
||||
|
|
@ -2396,6 +2412,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
//Update Resource Count for the given account
|
||||
resourceCountIncrement(account.getId(), vm.isDisplayVm(), serviceOffering, template);
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -2812,53 +2832,25 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
long currentCpu = currentServiceOffering.getCpu();
|
||||
long currentMemory = currentServiceOffering.getRamSize();
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
Long currentGpu = currentServiceOffering.getGpuCount() != null ? Long.valueOf(currentServiceOffering.getGpuCount()) : 0L;
|
||||
Long newGpu = svcOffering.getGpuCount() != null ? Long.valueOf(svcOffering.getGpuCount()) : 0L;
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
checkVmLimits(owner, vmInstance, svcOffering, template, newCpu, currentCpu, newMemory, currentMemory, newGpu, currentGpu);
|
||||
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), currentCpu, newCpu,
|
||||
currentMemory, newMemory, currentServiceOffering, svcOffering, template, reservations);
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.incrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newCpu - currentCpu);
|
||||
} else if (newCpu > 0 && currentCpu > newCpu){
|
||||
_resourceLimitMgr.decrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentCpu - newCpu);
|
||||
}
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.incrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newMemory - currentMemory);
|
||||
} else if (newMemory > 0 && currentMemory > newMemory){
|
||||
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentMemory - newMemory);
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error(String.format("Failed to updated VM due to: %s", e.getLocalizedMessage()));
|
||||
throw new InvalidParameterValueException(e.getLocalizedMessage());
|
||||
}
|
||||
adjustVmLimits(owner, vmInstance, svcOffering, template, newCpu, currentCpu, newMemory, currentMemory, newGpu, currentGpu);
|
||||
}
|
||||
|
||||
private void checkVmLimits(Account owner, UserVmVO vmInstance, ServiceOfferingVO svcOffering,
|
||||
VMTemplateVO template, Long newCpu, Long currentCpu, Long newMemory, Long currentMemory,
|
||||
Long newGpu, Long currentGpu
|
||||
) throws ResourceAllocationException {
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), svcOffering,
|
||||
template, newCpu - currentCpu);
|
||||
}
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.checkVmMemoryResourceLimit(owner, vmInstance.isDisplay(), svcOffering,
|
||||
template, newMemory - currentMemory);
|
||||
}
|
||||
if (newGpu > currentGpu) {
|
||||
_resourceLimitMgr.checkVmGpuResourceLimit(owner, vmInstance.isDisplay(), svcOffering,
|
||||
template, newGpu - currentGpu);
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustVmLimits(Account owner, UserVmVO vmInstance, ServiceOfferingVO svcOffering,
|
||||
VMTemplateVO template, Long newCpu, Long currentCpu, Long newMemory, Long currentMemory,
|
||||
Long newGpu, Long currentGpu
|
||||
) {
|
||||
if (newCpu > currentCpu) {
|
||||
_resourceLimitMgr.incrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newCpu - currentCpu);
|
||||
} else if (newCpu > 0 && currentCpu > newCpu){
|
||||
_resourceLimitMgr.decrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentCpu - newCpu);
|
||||
}
|
||||
if (newMemory > currentMemory) {
|
||||
_resourceLimitMgr.incrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newMemory - currentMemory);
|
||||
} else if (newMemory > 0 && currentMemory > newMemory){
|
||||
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentMemory - newMemory);
|
||||
}
|
||||
if (newGpu > currentGpu) {
|
||||
_resourceLimitMgr.incrementVmGpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newGpu - currentGpu);
|
||||
} else if (newGpu > 0 && currentGpu > newGpu){
|
||||
_resourceLimitMgr.decrementVmGpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentGpu - newGpu);
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4345,7 +4337,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
throw new InvalidParameterValueException(String.format("Invalid disk offering %s specified for datadisk Template %s. Disk offering size should be greater than or equal to the Template size", dataDiskOffering, dataDiskTemplate));
|
||||
}
|
||||
_templateDao.loadDetails(dataDiskTemplate);
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, dataDiskOffering.getDiskSize(), dataDiskOffering);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5844,11 +5835,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
CheckedReservation memReservation = new CheckedReservation(owner, ResourceType.memory, resourceLimitHostTags, Long.valueOf(offering.getRamSize()), reservationDao, resourceLimitService);
|
||||
) {
|
||||
return startVirtualMachineUnchecked(vm, template, podId, clusterId, hostId, additionalParams, deploymentPlannerToUse, isExplicitHost, isRootAdmin);
|
||||
} catch (ResourceAllocationException | CloudRuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to start VM {} : error during resource reservation and allocation", e);
|
||||
throw new CloudRuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
return startVirtualMachineUnchecked(vm, template, podId, clusterId, hostId, additionalParams, deploymentPlannerToUse, isExplicitHost, isRootAdmin);
|
||||
|
|
@ -7823,38 +7809,29 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
return findMigratedVm(vm.getId(), vm.getType());
|
||||
}
|
||||
|
||||
protected void checkVolumesLimits(Account account, List<VolumeVO> volumes) throws ResourceAllocationException {
|
||||
Long totalVolumes = 0L;
|
||||
Long totalVolumesSize = 0L;
|
||||
protected void checkVolumesLimits(Account account, List<VolumeVO> volumes, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
Map<Long, List<String>> diskOfferingTagsMap = new HashMap<>();
|
||||
Map<String, Long> tagVolumeCountMap = new HashMap<>();
|
||||
Map<String, Long> tagSizeMap = new HashMap<>();
|
||||
|
||||
for (VolumeVO volume : volumes) {
|
||||
if (!volume.isDisplay()) {
|
||||
continue;
|
||||
}
|
||||
totalVolumes++;
|
||||
totalVolumesSize += volume.getSize();
|
||||
if (!diskOfferingTagsMap.containsKey(volume.getDiskOfferingId())) {
|
||||
diskOfferingTagsMap.put(volume.getDiskOfferingId(), _resourceLimitMgr.getResourceLimitStorageTags(
|
||||
_diskOfferingDao.findById(volume.getDiskOfferingId())));
|
||||
|
||||
Long diskOfferingId = volume.getDiskOfferingId();
|
||||
if (!diskOfferingTagsMap.containsKey(diskOfferingId)) {
|
||||
DiskOffering diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||
List<String> tagsForDiskOffering = _resourceLimitMgr.getResourceLimitStorageTags(diskOffering);
|
||||
diskOfferingTagsMap.put(diskOfferingId, tagsForDiskOffering);
|
||||
}
|
||||
List<String> tags = diskOfferingTagsMap.get(volume.getDiskOfferingId());
|
||||
for (String tag : tags) {
|
||||
if (tagVolumeCountMap.containsKey(tag)) {
|
||||
tagVolumeCountMap.put(tag, tagVolumeCountMap.get(tag) + 1);
|
||||
tagSizeMap.put(tag, tagSizeMap.get(tag) + volume.getSize());
|
||||
} else {
|
||||
tagVolumeCountMap.put(tag, 1L);
|
||||
tagSizeMap.put(tag, volume.getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
_resourceLimitMgr.checkResourceLimit(account, ResourceType.volume, totalVolumes);
|
||||
_resourceLimitMgr.checkResourceLimit(account, ResourceType.primary_storage, totalVolumesSize);
|
||||
for (String tag : tagVolumeCountMap.keySet()) {
|
||||
resourceLimitService.checkResourceLimitWithTag(account, ResourceType.volume, tag, tagVolumeCountMap.get(tag));
|
||||
resourceLimitService.checkResourceLimitWithTag(account, ResourceType.primary_storage, tag, tagSizeMap.get(tag));
|
||||
|
||||
List<String> tags = diskOfferingTagsMap.get(diskOfferingId);
|
||||
|
||||
CheckedReservation volumeReservation = new CheckedReservation(account, ResourceType.volume, tags, 1L, reservationDao, resourceLimitService);
|
||||
reservations.add(volumeReservation);
|
||||
|
||||
long size = ObjectUtils.defaultIfNull(volume.getSize(), 0L);
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(account, ResourceType.primary_storage, tags, size, reservationDao, resourceLimitService);
|
||||
reservations.add(primaryStorageReservation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7896,14 +7873,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
final ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
|
||||
VirtualMachineTemplate template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||
|
||||
verifyResourceLimitsForAccountAndStorage(newAccount, vm, offering, volumes, template);
|
||||
|
||||
validateIfNewOwnerHasAccessToTemplate(vm, newAccount, template);
|
||||
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
logger.trace("Verifying if the new account [{}] has access to the specified domain [{}].", newAccount, domain);
|
||||
_accountMgr.checkAccess(newAccount, domain);
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
verifyResourceLimitsForAccountAndStorage(newAccount, vm, offering, volumes, template, reservations);
|
||||
|
||||
Network newNetwork = ensureDestinationNetwork(cmd, vm, newAccount);
|
||||
try {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
|
|
@ -7920,6 +7899,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
throw e;
|
||||
}
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
|
||||
logger.info("VM [{}] now belongs to account [{}].", vm.getInstanceName(), newAccountName);
|
||||
return vm;
|
||||
}
|
||||
|
|
@ -7990,18 +7973,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
* @param volumes The volumes whose total size can exceed resource limits.
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
protected void verifyResourceLimitsForAccountAndStorage(Account account, UserVmVO vm, ServiceOfferingVO offering, List<VolumeVO> volumes, VirtualMachineTemplate template)
|
||||
protected void verifyResourceLimitsForAccountAndStorage(Account account, UserVmVO vm, ServiceOfferingVO offering, List<VolumeVO> volumes, VirtualMachineTemplate template, List<Reserver> reservations)
|
||||
throws ResourceAllocationException {
|
||||
|
||||
logger.trace("Verifying if CPU and RAM for VM [{}] do not exceed account [{}] limit.", vm, account);
|
||||
|
||||
if (!countOnlyRunningVmsInResourceLimitation()) {
|
||||
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), offering, template);
|
||||
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), offering, template, reservations);
|
||||
}
|
||||
|
||||
logger.trace("Verifying if volume size for VM [{}] does not exceed account [{}] limit.", vm, account);
|
||||
|
||||
checkVolumesLimits(account, volumes);
|
||||
checkVolumesLimits(account, volumes, reservations);
|
||||
}
|
||||
|
||||
protected boolean countOnlyRunningVmsInResourceLimitation() {
|
||||
|
|
@ -8894,12 +8877,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
VMTemplateVO template = getRestoreVirtualMachineTemplate(caller, newTemplateId, rootVols, vm);
|
||||
DiskOffering diskOffering = rootDiskOfferingId != null ? _diskOfferingDao.findById(rootDiskOfferingId) : null;
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
checkRestoreVmFromTemplate(vm, template, rootVols, diskOffering, details);
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("Failed to restore VM {} due to {}", vm, e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to restore VM " + vm.getUuid() + " due to " + e.getMessage(), e);
|
||||
}
|
||||
checkRestoreVmFromTemplate(vm, template, rootVols, diskOffering, details, reservations);
|
||||
|
||||
if (needRestart) {
|
||||
try {
|
||||
|
|
@ -9044,6 +9025,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
logger.debug("Restore VM {} done successfully", vm);
|
||||
return vm;
|
||||
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("Failed to restore VM {} due to {}", vm, e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to restore VM " + vm.getUuid() + " due to " + e.getMessage(), e);
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
Long getRootVolumeSizeForVmRestore(Volume vol, VMTemplateVO template, UserVmVO userVm, DiskOffering diskOffering, Map<String, String> details, boolean update) {
|
||||
|
|
@ -9143,7 +9130,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, List<VolumeVO> rootVolumes, DiskOffering newDiskOffering, Map<String,String> details) throws ResourceAllocationException {
|
||||
private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template, List<VolumeVO> rootVolumes, DiskOffering newDiskOffering, Map<String,String> details, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
TemplateDataStoreVO tmplStore;
|
||||
if (!template.isDirectDownload()) {
|
||||
tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
|
||||
|
|
@ -9161,7 +9148,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
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);
|
||||
_resourceLimitMgr.checkVmResourceLimitsForTemplateChange(owner, vm.isDisplay(), serviceOffering, currentTemplate, template, reservations);
|
||||
}
|
||||
|
||||
for (Volume vol : rootVolumes) {
|
||||
|
|
@ -9172,7 +9159,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if (newDiskOffering != null || !vol.getSize().equals(newSize)) {
|
||||
DiskOffering currentOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
|
||||
_resourceLimitMgr.checkVolumeResourceLimitForDiskOfferingChange(owner, vol.isDisplay(),
|
||||
vol.getSize(), newSize, currentOffering, newDiskOffering);
|
||||
vol.getSize(), newSize, currentOffering, newDiskOffering, reservations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -808,25 +808,31 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
|
|||
}
|
||||
|
||||
/**
|
||||
* If snapshot was taken with a different service offering than actual used in vm, should change it back to it
|
||||
* @param userVm vm to change service offering (if necessary)
|
||||
* If snapshot was taken with a different service offering than actual used in vm, should change it back to it.
|
||||
* We also call <code>changeUserVmServiceOffering</code> in case the service offering is dynamic in order to
|
||||
* perform resource limit validation, as the amount of CPUs or memory may have been changed.
|
||||
* @param vmSnapshotVo vm snapshot
|
||||
*/
|
||||
protected void updateUserVmServiceOffering(UserVm userVm, VMSnapshotVO vmSnapshotVo) {
|
||||
if (vmSnapshotVo.getServiceOfferingId() != userVm.getServiceOfferingId()) {
|
||||
changeUserVmServiceOffering(userVm, vmSnapshotVo);
|
||||
return;
|
||||
}
|
||||
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(userVm.getServiceOfferingId());
|
||||
if (serviceOffering.isDynamic()) {
|
||||
changeUserVmServiceOffering(userVm, vmSnapshotVo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user vm details as a map
|
||||
* @param userVm user vm
|
||||
* @param vmSnapshotVo snapshot to get the details from
|
||||
* @return map
|
||||
*/
|
||||
protected Map<String, String> getVmMapDetails(UserVm userVm) {
|
||||
List<VMInstanceDetailVO> userVmDetails = _vmInstanceDetailsDao.listDetails(userVm.getId());
|
||||
protected Map<String, String> getVmMapDetails(VMSnapshotVO vmSnapshotVo) {
|
||||
List<VMSnapshotDetailsVO> vmSnapshotDetails = _vmSnapshotDetailsDao.listDetails(vmSnapshotVo.getId());
|
||||
Map<String, String> details = new HashMap<String, String>();
|
||||
for (VMInstanceDetailVO detail : userVmDetails) {
|
||||
for (VMSnapshotDetailsVO detail : vmSnapshotDetails) {
|
||||
details.put(detail.getName(), detail.getValue());
|
||||
}
|
||||
return details;
|
||||
|
|
@ -838,7 +844,7 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
|
|||
* @param vmSnapshotVo vm snapshot
|
||||
*/
|
||||
protected void changeUserVmServiceOffering(UserVm userVm, VMSnapshotVO vmSnapshotVo) {
|
||||
Map<String, String> vmDetails = getVmMapDetails(userVm);
|
||||
Map<String, String> vmDetails = getVmMapDetails(vmSnapshotVo);
|
||||
boolean result = upgradeUserVmServiceOffering(userVm, vmSnapshotVo.getServiceOfferingId(), vmDetails);
|
||||
if (! result){
|
||||
throw new CloudRuntimeException("VM Snapshot reverting failed due to vm service offering couldn't be changed to the one used when snapshot was taken");
|
||||
|
|
@ -935,8 +941,8 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
|
|||
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<CloudRuntimeException>() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) throws CloudRuntimeException {
|
||||
revertUserVmDetailsFromVmSnapshot(userVm, vmSnapshotVo);
|
||||
updateUserVmServiceOffering(userVm, vmSnapshotVo);
|
||||
revertUserVmDetailsFromVmSnapshot(userVm, vmSnapshotVo);
|
||||
}
|
||||
});
|
||||
return userVm;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.cloud.host.HostVO;
|
|||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.Storage;
|
||||
|
|
@ -68,6 +69,7 @@ import org.apache.cloudstack.api.response.VolumeForImportResponse;
|
|||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
|
@ -198,10 +200,7 @@ public class VolumeImportUnmanageManagerImpl implements VolumeImportUnmanageServ
|
|||
logFailureAndThrowException("Volume is a reference of snapshot on primary: " + volume.getFullPath());
|
||||
}
|
||||
|
||||
// 5. check resource limitation
|
||||
checkResourceLimitForImportVolume(owner, volume);
|
||||
|
||||
// 6. get disk offering
|
||||
// 5. get disk offering
|
||||
DiskOfferingVO diskOffering = getOrCreateDiskOffering(owner, cmd.getDiskOfferingId(), pool.getDataCenterId(), pool.isLocal());
|
||||
if (diskOffering.isCustomized()) {
|
||||
volumeApiService.validateCustomDiskOfferingSizeRange(volume.getVirtualSize() / ByteScaleUtils.GiB);
|
||||
|
|
@ -210,6 +209,11 @@ public class VolumeImportUnmanageManagerImpl implements VolumeImportUnmanageServ
|
|||
logFailureAndThrowException(String.format("Disk offering: %s storage tags are not compatible with selected storage pool: %s", diskOffering, pool));
|
||||
}
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
// 6. check resource limitation
|
||||
checkResourceLimitForImportVolume(owner, volume, diskOffering, reservations);
|
||||
|
||||
// 7. create records
|
||||
String volumeName = StringUtils.isNotBlank(cmd.getName()) ? cmd.getName().trim() : volumePath;
|
||||
VolumeVO volumeVO = importVolumeInternal(volume, diskOffering, owner, pool, volumeName);
|
||||
|
|
@ -221,6 +225,10 @@ public class VolumeImportUnmanageManagerImpl implements VolumeImportUnmanageServ
|
|||
publicUsageEventForVolumeImportAndUnmanage(volumeVO, true);
|
||||
|
||||
return responseGenerator.createVolumeResponse(ResponseObject.ResponseView.Full, volumeVO);
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
protected VolumeOnStorageTO getVolumeOnStorageAndCheck(StoragePoolVO pool, String volumePath) {
|
||||
|
|
@ -456,11 +464,10 @@ public class VolumeImportUnmanageManagerImpl implements VolumeImportUnmanageServ
|
|||
return volumeDao.findById(diskProfile.getVolumeId());
|
||||
}
|
||||
|
||||
protected void checkResourceLimitForImportVolume(Account owner, VolumeOnStorageTO volume) {
|
||||
protected void checkResourceLimitForImportVolume(Account owner, VolumeOnStorageTO volume, DiskOfferingVO diskOffering, List<Reserver> reservations) {
|
||||
Long volumeSize = volume.getVirtualSize();
|
||||
try {
|
||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.volume);
|
||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.primary_storage, volumeSize);
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, volumeSize, diskOffering, reservations);
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("VM resource allocation error for account: {}", owner, e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM resource allocation error for account: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
|
|||
import com.cloud.org.Cluster;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
|
|
@ -166,6 +168,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
|
|
@ -254,6 +258,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
@Inject
|
||||
private ResourceLimitService resourceLimitService;
|
||||
@Inject
|
||||
private ReservationDao reservationDao;
|
||||
@Inject
|
||||
private VMInstanceDetailsDao vmInstanceDetailsDao;
|
||||
@Inject
|
||||
private UserVmManager userVmManager;
|
||||
|
|
@ -639,7 +645,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
return new Pair<>(rootDisk, dataDisks);
|
||||
}
|
||||
|
||||
private void checkUnmanagedDiskAndOfferingForImport(String instanceName, UnmanagedInstanceTO.Disk disk, DiskOffering diskOffering, ServiceOffering serviceOffering, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed)
|
||||
private void checkUnmanagedDiskAndOfferingForImport(String instanceName, UnmanagedInstanceTO.Disk disk, DiskOffering diskOffering, ServiceOffering serviceOffering, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed, List<Reserver> reservations)
|
||||
throws ServerApiException, PermissionDeniedException, ResourceAllocationException {
|
||||
if (serviceOffering == null && diskOffering == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Disk offering for disk ID [%s] not found during VM [%s] import.", disk.getDiskId(), instanceName));
|
||||
|
|
@ -647,7 +653,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
if (diskOffering != null) {
|
||||
accountService.checkAccess(owner, diskOffering, zone);
|
||||
}
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, null, diskOffering);
|
||||
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Size of disk(ID: %s) is found invalid during VM import", disk.getDiskId()));
|
||||
}
|
||||
|
|
@ -662,9 +667,10 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
if (diskOffering != null && !migrateAllowed && !storagePoolSupportsDiskOffering(storagePool, diskOffering)) {
|
||||
throw new InvalidParameterValueException(String.format("Disk offering: %s is not compatible with storage pool: %s of unmanaged disk: %s", diskOffering.getUuid(), storagePool.getUuid(), disk.getDiskId()));
|
||||
}
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, disk.getCapacity(), diskOffering, reservations);
|
||||
}
|
||||
|
||||
private void checkUnmanagedDiskAndOfferingForImport(String intanceName, List<UnmanagedInstanceTO.Disk> disks, final Map<String, Long> diskOfferingMap, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed)
|
||||
private void checkUnmanagedDiskAndOfferingForImport(String intanceName, List<UnmanagedInstanceTO.Disk> disks, final Map<String, Long> diskOfferingMap, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed, List<Reserver> reservations)
|
||||
throws ServerApiException, PermissionDeniedException, ResourceAllocationException {
|
||||
String diskController = null;
|
||||
for (UnmanagedInstanceTO.Disk disk : disks) {
|
||||
|
|
@ -681,7 +687,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Multiple data disk controllers of different type (%s, %s) are not supported for import. Please make sure that all data disk controllers are of the same type", diskController, disk.getController()));
|
||||
}
|
||||
}
|
||||
checkUnmanagedDiskAndOfferingForImport(intanceName, disk, diskOfferingDao.findById(diskOfferingMap.get(disk.getDiskId())), null, owner, zone, cluster, migrateAllowed);
|
||||
checkUnmanagedDiskAndOfferingForImport(intanceName, disk, diskOfferingDao.findById(diskOfferingMap.get(disk.getDiskId())), null, owner, zone, cluster, migrateAllowed, reservations);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1108,40 +1114,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
}
|
||||
}
|
||||
|
||||
protected void checkUnmanagedDiskLimits(Account account, UnmanagedInstanceTO.Disk rootDisk, ServiceOffering serviceOffering,
|
||||
List<UnmanagedInstanceTO.Disk> dataDisks, Map<String, Long> dataDiskOfferingMap) throws ResourceAllocationException {
|
||||
Long totalVolumes = 0L;
|
||||
Long totalVolumesSize = 0L;
|
||||
List<UnmanagedInstanceTO.Disk> disks = new ArrayList<>();
|
||||
disks.add(rootDisk);
|
||||
disks.addAll(dataDisks);
|
||||
Map<String, Long> diskOfferingMap = new HashMap<>(dataDiskOfferingMap);
|
||||
diskOfferingMap.put(rootDisk.getDiskId(), serviceOffering.getDiskOfferingId());
|
||||
Map<Long, Long> diskOfferingVolumeCountMap = new HashMap<>();
|
||||
Map<Long, Long> diskOfferingSizeMap = new HashMap<>();
|
||||
for (UnmanagedInstanceTO.Disk disk : disks) {
|
||||
totalVolumes++;
|
||||
totalVolumesSize += disk.getCapacity();
|
||||
Long diskOfferingId = diskOfferingMap.get(disk.getDiskId());
|
||||
if (diskOfferingVolumeCountMap.containsKey(diskOfferingId)) {
|
||||
diskOfferingVolumeCountMap.put(diskOfferingId, diskOfferingVolumeCountMap.get(diskOfferingId) + 1);
|
||||
diskOfferingSizeMap.put(diskOfferingId, diskOfferingSizeMap.get(diskOfferingId) + disk.getCapacity());
|
||||
} else {
|
||||
diskOfferingVolumeCountMap.put(diskOfferingId, 1L);
|
||||
diskOfferingSizeMap.put(diskOfferingId, disk.getCapacity());
|
||||
}
|
||||
}
|
||||
resourceLimitService.checkResourceLimit(account, Resource.ResourceType.volume, totalVolumes);
|
||||
resourceLimitService.checkResourceLimit(account, Resource.ResourceType.primary_storage, totalVolumesSize);
|
||||
for (Long diskOfferingId : diskOfferingVolumeCountMap.keySet()) {
|
||||
List<String> tags = resourceLimitService.getResourceLimitStorageTags(diskOfferingDao.findById(diskOfferingId));
|
||||
for (String tag : tags) {
|
||||
resourceLimitService.checkResourceLimitWithTag(account, Resource.ResourceType.volume, tag, diskOfferingVolumeCountMap.get(diskOfferingId));
|
||||
resourceLimitService.checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, tag, diskOfferingSizeMap.get(diskOfferingId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedInstance, final String instanceNameInternal, final DataCenter zone, final Cluster cluster, final HostVO host,
|
||||
final VirtualMachineTemplate template, final String displayName, final String hostName, final Account caller, final Account owner, final Long userId,
|
||||
final ServiceOfferingVO serviceOffering, final Map<String, Long> dataDiskOfferingMap,
|
||||
|
|
@ -1199,99 +1171,103 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
allDetails.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(size));
|
||||
}
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), rootDisk, null, validatedServiceOffering, owner, zone, cluster, migrateAllowed);
|
||||
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), rootDisk, null, validatedServiceOffering, owner, zone, cluster, migrateAllowed, reservations);
|
||||
if (CollectionUtils.isNotEmpty(dataDisks)) { // Data disk(s) present
|
||||
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), dataDisks, dataDiskOfferingMap, owner, zone, cluster, migrateAllowed);
|
||||
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), dataDisks, dataDiskOfferingMap, owner, zone, cluster, migrateAllowed, reservations);
|
||||
allDetails.put(VmDetailConstants.DATA_DISK_CONTROLLER, dataDisks.get(0).getController());
|
||||
}
|
||||
checkUnmanagedDiskLimits(owner, rootDisk, serviceOffering, dataDisks, dataDiskOfferingMap);
|
||||
} catch (ResourceAllocationException e) {
|
||||
|
||||
// Check NICs and supplied networks
|
||||
Map<String, Network.IpAddresses> nicIpAddressMap = getNicIpAddresses(unmanagedInstance.getNics(), callerNicIpAddressMap);
|
||||
Map<String, Long> allNicNetworkMap = getUnmanagedNicNetworkMap(unmanagedInstance.getName(), unmanagedInstance.getNics(), nicNetworkMap, nicIpAddressMap, zone, hostName, owner, cluster.getHypervisorType());
|
||||
if (!CollectionUtils.isEmpty(unmanagedInstance.getNics())) {
|
||||
allDetails.put(VmDetailConstants.NIC_ADAPTER, unmanagedInstance.getNics().get(0).getAdapterType());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(unmanagedInstance.getVncPassword())) {
|
||||
allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword());
|
||||
}
|
||||
|
||||
addImportingVMBootTypeAndModeDetails(unmanagedInstance.getBootType(), unmanagedInstance.getBootMode(), allDetails);
|
||||
|
||||
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
||||
if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) {
|
||||
powerState = VirtualMachine.PowerState.PowerOn;
|
||||
}
|
||||
|
||||
try {
|
||||
userVm = userVmManager.importVM(zone, host, template, internalCSName, displayName, owner,
|
||||
null, caller, true, null, owner.getAccountId(), userId,
|
||||
validatedServiceOffering, null, hostName,
|
||||
cluster.getHypervisorType(), allDetails, powerState, null);
|
||||
} catch (InsufficientCapacityException ice) {
|
||||
String errorMsg = String.format("Failed to import VM [%s] due to [%s].", displayName, ice.getMessage());
|
||||
logger.error(errorMsg, ice);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, errorMsg);
|
||||
}
|
||||
|
||||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", displayName));
|
||||
}
|
||||
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
|
||||
try {
|
||||
if (rootDisk.getCapacity() == null || rootDisk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Root disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
Long minIops = null;
|
||||
if (details.containsKey(MIN_IOPS)) {
|
||||
minIops = Long.parseLong(details.get(MIN_IOPS));
|
||||
}
|
||||
Long maxIops = null;
|
||||
if (details.containsKey(MAX_IOPS)) {
|
||||
maxIops = Long.parseLong(details.get(MAX_IOPS));
|
||||
}
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||
diskProfileStoragePoolList.add(importDisk(rootDisk, userVm, cluster, diskOffering, Volume.Type.ROOT, String.format("ROOT-%d", userVm.getId()),
|
||||
rootDisk.getCapacity(), minIops, maxIops, template, owner, null));
|
||||
long deviceId = 1L;
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
diskProfileStoragePoolList.add(importDisk(disk, userVm, cluster, offering, Volume.Type.DATADISK, String.format("DATA-%d-%s", userVm.getId(), disk.getDiskId()),
|
||||
disk.getCapacity(), offering.getMinIops(), offering.getMaxIops(),
|
||||
template, owner, deviceId));
|
||||
deviceId++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import volumes while importing vm: %s", displayName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", displayName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
try {
|
||||
int nicIndex = 0;
|
||||
for (UnmanagedInstanceTO.Nic nic : unmanagedInstance.getNics()) {
|
||||
Network network = networkDao.findById(allNicNetworkMap.get(nic.getNicId()));
|
||||
Network.IpAddresses ipAddresses = nicIpAddressMap.get(nic.getNicId());
|
||||
importNic(nic, userVm, network, ipAddresses, nicIndex, nicIndex == 0, forced);
|
||||
nicIndex++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import NICs while importing vm: %s", displayName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", displayName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
if (migrateAllowed) {
|
||||
userVm = migrateImportedVM(host, template, validatedServiceOffering, userVm, owner, diskProfileStoragePoolList);
|
||||
}
|
||||
publishVMUsageUpdateResourceCount(userVm, validatedServiceOffering, template);
|
||||
return userVm;
|
||||
|
||||
} catch (ResourceAllocationException e) { // This will be thrown by checkUnmanagedDiskAndOfferingForImport, so the VM was not imported yet
|
||||
logger.error("Volume resource allocation error for owner: {}", owner, e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resource allocation error for owner: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
// Check NICs and supplied networks
|
||||
Map<String, Network.IpAddresses> nicIpAddressMap = getNicIpAddresses(unmanagedInstance.getNics(), callerNicIpAddressMap);
|
||||
Map<String, Long> allNicNetworkMap = getUnmanagedNicNetworkMap(unmanagedInstance.getName(), unmanagedInstance.getNics(), nicNetworkMap, nicIpAddressMap, zone, hostName, owner, cluster.getHypervisorType());
|
||||
if (!CollectionUtils.isEmpty(unmanagedInstance.getNics())) {
|
||||
allDetails.put(VmDetailConstants.NIC_ADAPTER, unmanagedInstance.getNics().get(0).getAdapterType());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(unmanagedInstance.getVncPassword())) {
|
||||
allDetails.put(VmDetailConstants.KVM_VNC_PASSWORD, unmanagedInstance.getVncPassword());
|
||||
}
|
||||
|
||||
addImportingVMBootTypeAndModeDetails(unmanagedInstance.getBootType(), unmanagedInstance.getBootMode(), allDetails);
|
||||
|
||||
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
||||
if (unmanagedInstance.getPowerState().equals(UnmanagedInstanceTO.PowerState.PowerOn)) {
|
||||
powerState = VirtualMachine.PowerState.PowerOn;
|
||||
}
|
||||
|
||||
try {
|
||||
userVm = userVmManager.importVM(zone, host, template, internalCSName, displayName, owner,
|
||||
null, caller, true, null, owner.getAccountId(), userId,
|
||||
validatedServiceOffering, null, hostName,
|
||||
cluster.getHypervisorType(), allDetails, powerState, null);
|
||||
} catch (InsufficientCapacityException ice) {
|
||||
String errorMsg = String.format("Failed to import VM [%s] due to [%s].", displayName, ice.getMessage());
|
||||
logger.error(errorMsg, ice);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, errorMsg);
|
||||
}
|
||||
|
||||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", displayName));
|
||||
}
|
||||
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
|
||||
try {
|
||||
if (rootDisk.getCapacity() == null || rootDisk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Root disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
Long minIops = null;
|
||||
if (details.containsKey(MIN_IOPS)) {
|
||||
minIops = Long.parseLong(details.get(MIN_IOPS));
|
||||
}
|
||||
Long maxIops = null;
|
||||
if (details.containsKey(MAX_IOPS)) {
|
||||
maxIops = Long.parseLong(details.get(MAX_IOPS));
|
||||
}
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||
diskProfileStoragePoolList.add(importDisk(rootDisk, userVm, cluster, diskOffering, Volume.Type.ROOT, String.format("ROOT-%d", userVm.getId()),
|
||||
rootDisk.getCapacity(), minIops, maxIops, template, owner, null));
|
||||
long deviceId = 1L;
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
diskProfileStoragePoolList.add(importDisk(disk, userVm, cluster, offering, Volume.Type.DATADISK, String.format("DATA-%d-%s", userVm.getId(), disk.getDiskId()),
|
||||
disk.getCapacity(), offering.getMinIops(), offering.getMaxIops(),
|
||||
template, owner, deviceId));
|
||||
deviceId++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import volumes while importing vm: %s", displayName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", displayName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
try {
|
||||
int nicIndex = 0;
|
||||
for (UnmanagedInstanceTO.Nic nic : unmanagedInstance.getNics()) {
|
||||
Network network = networkDao.findById(allNicNetworkMap.get(nic.getNicId()));
|
||||
Network.IpAddresses ipAddresses = nicIpAddressMap.get(nic.getNicId());
|
||||
importNic(nic, userVm, network, ipAddresses, nicIndex, nicIndex == 0, forced);
|
||||
nicIndex++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import NICs while importing vm: %s", displayName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", displayName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
if (migrateAllowed) {
|
||||
userVm = migrateImportedVM(host, template, validatedServiceOffering, userVm, owner, diskProfileStoragePoolList);
|
||||
}
|
||||
publishVMUsageUpdateResourceCount(userVm, validatedServiceOffering, template);
|
||||
return userVm;
|
||||
}
|
||||
|
||||
private void addImportingVMBootTypeAndModeDetails(String bootType, String bootMode, Map<String, String> allDetails) {
|
||||
|
|
@ -1396,8 +1372,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
VMTemplateVO template = getTemplateForImportInstance(cmd.getTemplateId(), cluster.getHypervisorType());
|
||||
ServiceOfferingVO serviceOffering = getServiceOfferingForImportInstance(cmd.getServiceOfferingId(), owner, zone);
|
||||
|
||||
checkResourceLimitForImportInstance(owner);
|
||||
|
||||
String displayName = getDisplayNameForImportInstance(cmd.getDisplayName(), instanceName);
|
||||
String hostName = getHostNameForImportInstance(cmd.getHostName(), cluster.getHypervisorType(), instanceName, displayName);
|
||||
|
||||
|
|
@ -1413,31 +1387,41 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
List<String> managedVms = new ArrayList<>(additionalNameFilters);
|
||||
managedVms.addAll(getHostsManagedVms(hosts));
|
||||
|
||||
ActionEventUtils.onStartedActionEvent(userId, owner.getId(), EventTypes.EVENT_VM_IMPORT,
|
||||
cmd.getEventDescription(), null, null, true, 0);
|
||||
List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(serviceOffering, template);
|
||||
try (CheckedReservation vmReservation = new CheckedReservation(owner, Resource.ResourceType.user_vm, resourceLimitHostTags, 1L, reservationDao, resourceLimitService);
|
||||
CheckedReservation cpuReservation = new CheckedReservation(owner, Resource.ResourceType.cpu, resourceLimitHostTags, Long.valueOf(serviceOffering.getCpu()), reservationDao, resourceLimitService);
|
||||
CheckedReservation memReservation = new CheckedReservation(owner, Resource.ResourceType.memory, resourceLimitHostTags, Long.valueOf(serviceOffering.getRamSize()), reservationDao, resourceLimitService)) {
|
||||
|
||||
if (cmd instanceof ImportVmCmd) {
|
||||
ImportVmCmd importVmCmd = (ImportVmCmd) cmd;
|
||||
if (StringUtils.isBlank(importVmCmd.getImportSource())) {
|
||||
throw new CloudRuntimeException("Please provide an import source for importing the VM");
|
||||
}
|
||||
String source = importVmCmd.getImportSource().toUpperCase();
|
||||
ImportSource importSource = Enum.valueOf(ImportSource.class, source);
|
||||
if (ImportSource.VMWARE == importSource) {
|
||||
userVm = importUnmanagedInstanceFromVmwareToKvm(zone, cluster,
|
||||
template, instanceName, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap,
|
||||
details, importVmCmd, forced);
|
||||
}
|
||||
} else {
|
||||
if (List.of(Hypervisor.HypervisorType.VMware, Hypervisor.HypervisorType.KVM).contains(cluster.getHypervisorType())) {
|
||||
userVm = importUnmanagedInstanceFromHypervisor(zone, cluster, hosts, additionalNameFilters,
|
||||
template, instanceName, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap,
|
||||
details, cmd.getMigrateAllowed(), managedVms, forced);
|
||||
ActionEventUtils.onStartedActionEvent(userId, owner.getId(), EventTypes.EVENT_VM_IMPORT,
|
||||
cmd.getEventDescription(), null, null, true, 0);
|
||||
|
||||
if (cmd instanceof ImportVmCmd) {
|
||||
ImportVmCmd importVmCmd = (ImportVmCmd) cmd;
|
||||
if (StringUtils.isBlank(importVmCmd.getImportSource())) {
|
||||
throw new CloudRuntimeException("Please provide an import source for importing the VM");
|
||||
}
|
||||
String source = importVmCmd.getImportSource().toUpperCase();
|
||||
ImportSource importSource = Enum.valueOf(ImportSource.class, source);
|
||||
if (ImportSource.VMWARE == importSource) {
|
||||
userVm = importUnmanagedInstanceFromVmwareToKvm(zone, cluster,
|
||||
template, instanceName, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap,
|
||||
details, importVmCmd, forced);
|
||||
}
|
||||
} else {
|
||||
if (List.of(Hypervisor.HypervisorType.VMware, Hypervisor.HypervisorType.KVM).contains(cluster.getHypervisorType())) {
|
||||
userVm = importUnmanagedInstanceFromHypervisor(zone, cluster, hosts, additionalNameFilters,
|
||||
template, instanceName, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap,
|
||||
details, cmd.getMigrateAllowed(), managedVms, forced);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error(String.format("VM resource allocation error for account: %s", owner.getUuid()), e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM resource allocation error for account: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
|
||||
if (userVm == null) {
|
||||
|
|
@ -1526,15 +1510,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
return StringUtils.isEmpty(displayName) ? instanceName : displayName;
|
||||
}
|
||||
|
||||
private void checkResourceLimitForImportInstance(Account owner) {
|
||||
try {
|
||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.user_vm, 1);
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("VM resource allocation error for account: {}", owner, e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM resource allocation error for account: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceOfferingVO getServiceOfferingForImportInstance(Long serviceOfferingId, Account owner, DataCenter zone) {
|
||||
if (serviceOfferingId == null) {
|
||||
throw new InvalidParameterValueException("Service offering ID cannot be null");
|
||||
|
|
@ -2520,12 +2495,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
throw new InvalidParameterValueException(String.format("Service offering ID: %d cannot be found", serviceOfferingId));
|
||||
}
|
||||
accountService.checkAccess(owner, serviceOffering, zone);
|
||||
try {
|
||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.user_vm, 1);
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error("VM resource allocation error for account: {}", owner, e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM resource allocation error for account: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
String displayName = cmd.getDisplayName();
|
||||
if (StringUtils.isEmpty(displayName)) {
|
||||
displayName = instanceName;
|
||||
|
|
@ -2613,26 +2582,37 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
|
||||
UserVm userVm = null;
|
||||
|
||||
if (ImportSource.EXTERNAL == importSource) {
|
||||
String username = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
String tmpPath = cmd.getTmpPath();
|
||||
userVm = importExternalKvmVirtualMachine(unmanagedInstanceTO, instanceName, zone,
|
||||
template, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap, remoteUrl, username, password, tmpPath, details);
|
||||
} else if (ImportSource.SHARED == importSource || ImportSource.LOCAL == importSource) {
|
||||
try {
|
||||
userVm = importKvmVirtualMachineFromDisk(importSource, instanceName, zone,
|
||||
List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(serviceOffering, template);
|
||||
try (CheckedReservation vmReservation = new CheckedReservation(owner, Resource.ResourceType.user_vm, resourceLimitHostTags, 1L, reservationDao, resourceLimitService);
|
||||
CheckedReservation cpuReservation = new CheckedReservation(owner, Resource.ResourceType.cpu, resourceLimitHostTags, Long.valueOf(serviceOffering.getCpu()), reservationDao, resourceLimitService);
|
||||
CheckedReservation memReservation = new CheckedReservation(owner, Resource.ResourceType.memory, resourceLimitHostTags, Long.valueOf(serviceOffering.getRamSize()), reservationDao, resourceLimitService)) {
|
||||
|
||||
if (ImportSource.EXTERNAL == importSource) {
|
||||
String username = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
String tmpPath = cmd.getTmpPath();
|
||||
userVm = importExternalKvmVirtualMachine(unmanagedInstanceTO, instanceName, zone,
|
||||
template, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap, networkId, hostId, poolId, diskPath,
|
||||
details);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
serviceOffering, dataDiskOfferingMap,
|
||||
nicNetworkMap, nicIpAddressMap, remoteUrl, username, password, tmpPath, details);
|
||||
} else if (ImportSource.SHARED == importSource || ImportSource.LOCAL == importSource) {
|
||||
try {
|
||||
userVm = importKvmVirtualMachineFromDisk(importSource, instanceName, zone,
|
||||
template, displayName, hostName, caller, owner, userId,
|
||||
serviceOffering, dataDiskOfferingMap, networkId, hostId, poolId, diskPath,
|
||||
details);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ResourceAllocationException e) {
|
||||
logger.error(String.format("VM resource allocation error for account: %s", owner.getUuid()), e);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM resource allocation error for account: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
|
||||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import Vm with name: %s ", instanceName));
|
||||
}
|
||||
|
|
@ -2646,7 +2626,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
final VirtualMachineTemplate template, final String displayName, final String hostName, final Account caller, final Account owner, final Long userId,
|
||||
final ServiceOfferingVO serviceOffering, final Map<String, Long> dataDiskOfferingMap,
|
||||
final Map<String, Long> nicNetworkMap, final Map<String, Network.IpAddresses> callerNicIpAddressMap,
|
||||
final String remoteUrl, String username, String password, String tmpPath, final Map<String, String> details) {
|
||||
final String remoteUrl, String username, String password, String tmpPath, final Map<String, String> details) throws ResourceAllocationException {
|
||||
UserVm userVm = null;
|
||||
|
||||
Map<String, String> allDetails = new HashMap<>(details);
|
||||
|
|
@ -2657,6 +2637,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("No attached disks found for the unmanaged VM: %s", instanceName));
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||
Pair<UnmanagedInstanceTO.Disk, List<UnmanagedInstanceTO.Disk>> rootAndDataDisksPair = getRootAndDataDisks(unmanagedInstanceDisks, dataDiskOfferingMap);
|
||||
final UnmanagedInstanceTO.Disk rootDisk = rootAndDataDisksPair.first();
|
||||
final List<UnmanagedInstanceTO.Disk> dataDisks = rootAndDataDisksPair.second();
|
||||
|
|
@ -2665,97 +2646,117 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
}
|
||||
allDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDisk.getController());
|
||||
|
||||
// Check NICs and supplied networks
|
||||
Map<String, Network.IpAddresses> nicIpAddressMap = getNicIpAddresses(unmanagedInstance.getNics(), callerNicIpAddressMap);
|
||||
Map<String, Long> allNicNetworkMap = getUnmanagedNicNetworkMap(unmanagedInstance.getName(), unmanagedInstance.getNics(), nicNetworkMap, nicIpAddressMap, zone, hostName, owner, Hypervisor.HypervisorType.KVM);
|
||||
if (!CollectionUtils.isEmpty(unmanagedInstance.getNics())) {
|
||||
allDetails.put(VmDetailConstants.NIC_ADAPTER, unmanagedInstance.getNics().get(0).getAdapterType());
|
||||
}
|
||||
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
userVm = userVmManager.importVM(zone, null, template, null, displayName, owner,
|
||||
null, caller, true, null, owner.getAccountId(), userId,
|
||||
serviceOffering, null, hostName,
|
||||
Hypervisor.HypervisorType.KVM, allDetails, powerState, null);
|
||||
} catch (InsufficientCapacityException ice) {
|
||||
logger.error(String.format("Failed to import vm name: %s", instanceName), ice);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ice.getMessage());
|
||||
}
|
||||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", instanceName));
|
||||
}
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||
String rootVolumeName = String.format("ROOT-%s", userVm.getId());
|
||||
DiskProfile diskProfile = volumeManager.allocateRawVolume(Volume.Type.ROOT, rootVolumeName, diskOffering, null, null, null, userVm, template, owner, null);
|
||||
checkVolumeResourceLimitsForExternalKvmVmImport(owner, rootDisk, dataDisks, diskOffering, dataDiskOfferingMap, reservations);
|
||||
|
||||
DiskProfile[] dataDiskProfiles = new DiskProfile[dataDisks.size()];
|
||||
int diskSeq = 0;
|
||||
// Check NICs and supplied networks
|
||||
Map<String, Network.IpAddresses> nicIpAddressMap = getNicIpAddresses(unmanagedInstance.getNics(), callerNicIpAddressMap);
|
||||
Map<String, Long> allNicNetworkMap = getUnmanagedNicNetworkMap(unmanagedInstance.getName(), unmanagedInstance.getNics(), nicNetworkMap, nicIpAddressMap, zone, hostName, owner, Hypervisor.HypervisorType.KVM);
|
||||
if (!CollectionUtils.isEmpty(unmanagedInstance.getNics())) {
|
||||
allDetails.put(VmDetailConstants.NIC_ADAPTER, unmanagedInstance.getNics().get(0).getAdapterType());
|
||||
}
|
||||
VirtualMachine.PowerState powerState = VirtualMachine.PowerState.PowerOff;
|
||||
|
||||
try {
|
||||
userVm = userVmManager.importVM(zone, null, template, null, displayName, owner,
|
||||
null, caller, true, null, owner.getAccountId(), userId,
|
||||
serviceOffering, null, hostName,
|
||||
Hypervisor.HypervisorType.KVM, allDetails, powerState, null);
|
||||
} catch (InsufficientCapacityException ice) {
|
||||
logger.error(String.format("Failed to import vm name: %s", instanceName), ice);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ice.getMessage());
|
||||
}
|
||||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", instanceName));
|
||||
}
|
||||
String rootVolumeName = String.format("ROOT-%s", userVm.getId());
|
||||
DiskProfile diskProfile = volumeManager.allocateRawVolume(Volume.Type.ROOT, rootVolumeName, diskOffering, null, null, null, userVm, template, owner, null);
|
||||
|
||||
DiskProfile[] dataDiskProfiles = new DiskProfile[dataDisks.size()];
|
||||
int diskSeq = 0;
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
DiskProfile dataDiskProfile = volumeManager.allocateRawVolume(Volume.Type.DATADISK, String.format("DATA-%d-%s", userVm.getId(), disk.getDiskId()), offering, null, null, null, userVm, template, owner, null);
|
||||
dataDiskProfiles[diskSeq++] = dataDiskProfile;
|
||||
}
|
||||
|
||||
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(userVm, template, serviceOffering, owner, null);
|
||||
ServiceOfferingVO dummyOffering = serviceOfferingDao.findById(userVm.getId(), serviceOffering.getId());
|
||||
profile.setServiceOffering(dummyOffering);
|
||||
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
|
||||
final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null, null, null);
|
||||
DeployDestination dest = null;
|
||||
try {
|
||||
dest = deploymentPlanningManager.planDeployment(profile, plan, excludeList, null);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Import failed for Vm: {} while finding deployment destination", userVm, e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s while finding deployment destination", userVm.getInstanceName()));
|
||||
}
|
||||
if(dest == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s. Suitable deployment destination not found", userVm.getInstanceName()));
|
||||
}
|
||||
|
||||
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
|
||||
try {
|
||||
diskProfileStoragePoolList.add(importExternalDisk(rootDisk, userVm, dest, diskOffering, Volume.Type.ROOT,
|
||||
template, null, remoteUrl, username, password, tmpPath, diskProfile));
|
||||
|
||||
long deviceId = 1L;
|
||||
diskSeq = 0;
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
DiskProfile dataDiskProfile = dataDiskProfiles[diskSeq++];
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
|
||||
diskProfileStoragePoolList.add(importExternalDisk(disk, userVm, dest, offering, Volume.Type.DATADISK,
|
||||
template, deviceId, remoteUrl, username, password, tmpPath, dataDiskProfile));
|
||||
deviceId++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import volumes while importing vm: %s", instanceName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
try {
|
||||
int nicIndex = 0;
|
||||
for (UnmanagedInstanceTO.Nic nic : unmanagedInstance.getNics()) {
|
||||
Network network = networkDao.findById(allNicNetworkMap.get(nic.getNicId()));
|
||||
Network.IpAddresses ipAddresses = nicIpAddressMap.get(nic.getNicId());
|
||||
importNic(nic, userVm, network, ipAddresses, nicIndex, nicIndex==0, true);
|
||||
nicIndex++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import NICs while importing vm: %s", instanceName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
publishVMUsageUpdateResourceCount(userVm, dummyOffering, template);
|
||||
return userVm;
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkVolumeResourceLimitsForExternalKvmVmImport(Account owner, UnmanagedInstanceTO.Disk rootDisk,
|
||||
List<UnmanagedInstanceTO.Disk> dataDisks, DiskOfferingVO rootDiskOffering,
|
||||
Map<String, Long> dataDiskOfferingMap, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
if (rootDisk.getCapacity() == null || rootDisk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Root disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, rootDisk.getCapacity(), rootDiskOffering, reservations);
|
||||
|
||||
if (CollectionUtils.isEmpty(dataDisks)) {
|
||||
return;
|
||||
}
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Disk ID: %s size is invalid", disk.getDiskId()));
|
||||
throw new InvalidParameterValueException(String.format("Data disk ID: %s size is invalid", disk.getDiskId()));
|
||||
}
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
DiskProfile dataDiskProfile = volumeManager.allocateRawVolume(Volume.Type.DATADISK, String.format("DATA-%d-%s", userVm.getId(), disk.getDiskId()), offering, null, null, null, userVm, template, owner, null);
|
||||
dataDiskProfiles[diskSeq++] = dataDiskProfile;
|
||||
resourceLimitService.checkVolumeResourceLimit(owner, true, disk.getCapacity(), offering, reservations);
|
||||
}
|
||||
|
||||
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(userVm, template, serviceOffering, owner, null);
|
||||
ServiceOfferingVO dummyOffering = serviceOfferingDao.findById(userVm.getId(), serviceOffering.getId());
|
||||
profile.setServiceOffering(dummyOffering);
|
||||
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
|
||||
final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null, null, null);
|
||||
DeployDestination dest = null;
|
||||
try {
|
||||
dest = deploymentPlanningManager.planDeployment(profile, plan, excludeList, null);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Import failed for Vm: {} while finding deployment destination", userVm, e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s while finding deployment destination", userVm.getInstanceName()));
|
||||
}
|
||||
if(dest == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s. Suitable deployment destination not found", userVm.getInstanceName()));
|
||||
}
|
||||
|
||||
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
|
||||
try {
|
||||
if (rootDisk.getCapacity() == null || rootDisk.getCapacity() == 0) {
|
||||
throw new InvalidParameterValueException(String.format("Root disk ID: %s size is invalid", rootDisk.getDiskId()));
|
||||
}
|
||||
|
||||
diskProfileStoragePoolList.add(importExternalDisk(rootDisk, userVm, dest, diskOffering, Volume.Type.ROOT,
|
||||
template, null, remoteUrl, username, password, tmpPath, diskProfile));
|
||||
|
||||
long deviceId = 1L;
|
||||
diskSeq = 0;
|
||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||
DiskProfile dataDiskProfile = dataDiskProfiles[diskSeq++];
|
||||
DiskOffering offering = diskOfferingDao.findById(dataDiskOfferingMap.get(disk.getDiskId()));
|
||||
|
||||
diskProfileStoragePoolList.add(importExternalDisk(disk, userVm, dest, offering, Volume.Type.DATADISK,
|
||||
template, deviceId, remoteUrl, username, password, tmpPath, dataDiskProfile));
|
||||
deviceId++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import volumes while importing vm: %s", instanceName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
try {
|
||||
int nicIndex = 0;
|
||||
for (UnmanagedInstanceTO.Nic nic : unmanagedInstance.getNics()) {
|
||||
Network network = networkDao.findById(allNicNetworkMap.get(nic.getNicId()));
|
||||
Network.IpAddresses ipAddresses = nicIpAddressMap.get(nic.getNicId());
|
||||
importNic(nic, userVm, network, ipAddresses, nicIndex, nicIndex==0, true);
|
||||
nicIndex++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(String.format("Failed to import NICs while importing vm: %s", instanceName), e);
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||
}
|
||||
publishVMUsageUpdateResourceCount(userVm, dummyOffering, template);
|
||||
return userVm;
|
||||
}
|
||||
|
||||
private UserVm importKvmVirtualMachineFromDisk(final ImportSource importSource, final String instanceName, final DataCenter zone,
|
||||
|
|
@ -2823,7 +2824,16 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
if (userVm == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", instanceName));
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
List<String> resourceLimitStorageTags = resourceLimitService.getResourceLimitStorageTagsForResourceCountOperation(true, diskOffering);
|
||||
try {
|
||||
CheckedReservation volumeReservation = new CheckedReservation(owner, Resource.ResourceType.volume, resourceLimitStorageTags,
|
||||
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? 1L : 0L, reservationDao, resourceLimitService);
|
||||
reservations.add(volumeReservation);
|
||||
|
||||
String rootVolumeName = String.format("ROOT-%s", userVm.getId());
|
||||
DiskProfile diskProfile = volumeManager.allocateRawVolume(Volume.Type.ROOT, rootVolumeName, diskOffering, null, null, null, userVm, template, owner, null);
|
||||
|
||||
|
|
@ -2868,6 +2878,14 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
throw new CloudRuntimeException("Disk not found or is invalid");
|
||||
}
|
||||
diskProfile.setSize(checkVolumeAnswer.getSize());
|
||||
try {
|
||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, Resource.ResourceType.primary_storage, resourceLimitStorageTags,
|
||||
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? diskProfile.getSize() : 0L, reservationDao, resourceLimitService);
|
||||
reservations.add(primaryStorageReservation);
|
||||
} catch (ResourceAllocationException e) {
|
||||
cleanupFailedImportVM(userVm);
|
||||
throw e;
|
||||
}
|
||||
|
||||
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
|
||||
try {
|
||||
|
|
@ -2887,6 +2905,10 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
networkOrchestrationService.importNic(macAddress, 0, network, true, userVm, requestedIpPair, zone, true);
|
||||
publishVMUsageUpdateResourceCount(userVm, dummyOffering, template);
|
||||
return userVm;
|
||||
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkVolume(Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import org.apache.cloudstack.api.response.TaggedResourceLimitAndCountResponse;
|
|||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
@ -45,6 +46,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
|
@ -275,6 +277,7 @@ public class ResourceLimitManagerImplTest {
|
|||
|
||||
@Test
|
||||
public void testCheckVmResourceLimit() {
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
ServiceOffering serviceOffering = Mockito.mock(ServiceOffering.class);
|
||||
VirtualMachineTemplate template = Mockito.mock(VirtualMachineTemplate.class);
|
||||
Mockito.when(serviceOffering.getHostTag()).thenReturn(hostTags.get(0));
|
||||
|
|
@ -282,54 +285,12 @@ public class ResourceLimitManagerImplTest {
|
|||
Mockito.when(serviceOffering.getRamSize()).thenReturn(256);
|
||||
Mockito.when(template.getTemplateTag()).thenReturn(hostTags.get(0));
|
||||
Account account = Mockito.mock(Account.class);
|
||||
try {
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any());
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
resourceLimitManager.checkVmResourceLimit(account, true, serviceOffering, template);
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
resourceLimitManager.checkVmResourceLimit(account, true, serviceOffering, template, reservations);
|
||||
List<String> tags = new ArrayList<>();
|
||||
tags.add(null);
|
||||
tags.add(hostTags.get(0));
|
||||
for (String tag: tags) {
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.user_vm, tag);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.cpu, tag, 2L);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.memory, tag, 256L);
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail("Exception encountered: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckVmCpuResourceLimit() {
|
||||
ServiceOffering serviceOffering = Mockito.mock(ServiceOffering.class);
|
||||
VirtualMachineTemplate template = Mockito.mock(VirtualMachineTemplate.class);
|
||||
Mockito.when(serviceOffering.getHostTag()).thenReturn(hostTags.get(0));
|
||||
Mockito.when(template.getTemplateTag()).thenReturn(hostTags.get(0));
|
||||
Account account = Mockito.mock(Account.class);
|
||||
long cpu = 2L;
|
||||
try {
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
resourceLimitManager.checkVmCpuResourceLimit(account, true, serviceOffering, template, cpu);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.cpu, null, cpu);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.cpu, hostTags.get(0), cpu);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail("Exception encountered: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckVmMemoryResourceLimit() {
|
||||
ServiceOffering serviceOffering = Mockito.mock(ServiceOffering.class);
|
||||
VirtualMachineTemplate template = Mockito.mock(VirtualMachineTemplate.class);
|
||||
Mockito.when(serviceOffering.getHostTag()).thenReturn(hostTags.get(0));
|
||||
Mockito.when(template.getTemplateTag()).thenReturn(hostTags.get(0));
|
||||
Account account = Mockito.mock(Account.class);
|
||||
long delta = 256L;
|
||||
try {
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
resourceLimitManager.checkVmMemoryResourceLimit(account, true, serviceOffering, template, delta);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.memory, null, delta);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.memory, hostTags.get(0), delta);
|
||||
Assert.assertEquals(4, mockCheckedReservation.constructed().size());
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail("Exception encountered: " + e.getMessage());
|
||||
}
|
||||
|
|
@ -355,22 +316,15 @@ public class ResourceLimitManagerImplTest {
|
|||
|
||||
@Test
|
||||
public void testCheckVolumeResourceLimit() {
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
String checkTag = storageTags.get(0);
|
||||
DiskOffering diskOffering = Mockito.mock(DiskOffering.class);
|
||||
Mockito.when(diskOffering.getTags()).thenReturn(checkTag);
|
||||
Mockito.when(diskOffering.getTagsArray()).thenReturn(new String[]{checkTag});
|
||||
Account account = Mockito.mock(Account.class);
|
||||
try {
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any());
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
resourceLimitManager.checkVolumeResourceLimit(account, true, 100L, diskOffering);
|
||||
List<String> tags = new ArrayList<>();
|
||||
tags.add(null);
|
||||
tags.add(checkTag);
|
||||
for (String tag: tags) {
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.volume, tag);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, tag, 100L);
|
||||
}
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
resourceLimitManager.checkVolumeResourceLimit(account, true, 100L, diskOffering, reservations);
|
||||
Assert.assertEquals(2, reservations.size());
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail("Exception encountered: " + e.getMessage());
|
||||
}
|
||||
|
|
@ -989,13 +943,6 @@ public class ResourceLimitManagerImplTest {
|
|||
Mockito.anyList(), Mockito.eq(tag));
|
||||
}
|
||||
|
||||
private void mockCheckResourceLimitWithTag() throws ResourceAllocationException {
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(
|
||||
Mockito.any(Account.class), Mockito.any(Resource.ResourceType.class), Mockito.anyString());
|
||||
Mockito.doNothing().when(resourceLimitManager).checkResourceLimitWithTag(
|
||||
Mockito.any(Account.class), Mockito.any(Resource.ResourceType.class), Mockito.anyString(), Mockito.anyLong());
|
||||
}
|
||||
|
||||
private void mockIncrementResourceCountWithTag() {
|
||||
Mockito.doNothing().when(resourceLimitManager).incrementResourceCountWithTag(
|
||||
Mockito.anyLong(), Mockito.any(Resource.ResourceType.class), Mockito.anyString());
|
||||
|
|
@ -1012,6 +959,7 @@ public class ResourceLimitManagerImplTest {
|
|||
|
||||
@Test
|
||||
public void testCheckVolumeResourceCount() throws ResourceAllocationException {
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
Account account = Mockito.mock(Account.class);
|
||||
String tag = "tag";
|
||||
long delta = 10L;
|
||||
|
|
@ -1025,12 +973,11 @@ public class ResourceLimitManagerImplTest {
|
|||
|
||||
Mockito.doReturn(List.of(tag)).when(resourceLimitManager)
|
||||
.getResourceLimitStorageTagsForResourceCountOperation(Mockito.anyBoolean(), Mockito.any(DiskOffering.class));
|
||||
mockCheckResourceLimitWithTag();
|
||||
resourceLimitManager.checkVolumeResourceLimit(account, false, delta, Mockito.mock(DiskOffering.class));
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1)).checkResourceLimitWithTag(
|
||||
account, Resource.ResourceType.volume, tag);
|
||||
Mockito.verify(resourceLimitManager, Mockito.times(1))
|
||||
.checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, tag, 10L);
|
||||
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
resourceLimitManager.checkVolumeResourceLimit(account, false, delta, Mockito.mock(DiskOffering.class), reservations);
|
||||
Assert.assertEquals(2, reservations.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import static org.mockito.ArgumentMatchers.eq;
|
|||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
|
@ -44,6 +43,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventUtils;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
|
@ -91,6 +91,7 @@ import org.junit.runner.RunWith;
|
|||
import org.mockito.InOrder;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
|
@ -99,7 +100,6 @@ import org.springframework.test.util.ReflectionTestUtils;
|
|||
|
||||
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
|
|
@ -551,7 +551,9 @@ public class VolumeApiServiceImplTest {
|
|||
@Test
|
||||
public void attachRootVolumePositive() throws NoSuchFieldException, IllegalAccessException {
|
||||
thrown.expect(NullPointerException.class);
|
||||
volumeApiServiceImpl.attachVolumeToVM(2L, 6L, 0L, false);
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
volumeApiServiceImpl.attachVolumeToVM(2L, 6L, 0L, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Negative test - attach data volume, to the vm on non-kvm hypervisor
|
||||
|
|
@ -570,7 +572,9 @@ public class VolumeApiServiceImplTest {
|
|||
DiskOfferingVO diskOffering = Mockito.mock(DiskOfferingVO.class);
|
||||
when(diskOffering.getEncrypt()).thenReturn(true);
|
||||
when(_diskOfferingDao.findById(anyLong())).thenReturn(diskOffering);
|
||||
volumeApiServiceImpl.attachVolumeToVM(4L, 10L, 1L, false);
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
volumeApiServiceImpl.attachVolumeToVM(4L, 10L, 1L, false);
|
||||
}
|
||||
}
|
||||
|
||||
// volume not Ready
|
||||
|
|
@ -655,9 +659,7 @@ public class VolumeApiServiceImplTest {
|
|||
* The resource limit check for primary storage should not be skipped for Volume in 'Uploaded' state.
|
||||
*/
|
||||
@Test
|
||||
public void testResourceLimitCheckForUploadedVolume() throws NoSuchFieldException, IllegalAccessException, ResourceAllocationException {
|
||||
doThrow(new ResourceAllocationException("primary storage resource limit check failed", Resource.ResourceType.primary_storage)).when(resourceLimitServiceMock)
|
||||
.checkResourceLimit(any(AccountVO.class), any(Resource.ResourceType.class), any(Long.class));
|
||||
public void testAttachVolumeToVMPerformsResourceReservation() throws NoSuchFieldException, IllegalAccessException, ResourceAllocationException {
|
||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||
AccountVO acc = Mockito.mock(AccountVO.class);
|
||||
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
||||
|
|
@ -678,10 +680,10 @@ public class VolumeApiServiceImplTest {
|
|||
DataCenterVO zoneWithDisabledLocalStorage = Mockito.mock(DataCenterVO.class);
|
||||
when(_dcDao.findById(anyLong())).thenReturn(zoneWithDisabledLocalStorage);
|
||||
when(zoneWithDisabledLocalStorage.isLocalStorageEnabled()).thenReturn(true);
|
||||
try {
|
||||
doReturn(volumeVoMock).when(volumeApiServiceImpl).getVolumeAttachJobResult(Mockito.any(), Mockito.any(), Mockito.any());
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
volumeApiServiceImpl.attachVolumeToVM(2L, 9L, null, false);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
Assert.assertEquals(e.getMessage(), ("primary storage resource limit check failed"));
|
||||
Assert.assertEquals(1, mockCheckedReservation.constructed().size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2208,6 +2210,36 @@ public class VolumeApiServiceImplTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequiredPrimaryStorageSizeForVolumeAttachTestTagsAreEmptyReturnsZero() {
|
||||
List<String> tags = new ArrayList<>();
|
||||
|
||||
Long result = volumeApiServiceImpl.getRequiredPrimaryStorageSizeForVolumeAttach(tags, volumeInfoMock);
|
||||
|
||||
Assert.assertEquals(0L, (long) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequiredPrimaryStorageSizeForVolumeAttachTestVolumeIsReadyReturnsZero() {
|
||||
List<String> tags = List.of("tag1", "tag2");
|
||||
Mockito.doReturn(Volume.State.Ready).when(volumeInfoMock).getState();
|
||||
|
||||
Long result = volumeApiServiceImpl.getRequiredPrimaryStorageSizeForVolumeAttach(tags, volumeInfoMock);
|
||||
|
||||
Assert.assertEquals(0L, (long) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequiredPrimaryStorageSizeForVolumeAttachTestTagsAreNotEmptyAndVolumeIsUploadedReturnsVolumeSize() {
|
||||
List<String> tags = List.of("tag1", "tag2");
|
||||
Mockito.doReturn(Volume.State.Uploaded).when(volumeInfoMock).getState();
|
||||
Mockito.doReturn(2L).when(volumeInfoMock).getSize();
|
||||
|
||||
Long result = volumeApiServiceImpl.getRequiredPrimaryStorageSizeForVolumeAttach(tags, volumeInfoMock);
|
||||
|
||||
Assert.assertEquals(2L, (long) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateNoVmSnapshotsTestNoInstanceId() {
|
||||
Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.secstorage.dao.SecondaryStorageHeuristicDao;
|
||||
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
|
|
@ -207,6 +208,8 @@ public class TemplateManagerImplTest {
|
|||
VnfTemplateManager vnfTemplateManager;
|
||||
@Inject
|
||||
SnapshotJoinDao snapshotJoinDao;
|
||||
@Inject
|
||||
ReservationDao reservationDao;
|
||||
|
||||
@Inject
|
||||
HeuristicRuleHelper heuristicRuleHelperMock;
|
||||
|
|
@ -959,6 +962,11 @@ public class TemplateManagerImplTest {
|
|||
return Mockito.mock(VnfTemplateManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ReservationDao reservationDao() {
|
||||
return Mockito.mock(ReservationDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SnapshotHelper snapshotHelper() {
|
||||
return Mockito.mock(SnapshotHelper.class);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import java.util.Map;
|
|||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.storage.dao.SnapshotPolicyDao;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
|
|
@ -83,6 +84,7 @@ import org.apache.cloudstack.backup.dao.BackupDao;
|
|||
import org.apache.cloudstack.backup.dao.BackupScheduleDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
|
|
@ -100,6 +102,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
|
@ -690,7 +693,6 @@ public class UserVmManagerImplTest {
|
|||
Mockito.doNothing().when(userVmManagerImpl).validateOldAndNewAccounts(Mockito.nullable(Account.class), Mockito.nullable(Account.class), Mockito.anyLong(), Mockito.nullable(String.class), Mockito.nullable(Long.class));
|
||||
Mockito.doNothing().when(userVmManagerImpl).validateIfVmHasNoRules(Mockito.any(), Mockito.anyLong());
|
||||
Mockito.doNothing().when(userVmManagerImpl).removeInstanceFromInstanceGroup(Mockito.anyLong());
|
||||
Mockito.doNothing().when(userVmManagerImpl).verifyResourceLimitsForAccountAndStorage(Mockito.any(), Mockito.any(), Mockito.any(), anyList(), Mockito.any());
|
||||
Mockito.doNothing().when(userVmManagerImpl).validateIfNewOwnerHasAccessToTemplate(Mockito.any(), Mockito.any(), Mockito.any());
|
||||
|
||||
Mockito.doNothing().when(userVmManagerImpl).updateVmOwner(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
|
|
@ -1696,23 +1698,11 @@ public class UserVmManagerImplTest {
|
|||
Mockito.when(vol5.isDisplay()).thenReturn(true);
|
||||
|
||||
List<VolumeVO> volumes = List.of(vol1, undisplayedVolume, vol3, vol4, vol5);
|
||||
Long size = volumes.stream().filter(VolumeVO::isDisplay).mapToLong(VolumeVO::getSize).sum();
|
||||
try {
|
||||
userVmManagerImpl.checkVolumesLimits(account, volumes);
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimit(account, Resource.ResourceType.volume, 4);
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimit(account, Resource.ResourceType.primary_storage, size);
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimitWithTag(account, Resource.ResourceType.volume, "tag1", 2);
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimitWithTag(account, Resource.ResourceType.volume, "tag2", 3);
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, "tag1",
|
||||
vol1.getSize() + vol5.getSize());
|
||||
Mockito.verify(resourceLimitMgr, times(1))
|
||||
.checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, "tag2",
|
||||
vol1.getSize() + vol3.getSize() + vol5.getSize());
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
|
||||
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
userVmManagerImpl.checkVolumesLimits(account, volumes, reservations);
|
||||
Assert.assertEquals(8, reservations.size());
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
|
@ -2003,26 +1993,26 @@ public class UserVmManagerImplTest {
|
|||
|
||||
@Test
|
||||
public void verifyResourceLimitsForAccountAndStorageTestCountOnlyRunningVmsInResourceLimitationIsTrueDoesNotCallVmResourceLimitCheck() throws ResourceAllocationException {
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
LinkedList<VolumeVO> volumeVoList = new LinkedList<VolumeVO>();
|
||||
Mockito.doReturn(true).when(userVmManagerImpl).countOnlyRunningVmsInResourceLimitation();
|
||||
|
||||
userVmManagerImpl.verifyResourceLimitsForAccountAndStorage(accountMock, userVmVoMock, serviceOfferingVoMock, volumeVoList, virtualMachineTemplateMock);
|
||||
userVmManagerImpl.verifyResourceLimitsForAccountAndStorage(accountMock, userVmVoMock, serviceOfferingVoMock, volumeVoList, virtualMachineTemplateMock, reservations);
|
||||
|
||||
Mockito.verify(resourceLimitMgr, Mockito.never()).checkVmResourceLimit(Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any());
|
||||
Mockito.verify(resourceLimitMgr).checkResourceLimit(accountMock, Resource.ResourceType.volume, 0l);
|
||||
Mockito.verify(resourceLimitMgr).checkResourceLimit(accountMock, Resource.ResourceType.primary_storage, 0l);
|
||||
Mockito.verify(resourceLimitMgr, Mockito.never()).checkVmResourceLimit(Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
Mockito.verify(resourceLimitMgr, Mockito.never()).checkVolumeResourceLimit(Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyResourceLimitsForAccountAndStorageTestCountOnlyRunningVmsInResourceLimitationIsFalseCallsVmResourceLimitCheck() throws ResourceAllocationException {
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
LinkedList<VolumeVO> volumeVoList = new LinkedList<VolumeVO>();
|
||||
Mockito.doReturn(false).when(userVmManagerImpl).countOnlyRunningVmsInResourceLimitation();
|
||||
|
||||
userVmManagerImpl.verifyResourceLimitsForAccountAndStorage(accountMock, userVmVoMock, serviceOfferingVoMock, volumeVoList, virtualMachineTemplateMock);
|
||||
userVmManagerImpl.verifyResourceLimitsForAccountAndStorage(accountMock, userVmVoMock, serviceOfferingVoMock, volumeVoList, virtualMachineTemplateMock, reservations);
|
||||
|
||||
Mockito.verify(resourceLimitMgr).checkVmResourceLimit(Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any());
|
||||
Mockito.verify(resourceLimitMgr).checkResourceLimit(accountMock, Resource.ResourceType.volume, 0l);
|
||||
Mockito.verify(resourceLimitMgr).checkResourceLimit(accountMock, Resource.ResourceType.primary_storage, 0l);
|
||||
Mockito.verify(resourceLimitMgr).checkVmResourceLimit(Mockito.any(), Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
Mockito.verify(userVmManagerImpl).checkVolumesLimits(Mockito.any(), Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -3067,7 +3057,7 @@ public class UserVmManagerImplTest {
|
|||
configureDoNothingForMethodsThatWeDoNotWantToTest();
|
||||
|
||||
doThrow(ResourceAllocationException.class).when(userVmManagerImpl).verifyResourceLimitsForAccountAndStorage(Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any());
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||
|
||||
Assert.assertThrows(ResourceAllocationException.class, () -> userVmManagerImpl.moveVmToUser(assignVmCmdMock));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,13 +352,13 @@ public class VMSnapshotManagerTest {
|
|||
_vmSnapshotMgr.updateUserVmServiceOffering(userVm, vmSnapshotVO);
|
||||
|
||||
verify(_vmSnapshotMgr).changeUserVmServiceOffering(userVm, vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(userVm);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).upgradeUserVmServiceOffering(ArgumentMatchers.eq(userVm), ArgumentMatchers.eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVmMapDetails() {
|
||||
Map<String, String> result = _vmSnapshotMgr.getVmMapDetails(userVm);
|
||||
Map<String, String> result = _vmSnapshotMgr.getVmMapDetails(vmSnapshotVO);
|
||||
assert(result.containsKey(userVmDetailCpuNumber.getName()));
|
||||
assert(result.containsKey(userVmDetailMemory.getName()));
|
||||
assertEquals(userVmDetails.size(), result.size());
|
||||
|
|
@ -370,7 +370,7 @@ public class VMSnapshotManagerTest {
|
|||
public void testChangeUserVmServiceOffering() throws ConcurrentOperationException, ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException {
|
||||
when(_userVmManager.upgradeVirtualMachine(ArgumentMatchers.eq(TEST_VM_ID), ArgumentMatchers.eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture())).thenReturn(true);
|
||||
_vmSnapshotMgr.changeUserVmServiceOffering(userVm, vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(userVm);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).upgradeUserVmServiceOffering(ArgumentMatchers.eq(userVm), ArgumentMatchers.eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture());
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +378,7 @@ public class VMSnapshotManagerTest {
|
|||
public void testChangeUserVmServiceOfferingFailOnUpgradeVMServiceOffering() throws ConcurrentOperationException, ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException {
|
||||
when(_userVmManager.upgradeVirtualMachine(ArgumentMatchers.eq(TEST_VM_ID), ArgumentMatchers.eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture())).thenReturn(false);
|
||||
_vmSnapshotMgr.changeUserVmServiceOffering(userVm, vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(userVm);
|
||||
verify(_vmSnapshotMgr).getVmMapDetails(vmSnapshotVO);
|
||||
verify(_vmSnapshotMgr).upgradeUserVmServiceOffering(ArgumentMatchers.eq(userVm), ArgumentMatchers.eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import javax.naming.ConfigurationException;
|
|||
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
|
|
@ -273,7 +274,7 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException {
|
||||
public void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -284,13 +285,13 @@ 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 {
|
||||
DiskOffering currentOffering, DiskOffering newOffering, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size,
|
||||
DiskOffering diskOffering) {
|
||||
DiskOffering diskOffering, List<Reserver> reservations) {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +335,7 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException {
|
||||
public void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -351,19 +352,14 @@ 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 {
|
||||
VirtualMachineTemplate template, List<Reserver> reservations) 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 {
|
||||
VirtualMachineTemplate newTemplate, List<Reserver> reservations) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -377,11 +373,6 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) {
|
||||
|
||||
|
|
|
|||
|
|
@ -268,9 +268,6 @@ public class VolumeImportUnmanageManagerImplTest {
|
|||
doNothing().when(volumeImportUnmanageManager).checkIfVolumeIsEncrypted(volumeOnStorageTO);
|
||||
doNothing().when(volumeImportUnmanageManager).checkIfVolumeHasBackingFile(volumeOnStorageTO);
|
||||
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.volume);
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.primary_storage, virtualSize);
|
||||
|
||||
DiskOfferingVO diskOffering = mock(DiskOfferingVO.class);
|
||||
when(diskOffering.isCustomized()).thenReturn(true);
|
||||
doReturn(diskOffering).when(volumeImportUnmanageManager).getOrCreateDiskOffering(account, diskOfferingId, zoneId, isLocal);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.vm.ImportVMTaskVO;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
|
|
@ -58,6 +59,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
|
|
@ -71,6 +73,7 @@ import org.junit.runner.RunWith;
|
|||
import org.mockito.BDDMockito;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
|
@ -94,7 +97,6 @@ import com.cloud.agent.api.GetUnmanagedInstancesCommand;
|
|||
import com.cloud.agent.api.ImportConvertedInstanceAnswer;
|
||||
import com.cloud.agent.api.ImportConvertedInstanceCommand;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
|
|
@ -111,7 +113,6 @@ import com.cloud.exception.InsufficientServerCapacityException;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.UnsupportedServiceException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
|
|
@ -241,6 +242,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
private StoragePoolHostDao storagePoolHostDao;
|
||||
@Mock
|
||||
private ImportVmTasksManager importVmTasksManager;
|
||||
@Mock
|
||||
private ReservationDao reservationDao;
|
||||
|
||||
@Mock
|
||||
private VMInstanceVO virtualMachine;
|
||||
|
|
@ -302,7 +305,6 @@ public class UnmanagedVMsManagerImplTest {
|
|||
clusterVO.setHypervisorType(Hypervisor.HypervisorType.VMware.toString());
|
||||
when(clusterDao.findById(anyLong())).thenReturn(clusterVO);
|
||||
when(configurationDao.getValue(Mockito.anyString())).thenReturn(null);
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(any(Account.class), any(Resource.ResourceType.class), anyLong());
|
||||
List<HostVO> hosts = new ArrayList<>();
|
||||
HostVO hostVO = Mockito.mock(HostVO.class);
|
||||
when(hostVO.isInMaintenanceStates()).thenReturn(false);
|
||||
|
|
@ -442,7 +444,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
when(importUnmanageInstanceCmd.getName()).thenReturn("TestInstance");
|
||||
when(importUnmanageInstanceCmd.getDomainId()).thenReturn(null);
|
||||
when(volumeApiService.doesStoragePoolSupportDiskOffering(any(StoragePool.class), any())).thenReturn(true);
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class);
|
||||
MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
unmanagedVMsManager.importUnmanagedInstance(importUnmanageInstanceCmd);
|
||||
}
|
||||
}
|
||||
|
|
@ -609,7 +612,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
CopyRemoteVolumeAnswer copyAnswer = Mockito.mock(CopyRemoteVolumeAnswer.class);
|
||||
when(copyAnswer.getResult()).thenReturn(true);
|
||||
when(agentManager.easySend(anyLong(), any(CopyRemoteVolumeCommand.class))).thenReturn(copyAnswer);
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class);
|
||||
MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
unmanagedVMsManager.importVm(cmd);
|
||||
}
|
||||
}
|
||||
|
|
@ -797,7 +801,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
Mockito.lenient().when(agentManager.send(Mockito.eq(convertHostId), Mockito.any(ImportConvertedInstanceCommand.class))).thenReturn(convertImportedInstanceAnswer);
|
||||
}
|
||||
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class);
|
||||
MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
unmanagedVMsManager.importVm(importVmCmd);
|
||||
verify(vmwareGuru).getHypervisorVMOutOfBandAndCloneIfRequired(Mockito.eq(host), Mockito.eq(vmName), anyMap());
|
||||
verify(vmwareGuru).createVMTemplateOutOfBand(Mockito.eq(host), Mockito.eq(vmName), anyMap(), any(DataStoreTO.class), anyInt());
|
||||
|
|
@ -850,7 +855,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
when(volumeApiService.doesStoragePoolSupportDiskOffering(any(StoragePool.class), any())).thenReturn(true);
|
||||
StoragePoolHostVO storagePoolHost = Mockito.mock(StoragePoolHostVO.class);
|
||||
when(storagePoolHostDao.findByPoolHost(anyLong(), anyLong())).thenReturn(storagePoolHost);
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
|
||||
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class);
|
||||
MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
|
||||
unmanagedVMsManager.importVm(cmd);
|
||||
}
|
||||
}
|
||||
|
|
@ -1198,42 +1204,6 @@ public class UnmanagedVMsManagerImplTest {
|
|||
unmanagedVMsManager.selectKVMHostForConversionInCluster(cluster, hostId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUnmanagedDiskLimits() {
|
||||
Account owner = Mockito.mock(Account.class);
|
||||
UnmanagedInstanceTO.Disk disk = Mockito.mock(UnmanagedInstanceTO.Disk.class);
|
||||
Mockito.when(disk.getDiskId()).thenReturn("disk1");
|
||||
Mockito.when(disk.getCapacity()).thenReturn(100L);
|
||||
ServiceOffering serviceOffering = Mockito.mock(ServiceOffering.class);
|
||||
Mockito.when(serviceOffering.getDiskOfferingId()).thenReturn(1L);
|
||||
UnmanagedInstanceTO.Disk dataDisk = Mockito.mock(UnmanagedInstanceTO.Disk.class);
|
||||
Mockito.when(dataDisk.getDiskId()).thenReturn("disk2");
|
||||
Mockito.when(dataDisk.getCapacity()).thenReturn(1000L);
|
||||
Map<String, Long> dataDiskMap = new HashMap<>();
|
||||
dataDiskMap.put("disk2", 2L);
|
||||
DiskOfferingVO offering1 = Mockito.mock(DiskOfferingVO.class);
|
||||
Mockito.when(diskOfferingDao.findById(1L)).thenReturn(offering1);
|
||||
String tag1 = "tag1";
|
||||
Mockito.when(resourceLimitService.getResourceLimitStorageTags(offering1)).thenReturn(List.of(tag1));
|
||||
DiskOfferingVO offering2 = Mockito.mock(DiskOfferingVO.class);
|
||||
Mockito.when(diskOfferingDao.findById(2L)).thenReturn(offering2);
|
||||
String tag2 = "tag2";
|
||||
Mockito.when(resourceLimitService.getResourceLimitStorageTags(offering2)).thenReturn(List.of(tag2));
|
||||
try {
|
||||
Mockito.doNothing().when(resourceLimitService).checkResourceLimit(any(), any(), any());
|
||||
Mockito.doNothing().when(resourceLimitService).checkResourceLimitWithTag(any(), any(), any(), any());
|
||||
unmanagedVMsManager.checkUnmanagedDiskLimits(owner, disk, serviceOffering, List.of(dataDisk), dataDiskMap);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimit(owner, Resource.ResourceType.volume, 2);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimit(owner, Resource.ResourceType.primary_storage, 1100L);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimitWithTag(owner, Resource.ResourceType.volume, tag1,1);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimitWithTag(owner, Resource.ResourceType.volume, tag2,1);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimitWithTag(owner, Resource.ResourceType.primary_storage, tag1,100L);
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).checkResourceLimitWithTag(owner, Resource.ResourceType.primary_storage, tag2,1000L);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail("Exception encountered: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConversionStoragePoolSecondaryStorageStaging() {
|
||||
unmanagedVMsManager.checkConversionStoragePool(null, false);
|
||||
|
|
|
|||
Loading…
Reference in New Issue