mirror of https://github.com/apache/cloudstack.git
Skip removal of offerings if in use during domain removal (#11780)
This PR fixes #11502 - Prevent service offering update to specific domains if any instance for the offering are outside of those - Removal of offerings is skipped if it is in use by any Instance.
This commit is contained in:
parent
a29de0ed06
commit
57331aca2f
|
|
@ -162,4 +162,6 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
List<VolumeVO> searchRemovedByVms(List<Long> vmIds, Long batchSize);
|
||||
|
||||
VolumeVO findOneByIScsiName(String iScsiName);
|
||||
|
||||
int getVolumeCountByOfferingId(long diskOfferingId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch2;
|
||||
protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
|
||||
private final SearchBuilder<VolumeVO> poolAndPathSearch;
|
||||
final GenericSearchBuilder<VolumeVO, Integer> CountByOfferingId;
|
||||
|
||||
@Inject
|
||||
ReservationDao reservationDao;
|
||||
|
|
@ -504,6 +505,11 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
poolAndPathSearch.and("poolId", poolAndPathSearch.entity().getPoolId(), Op.EQ);
|
||||
poolAndPathSearch.and("path", poolAndPathSearch.entity().getPath(), Op.EQ);
|
||||
poolAndPathSearch.done();
|
||||
|
||||
CountByOfferingId = createSearchBuilder(Integer.class);
|
||||
CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId());
|
||||
CountByOfferingId.and("diskOfferingId", CountByOfferingId.entity().getDiskOfferingId(), Op.EQ);
|
||||
CountByOfferingId.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -909,4 +915,12 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
sc.setParameters("iScsiName", iScsiName);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVolumeCountByOfferingId(long diskOfferingId) {
|
||||
SearchCriteria<Integer> sc = CountByOfferingId.create();
|
||||
sc.setParameters("diskOfferingId", diskOfferingId);
|
||||
List<Integer> results = customSearch(sc, null);
|
||||
return results.get(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,4 +187,7 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
|||
|
||||
Map<String, Long> getNameIdMapForVmIds(Collection<Long> ids);
|
||||
|
||||
int getVmCountByOfferingId(Long serviceOfferingId);
|
||||
|
||||
int getVmCountByOfferingNotInDomain(Long serviceOfferingId, List<Long> domainIds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
protected SearchBuilder<VMInstanceVO> LastHostAndStatesSearch;
|
||||
protected SearchBuilder<VMInstanceVO> VmsNotInClusterUsingPool;
|
||||
protected SearchBuilder<VMInstanceVO> IdsPowerStateSelectSearch;
|
||||
GenericSearchBuilder<VMInstanceVO, Integer> CountByOfferingId;
|
||||
GenericSearchBuilder<VMInstanceVO, Integer> CountUserVmNotInDomain;
|
||||
|
||||
@Inject
|
||||
ResourceTagDao tagsDao;
|
||||
|
|
@ -344,6 +346,18 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
IdsPowerStateSelectSearch.entity().getPowerStateUpdateCount(),
|
||||
IdsPowerStateSelectSearch.entity().getPowerStateUpdateTime());
|
||||
IdsPowerStateSelectSearch.done();
|
||||
|
||||
CountByOfferingId = createSearchBuilder(Integer.class);
|
||||
CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId());
|
||||
CountByOfferingId.and("serviceOfferingId", CountByOfferingId.entity().getServiceOfferingId(), Op.EQ);
|
||||
CountByOfferingId.done();
|
||||
|
||||
CountUserVmNotInDomain = createSearchBuilder(Integer.class);
|
||||
CountUserVmNotInDomain.select(null, Func.COUNT, CountUserVmNotInDomain.entity().getId());
|
||||
CountUserVmNotInDomain.and("serviceOfferingId", CountUserVmNotInDomain.entity().getServiceOfferingId(), Op.EQ);
|
||||
CountUserVmNotInDomain.and("domainIdsNotIn", CountUserVmNotInDomain.entity().getDomainId(), Op.NIN);
|
||||
CountUserVmNotInDomain.done();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1224,4 +1238,27 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
return vms.stream()
|
||||
.collect(Collectors.toMap(VMInstanceVO::getInstanceName, VMInstanceVO::getId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVmCountByOfferingId(Long serviceOfferingId) {
|
||||
if (serviceOfferingId == null) {
|
||||
return 0;
|
||||
}
|
||||
SearchCriteria<Integer> sc = CountByOfferingId.create();
|
||||
sc.setParameters("serviceOfferingId", serviceOfferingId);
|
||||
List<Integer> count = customSearch(sc, null);
|
||||
return count.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVmCountByOfferingNotInDomain(Long serviceOfferingId, List<Long> domainIds) {
|
||||
if (serviceOfferingId == null || CollectionUtils.isEmpty(domainIds)) {
|
||||
return 0;
|
||||
}
|
||||
SearchCriteria<Integer> sc = CountUserVmNotInDomain.create();
|
||||
sc.setParameters("serviceOfferingId", serviceOfferingId);
|
||||
sc.setParameters("domainIdsNotIn", domainIds.toArray());
|
||||
List<Integer> count = customSearch(sc, null);
|
||||
return count.get(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ import java.util.stream.Collectors;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
|
||||
import com.cloud.exception.UnsupportedServiceException;
|
||||
import com.cloud.network.as.AutoScaleManager;
|
||||
import com.cloud.user.AccountManagerImpl;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
|
|
@ -3722,6 +3722,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
|
||||
Collections.sort(filteredDomainIds);
|
||||
|
||||
// avoid domain update of service offering if any instance is associated to it
|
||||
int instanceCount = _vmInstanceDao.getVmCountByOfferingNotInDomain(offeringHandle.getId(), filteredDomainIds);
|
||||
if (instanceCount > 0) {
|
||||
throw new UnsupportedServiceException("There are Instances associated to this service offering outside of the specified domains.");
|
||||
}
|
||||
|
||||
List<Long> filteredZoneIds = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(zoneIds)) {
|
||||
filteredZoneIds.addAll(zoneIds);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import com.cloud.api.query.vo.NetworkOfferingJoinVO;
|
|||
import com.cloud.api.query.vo.VpcOfferingJoinVO;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDetailsDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
|
|
@ -85,6 +87,7 @@ import com.cloud.projects.dao.ProjectDao;
|
|||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
|
@ -101,6 +104,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.ReservationContextImpl;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Component
|
||||
|
|
@ -141,6 +146,14 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||
@Inject
|
||||
private ProjectDao _projectDao;
|
||||
@Inject
|
||||
private VMInstanceDao vmInstanceDao;
|
||||
@Inject
|
||||
private NetworkDao networkDao;
|
||||
@Inject
|
||||
private VolumeDao volumeDao;
|
||||
@Inject
|
||||
private VpcDao vpcDao;
|
||||
@Inject
|
||||
private ProjectManager _projectMgr;
|
||||
@Inject
|
||||
private RegionManager _regionMgr;
|
||||
|
|
@ -543,7 +556,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||
List<Long> vpcOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<VpcOfferingJoinVO> vpcOfferingsForThisDomain = vpcOfferingJoinDao.findByDomainId(domainId);
|
||||
for (VpcOfferingJoinVO vpcOffering : vpcOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(vpcOffering.getDomainId())) {
|
||||
int vpcCount = vpcDao.getVpcCountByOfferingId(vpcOffering.getId());
|
||||
if (vpcCount == 0) {
|
||||
vpcOfferingDao.remove(vpcOffering.getId());
|
||||
} else {
|
||||
vpcOfferingsDetailsToRemove.add(vpcOffering.getId());
|
||||
|
|
@ -558,7 +572,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||
List<Long> networkOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<NetworkOfferingJoinVO> networkOfferingsForThisDomain = networkOfferingJoinDao.findByDomainId(domainId, false);
|
||||
for (NetworkOfferingJoinVO networkOffering : networkOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(networkOffering.getDomainId())) {
|
||||
int networkCount = networkDao.getNetworkCountByNetworkOffId(networkOffering.getId());
|
||||
if (networkCount == 0) {
|
||||
networkOfferingDao.remove(networkOffering.getId());
|
||||
} else {
|
||||
networkOfferingsDetailsToRemove.add(networkOffering.getId());
|
||||
|
|
@ -573,7 +588,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||
List<Long> serviceOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<ServiceOfferingJoinVO> serviceOfferingsForThisDomain = serviceOfferingJoinDao.findByDomainId(domainId);
|
||||
for (ServiceOfferingJoinVO serviceOffering : serviceOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(serviceOffering.getDomainId())) {
|
||||
int vmCount = vmInstanceDao.getVmCountByOfferingId(serviceOffering.getId());
|
||||
if (vmCount == 0) {
|
||||
serviceOfferingDao.remove(serviceOffering.getId());
|
||||
} else {
|
||||
serviceOfferingsDetailsToRemove.add(serviceOffering.getId());
|
||||
|
|
@ -588,7 +604,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||
List<Long> diskOfferingsDetailsToRemove = new ArrayList<>();
|
||||
List<DiskOfferingJoinVO> diskOfferingsForThisDomain = diskOfferingJoinDao.findByDomainId(domainId);
|
||||
for (DiskOfferingJoinVO diskOffering : diskOfferingsForThisDomain) {
|
||||
if (domainIdString.equals(diskOffering.getDomainId())) {
|
||||
int volumeCount = volumeDao.getVolumeCountByOfferingId(diskOffering.getId());
|
||||
if (volumeCount == 0) {
|
||||
diskOfferingDao.remove(diskOffering.getId());
|
||||
} else {
|
||||
diskOfferingsDetailsToRemove.add(diskOffering.getId());
|
||||
|
|
|
|||
Loading…
Reference in New Issue