mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.18'
This commit is contained in:
commit
32448e1ac7
@ -164,6 +164,8 @@ public interface VolumeApiService {
|
||||
|
||||
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
|
||||
|
||||
void destroyVolume(long volumeId);
|
||||
|
||||
Volume recoverVolume(long volumeId);
|
||||
|
||||
void validateCustomDiskOfferingSizeRange(Long sizeInGB);
|
||||
|
||||
@ -429,6 +429,14 @@ public interface UserVmService {
|
||||
UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
|
||||
StorageUnavailableException, ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* This API is mostly to trigger VM.CREATE event for deployVirtualMachine with startvm=false, because there is no code in "execute" part of VM creation.
|
||||
* However, it can be used for additional VM customization in the future.
|
||||
* @param vmId - Virtual Machine Id
|
||||
* @return - Virtual Machine
|
||||
*/
|
||||
UserVm finalizeCreateVirtualMachine(long vmId);
|
||||
|
||||
UserVm getUserVm(long vmId);
|
||||
|
||||
VirtualMachine getVm(long vmId);
|
||||
|
||||
@ -769,7 +769,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "starting Vm. Vm Id: " + getEntityUuid();
|
||||
if(getStartVm()) {
|
||||
return "starting Vm. Vm Id: " + getEntityUuid();
|
||||
}
|
||||
return "deploying Vm. Vm Id: " + getEntityUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -781,28 +784,33 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
||||
public void execute() {
|
||||
UserVm result;
|
||||
|
||||
try {
|
||||
CallContext.current().setEventDetails("Vm Id: " + getEntityUuid());
|
||||
result = _userVmService.startVirtualMachine(this);
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
|
||||
} catch (ResourceAllocationException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
|
||||
} catch (ConcurrentOperationException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
} catch (InsufficientCapacityException ex) {
|
||||
StringBuilder message = new StringBuilder(ex.getMessage());
|
||||
if (ex instanceof InsufficientServerCapacityException) {
|
||||
if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
|
||||
message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
|
||||
CallContext.current().setEventDetails("Vm Id: " + getEntityUuid());
|
||||
if (getStartVm()) {
|
||||
try {
|
||||
result = _userVmService.startVirtualMachine(this);
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
|
||||
} catch (ResourceAllocationException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
|
||||
} catch (ConcurrentOperationException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
} catch (InsufficientCapacityException ex) {
|
||||
StringBuilder message = new StringBuilder(ex.getMessage());
|
||||
if (ex instanceof InsufficientServerCapacityException) {
|
||||
if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
|
||||
message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
|
||||
}
|
||||
}
|
||||
s_logger.info(String.format("%s: %s", message.toString(), ex.getLocalizedMessage()));
|
||||
s_logger.debug(message.toString(), ex);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
|
||||
}
|
||||
s_logger.info(ex);
|
||||
s_logger.info(message.toString(), ex);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
|
||||
} else {
|
||||
s_logger.info("VM " + getEntityUuid() + " already created, load UserVm from DB");
|
||||
result = _userVmService.finalizeCreateVirtualMachine(getEntityId());
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
|
||||
@ -500,22 +500,29 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
|
||||
allocateRootVolume(persistedVm, template, rootDiskOfferingInfo, owner, rootDiskSizeFinal);
|
||||
|
||||
if (dataDiskOfferings != null) {
|
||||
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, null);
|
||||
// Create new Volume context and inject event resource type, id and details to generate VOLUME.CREATE event for the ROOT disk.
|
||||
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
|
||||
try {
|
||||
if (dataDiskOfferings != null) {
|
||||
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||
int diskNumber = 1;
|
||||
for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
|
||||
DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
|
||||
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
||||
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
|
||||
persistedVm, dataDiskTemplate, owner, Long.valueOf(diskNumber));
|
||||
diskNumber++;
|
||||
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||
int diskNumber = 1;
|
||||
for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
|
||||
DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
|
||||
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
||||
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
|
||||
persistedVm, dataDiskTemplate, owner, Long.valueOf(diskNumber));
|
||||
diskNumber++;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Remove volumeContext and pop vmContext back
|
||||
CallContext.unregister();
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
||||
@ -819,7 +819,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
vol.getTemplateId());
|
||||
}
|
||||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating ROOT volume", create = true)
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
|
||||
@Override
|
||||
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
|
||||
Long deviceId) {
|
||||
@ -1035,13 +1035,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
private void updateRootDiskVolumeEventDetails(Type type, VirtualMachine vm, List<DiskProfile> diskProfiles) {
|
||||
CallContext callContext = CallContext.current();
|
||||
// Update only for volume type ROOT and API command resource type Volume
|
||||
if (type == Type.ROOT && callContext != null && callContext.getEventResourceType() == ApiCommandResourceType.Volume) {
|
||||
if ((type == Type.ROOT || type == Type.DATADISK) && callContext != null && callContext.getEventResourceType() == ApiCommandResourceType.Volume) {
|
||||
List<Long> volumeIds = diskProfiles.stream().map(DiskProfile::getVolumeId).filter(volumeId -> volumeId != null).collect(Collectors.toList());
|
||||
if (!volumeIds.isEmpty()) {
|
||||
callContext.setEventResourceId(volumeIds.get(0));
|
||||
}
|
||||
String volumeUuids = volumeIds.stream().map(volumeId -> this._uuidMgr.getUuid(Volume.class, volumeId)).collect(Collectors.joining(", "));
|
||||
callContext.setEventDetails("Volume Id: " + volumeUuids + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, vm.getId()));
|
||||
callContext.setEventDetails("Volume Type: " + type + "Volume Id: " + volumeUuids + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, vm.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1245,7 +1245,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
// Destroy volume if not already destroyed
|
||||
boolean volumeAlreadyDestroyed = (vol.getState() == Volume.State.Destroy || vol.getState() == Volume.State.Expunged || vol.getState() == Volume.State.Expunging);
|
||||
if (!volumeAlreadyDestroyed) {
|
||||
volService.destroyVolume(vol.getId());
|
||||
destroyVolumeInContext(vol);
|
||||
} else {
|
||||
s_logger.debug(String.format("Skipping destroy for the volume [%s] as it is in [%s] state.", volumeToString, vol.getState().toString()));
|
||||
}
|
||||
@ -1277,6 +1277,21 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyVolumeInContext(Volume volume) {
|
||||
// Create new context and inject correct event resource type, id and details,
|
||||
// otherwise VOLUME.DESTROY event will be associated with VirtualMachine and contain VM id and other information.
|
||||
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + volume.getUuid() + " Vm Id: " + _uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId()));
|
||||
volumeContext.setEventResourceType(ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventResourceId(volume.getId());
|
||||
try {
|
||||
_volumeApiService.destroyVolume(volume.getId());
|
||||
} finally {
|
||||
// Remove volumeContext and pop vmContext back
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
|
||||
DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
|
||||
@ -2080,7 +2095,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
||||
} else {
|
||||
volService.destroyVolume(volume.getId());
|
||||
destroyVolumeInContext(volume);
|
||||
}
|
||||
// FIXME - All this is boiler plate code and should be done as part of state transition. This shouldn't be part of orchestrator.
|
||||
// publish usage event for the volume
|
||||
|
||||
@ -31,3 +31,8 @@ CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VM
|
||||
CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VMware', '8.0', 'windows2019srvNext_64Guest');
|
||||
CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VMware', '8.0.0.1', 'windows2019srvNext_64Guest');
|
||||
CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'Xenserver', '8.2.0', 'Windows Server 2022 (64-bit)');
|
||||
|
||||
-- Don't enable CPU cap for default system offerings, fixes regression from https://github.com/apache/cloudstack/pull/6420
|
||||
UPDATE `cloud`.`service_offering` so
|
||||
SET so.limit_cpu_use = 0
|
||||
WHERE so.default_use = 1 AND so.vm_type IN ('domainrouter', 'secondarystoragevm', 'consoleproxy', 'internalloadbalancervm', 'elasticloadbalancervm');
|
||||
|
||||
@ -727,6 +727,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||
|
||||
Filter searchFilter = new Filter(EventJoinVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
// additional order by since createdDate does not have milliseconds
|
||||
// and two events, created within one second can be incorrectly ordered (for example VM.CREATE Completed before Scheduled)
|
||||
searchFilter.addOrderBy(EventJoinVO.class, "id", false);
|
||||
|
||||
SearchBuilder<EventJoinVO> sb = _eventJoinDao.createSearchBuilder();
|
||||
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
@ -1317,7 +1321,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
vmIds[i++] = v.getId();
|
||||
}
|
||||
List<UserVmJoinVO> vms = _userVmJoinDao.searchByIds(vmIds);
|
||||
return new Pair<List<UserVmJoinVO>, Integer>(vms, count);
|
||||
return new Pair<>(vms, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1728,6 +1728,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
return volume;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_DESTROY, eventDescription = "destroying a volume")
|
||||
public void destroyVolume(long volumeId) {
|
||||
volService.destroyVolume(volumeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_RECOVER, eventDescription = "recovering a volume in Destroy state")
|
||||
public Volume recoverVolume(long volumeId) {
|
||||
|
||||
@ -24,7 +24,15 @@ import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.api.query.dao.NetworkOfferingJoinDao;
|
||||
import com.cloud.api.query.dao.VpcOfferingJoinDao;
|
||||
import com.cloud.api.query.vo.NetworkOfferingJoinVO;
|
||||
import com.cloud.api.query.vo.VpcOfferingJoinVO;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDetailsDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -106,12 +114,24 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
||||
@Inject
|
||||
private DiskOfferingDetailsDao diskOfferingDetailsDao;
|
||||
@Inject
|
||||
private NetworkOfferingDao networkOfferingDao;
|
||||
@Inject
|
||||
private NetworkOfferingJoinDao networkOfferingJoinDao;
|
||||
@Inject
|
||||
private NetworkOfferingDetailsDao networkOfferingDetailsDao;
|
||||
@Inject
|
||||
private ServiceOfferingJoinDao serviceOfferingJoinDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao serviceOfferingDao;
|
||||
@Inject
|
||||
private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
|
||||
@Inject
|
||||
private VpcOfferingDao vpcOfferingDao;
|
||||
@Inject
|
||||
private VpcOfferingJoinDao vpcOfferingJoinDao;
|
||||
@Inject
|
||||
private VpcOfferingDetailsDao vpcOfferingDetailsDao;
|
||||
@Inject
|
||||
private ProjectDao _projectDao;
|
||||
@Inject
|
||||
private ProjectManager _projectMgr;
|
||||
@ -483,18 +503,48 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
||||
}
|
||||
|
||||
String domainIdString = String.valueOf(domainId);
|
||||
List<Long> diskOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<Long> serviceOfferingsDetailsToRemove = new ArrayList<>();
|
||||
|
||||
// delete the service and disk offerings associated with this domain
|
||||
List<DiskOfferingJoinVO> diskOfferingsForThisDomain = diskOfferingJoinDao.findByDomainId(domainId);
|
||||
for (DiskOfferingJoinVO diskOffering : diskOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(diskOffering.getDomainId())) {
|
||||
diskOfferingDao.remove(diskOffering.getId());
|
||||
removeDiskOfferings(domainId, domainIdString);
|
||||
|
||||
removeServiceOfferings(domainId, domainIdString);
|
||||
|
||||
removeNetworkOfferings(domainId, domainIdString);
|
||||
|
||||
removeVpcOfferings(domainId, domainIdString);
|
||||
}
|
||||
|
||||
private void removeVpcOfferings(Long domainId, String domainIdString) {
|
||||
List<Long> vpcOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<VpcOfferingJoinVO> vpcOfferingsForThisDomain = vpcOfferingJoinDao.findByDomainId(domainId);
|
||||
for (VpcOfferingJoinVO vpcOffering : vpcOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(vpcOffering.getDomainId())) {
|
||||
vpcOfferingDao.remove(vpcOffering.getId());
|
||||
} else {
|
||||
diskOfferingsDetailsToRemove.add(diskOffering.getId());
|
||||
vpcOfferingsDetailsToRemove.add(vpcOffering.getId());
|
||||
}
|
||||
}
|
||||
for (final Long vpcOfferingId : vpcOfferingsDetailsToRemove) {
|
||||
vpcOfferingDetailsDao.removeDetail(vpcOfferingId, ApiConstants.DOMAIN_ID, domainIdString);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNetworkOfferings(Long domainId, String domainIdString) {
|
||||
List<Long> networkOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<NetworkOfferingJoinVO> networkOfferingsForThisDomain = networkOfferingJoinDao.findByDomainId(domainId, false);
|
||||
for (NetworkOfferingJoinVO networkOffering : networkOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(networkOffering.getDomainId())) {
|
||||
networkOfferingDao.remove(networkOffering.getId());
|
||||
} else {
|
||||
networkOfferingsDetailsToRemove.add(networkOffering.getId());
|
||||
}
|
||||
}
|
||||
for (final Long networkOfferingId : networkOfferingsDetailsToRemove) {
|
||||
networkOfferingDetailsDao.removeDetail(networkOfferingId, ApiConstants.DOMAIN_ID, domainIdString);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeServiceOfferings(Long domainId, String domainIdString) {
|
||||
List<Long> serviceOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<ServiceOfferingJoinVO> serviceOfferingsForThisDomain = serviceOfferingJoinDao.findByDomainId(domainId);
|
||||
for (ServiceOfferingJoinVO serviceOffering : serviceOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(serviceOffering.getDomainId())) {
|
||||
@ -503,14 +553,25 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
||||
serviceOfferingsDetailsToRemove.add(serviceOffering.getId());
|
||||
}
|
||||
}
|
||||
for (final Long serviceOfferingId : serviceOfferingsDetailsToRemove) {
|
||||
serviceOfferingDetailsDao.removeDetail(serviceOfferingId, ApiConstants.DOMAIN_ID, domainIdString);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDiskOfferings(Long domainId, String domainIdString) {
|
||||
List<Long> diskOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<DiskOfferingJoinVO> diskOfferingsForThisDomain = diskOfferingJoinDao.findByDomainId(domainId);
|
||||
for (DiskOfferingJoinVO diskOffering : diskOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(diskOffering.getDomainId())) {
|
||||
diskOfferingDao.remove(diskOffering.getId());
|
||||
} else {
|
||||
diskOfferingsDetailsToRemove.add(diskOffering.getId());
|
||||
}
|
||||
}
|
||||
// Remove domain IDs for offerings which may be multi-domain
|
||||
for (final Long diskOfferingId : diskOfferingsDetailsToRemove) {
|
||||
diskOfferingDetailsDao.removeDetail(diskOfferingId, ApiConstants.DOMAIN_ID, domainIdString);
|
||||
}
|
||||
for (final Long serviceOfferingId : serviceOfferingsDetailsToRemove) {
|
||||
serviceOfferingDetailsDao.removeDetail(serviceOfferingId, ApiConstants.DOMAIN_ID, domainIdString);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
|
||||
@ -3274,9 +3274,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
autoScaleManager.removeVmFromVmGroup(vmId);
|
||||
|
||||
vmScheduleManager.removeScheduleByVmId(vmId, expunge);
|
||||
|
||||
deleteVolumesFromVm(volumesToBeDeleted, expunge);
|
||||
deleteVolumesFromVm(vm, volumesToBeDeleted, expunge);
|
||||
|
||||
if (getDestroyRootVolumeOnVmDestruction(vm.getDomainId())) {
|
||||
VolumeVO rootVolume = _volsDao.getInstanceRootVolume(vm.getId());
|
||||
@ -3720,6 +3718,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap, dynamicScalingEnabled, vmType, overrideDiskOfferingId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm")
|
||||
public UserVm finalizeCreateVirtualMachine(long vmId) {
|
||||
s_logger.info("Loading UserVm " + vmId + " from DB");
|
||||
UserVm userVm = getUserVm(vmId);
|
||||
if (userVm == null) {
|
||||
s_logger.info("Loaded UserVm " + vmId + " (" + userVm.getUuid() + ") from DB");
|
||||
} else {
|
||||
s_logger.warn("UserVm " + vmId + " does not exist in DB");
|
||||
}
|
||||
return userVm;
|
||||
}
|
||||
|
||||
private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, Account owner, HypervisorType hypervisor,
|
||||
List<HypervisorType> vpcSupportedHTypes, Long networkId) {
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
@ -7974,7 +7985,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
// Create new context and inject correct event resource type, id and details,
|
||||
// otherwise VOLUME.DETACH event will be associated with VirtualMachine and contain VM id and other information.
|
||||
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId()));
|
||||
volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId()));
|
||||
volumeContext.setEventResourceType(ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventResourceId(volume.getId());
|
||||
|
||||
@ -7992,15 +8003,29 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteVolumesFromVm(List<VolumeVO> volumes, boolean expunge) {
|
||||
private void deleteVolumesFromVm(UserVmVO vm, List<VolumeVO> volumes, boolean expunge) {
|
||||
|
||||
for (VolumeVO volume : volumes) {
|
||||
destroyVolumeInContext(vm, expunge, volume);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyVolumeInContext(UserVmVO vm, boolean expunge, VolumeVO volume) {
|
||||
// Create new context and inject correct event resource type, id and details,
|
||||
// otherwise VOLUME.DESTROY event will be associated with VirtualMachine and contain VM id and other information.
|
||||
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + vm.getUuid());
|
||||
volumeContext.setEventResourceType(ApiCommandResourceType.Volume);
|
||||
volumeContext.setEventResourceId(volume.getId());
|
||||
try {
|
||||
Volume result = _volumeService.destroyVolume(volume.getId(), CallContext.current().getCallingAccount(), expunge, false);
|
||||
|
||||
if (result == null) {
|
||||
s_logger.error("DestroyVM remove volume - failed to delete volume " + volume.getInstanceId() + " from instance " + volume.getId());
|
||||
s_logger.error(String.format("DestroyVM remove volume - failed to delete volume %s from instance %s", volume.getId(), volume.getInstanceId()));
|
||||
}
|
||||
} finally {
|
||||
// Remove volumeContext and pop vmContext back
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.api.query.dao.NetworkOfferingJoinDao;
|
||||
import com.cloud.api.query.dao.VpcOfferingJoinDao;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.utils.UuidUtils;
|
||||
@ -82,7 +84,11 @@ public class DomainManagerImplTest {
|
||||
@Mock
|
||||
DiskOfferingJoinDao _diskOfferingDao;
|
||||
@Mock
|
||||
ServiceOfferingJoinDao _offeringsDao;
|
||||
NetworkOfferingJoinDao networkOfferingJoinDao;
|
||||
@Mock
|
||||
ServiceOfferingJoinDao serviceOfferingJoinDao;
|
||||
@Mock
|
||||
VpcOfferingJoinDao vpcOfferingJoinDao;
|
||||
@Mock
|
||||
ProjectDao _projectDao;
|
||||
@Mock
|
||||
@ -142,6 +148,11 @@ public class DomainManagerImplTest {
|
||||
Mockito.when(_accountDao.findCleanupsForRemovedAccounts(DOMAIN_ID)).thenReturn(domainAccountsForCleanup);
|
||||
Mockito.when(_networkDomainDao.listNetworkIdsByDomain(DOMAIN_ID)).thenReturn(domainNetworkIds);
|
||||
Mockito.when(_dedicatedDao.listByDomainId(DOMAIN_ID)).thenReturn(domainDedicatedResources);
|
||||
|
||||
Mockito.when(_diskOfferingDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
Mockito.when(networkOfferingJoinDao.findByDomainId(Mockito.anyLong(), Mockito.anyBoolean())).thenReturn(Collections.emptyList());
|
||||
Mockito.when(serviceOfferingJoinDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
Mockito.when(vpcOfferingJoinDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -266,8 +277,6 @@ public class DomainManagerImplTest {
|
||||
Mockito.when(_dedicatedDao.listByDomainId(Mockito.anyLong())).thenReturn(new ArrayList<DedicatedResourceVO>());
|
||||
Mockito.when(domainDaoMock.remove(Mockito.anyLong())).thenReturn(true);
|
||||
Mockito.when(_configMgr.releaseDomainSpecificVirtualRanges(Mockito.anyLong())).thenReturn(true);
|
||||
Mockito.when(_diskOfferingDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
Mockito.when(_offeringsDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
|
||||
try {
|
||||
Assert.assertTrue(domainManager.deleteDomain(20l, false));
|
||||
@ -299,8 +308,6 @@ public class DomainManagerImplTest {
|
||||
Mockito.when(_resourceCountDao.removeEntriesByOwner(Mockito.anyLong(), Mockito.eq(ResourceOwnerType.Domain))).thenReturn(1l);
|
||||
Mockito.when(_resourceLimitDao.removeEntriesByOwner(Mockito.anyLong(), Mockito.eq(ResourceOwnerType.Domain))).thenReturn(1l);
|
||||
Mockito.when(_configMgr.releaseDomainSpecificVirtualRanges(Mockito.anyLong())).thenReturn(true);
|
||||
Mockito.when(_diskOfferingDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
Mockito.when(_offeringsDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
|
||||
|
||||
try {
|
||||
Assert.assertTrue(domainManager.deleteDomain(20l, true));
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
# under the License.
|
||||
""" BVT tests for Events Resource
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
@ -184,7 +185,7 @@ class TestEventsResource(cloudstackTestCase):
|
||||
for event in events:
|
||||
if event.type.startswith("VM.") or (event.type.startswith("NETWORK.") and not event.type.startswith("NETWORK.ELEMENT")) or event.type.startswith("VOLUME.") or event.type.startswith("ACCOUNT.") or event.type.startswith("DOMAIN.") or event.type.startswith("TEMPLATE."):
|
||||
if event.resourceid is None or event.resourcetype is None:
|
||||
self.debug("Failed event:: %" % event)
|
||||
self.debug("Failed event:: %s" % json.dumps(event, indent=2))
|
||||
self.fail("resourceid or resourcetype for the event not found!")
|
||||
else:
|
||||
self.debug("Event %s at %s:: Resource Type: %s, Resource ID: %s" % (event.type, event.created, event.resourcetype, event.resourceid))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user