Merge remote-tracking branch 'apache/4.20' into 4.22

This commit is contained in:
Abhishek Kumar 2026-01-07 13:10:41 +05:30
commit 425c4e3312
No known key found for this signature in database
GPG Key ID: 26DF259080DABDC4
11 changed files with 128 additions and 34 deletions

View File

@ -151,7 +151,7 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te
client.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new UsernamePasswordCredentials(user, password);
client.getState().setCredentials(new AuthScope(hostAndPort.first(), hostAndPort.second(), AuthScope.ANY_REALM), defaultcreds);
logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + ":" + hostAndPort.second());
logger.info("Added username={}, password=****** for host {}:{}", user, hostAndPort.first(), hostAndPort.second());
} else {
logger.info("No credentials configured for host=" + hostAndPort.first() + ":" + hostAndPort.second());
}

View File

@ -163,5 +163,7 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
VolumeVO findOneByIScsiName(String iScsiName);
int getVolumeCountByOfferingId(long diskOfferingId);
VolumeVO findByLastIdAndState(long lastVolumeId, Volume.State...states);
}

View File

@ -78,6 +78,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;
@ -506,6 +507,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
@ -914,6 +920,14 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
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);
}
@Override
public VolumeVO findByLastIdAndState(long lastVolumeId, State ...states) {
QueryBuilder<VolumeVO> sc = QueryBuilder.create(VolumeVO.class);

View File

@ -99,7 +99,7 @@ public class DatabaseCreator {
String username = dbProperties.getProperty(String.format("db.%s.username", database));
String password = dbProperties.getProperty(String.format("db.%s.password", database));
String dbName = dbProperties.getProperty(String.format("db.%s.name", database));
System.out.println(String.format("========> Initializing database=%s with host=%s port=%s username=%s password=%s", dbName, host, port, username, password));
System.out.println(String.format("========> Initializing database=%s with host=%s port=%s username=%s password=******", dbName, host, port, username));
List<String> queries = new ArrayList<String>();
queries.add(String.format("drop database if exists `%s`", dbName));

View File

@ -187,5 +187,9 @@ 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);
List<VMInstanceVO> listByIdsIncludingRemoved(List<Long> ids);
}

View File

@ -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;
@ -354,6 +356,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
@ -1247,6 +1261,29 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
.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);
}
@Override
public List<VMInstanceVO> listByIdsIncludingRemoved(List<Long> ids) {
SearchBuilder<VMInstanceVO> idsSearch = createSearchBuilder();

View File

@ -49,10 +49,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.vm.VirtualMachineManager;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup;
@ -154,6 +150,7 @@ import com.cloud.api.query.vo.NetworkOfferingJoinVO;
import com.cloud.capacity.CapacityManager;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.dc.AccountVlanMapVO;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
@ -204,6 +201,7 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.gpu.GPU;
import com.cloud.gpu.VgpuProfileVO;
import com.cloud.gpu.dao.VgpuProfileDao;
@ -247,6 +245,7 @@ import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.network.element.NetrisProviderVO;
import com.cloud.network.element.NsxProviderVO;
import com.cloud.network.netris.NetrisService;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.network.vpc.VpcManager;
import com.cloud.offering.DiskOffering;
@ -281,6 +280,7 @@ import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.StoragePoolTagsDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.test.IPRangeConfig;
import com.cloud.user.Account;
import com.cloud.user.AccountDetailVO;
@ -314,6 +314,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.NicIpAlias;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.NicIpAliasDao;
import com.cloud.vm.dao.NicIpAliasVO;
@ -3901,6 +3902,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);

View File

@ -134,7 +134,8 @@ public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru {
VirtualMachine vm = vmProfile.getVirtualMachine();
HostVO host = hostDao.findById(vm.getHostId());
if (host == null) {
throw new CloudRuntimeException("Host with id: " + vm.getHostId() + " not found");
logger.warn("Host is not available. Skipping setting CPU quota percentage for VM: {}", vm);
return;
}
logger.debug("Limiting CPU usage for VM: {} on host: {}", vm, host);
double hostMaxSpeed = getHostCPUSpeed(host);

View File

@ -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());

View File

@ -32,7 +32,6 @@ import com.cloud.storage.GuestOSVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.GuestOSHypervisorDao;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.api.ApiConstants;
@ -141,10 +140,11 @@ public class KVMGuruTest {
Mockito.verify(vmTO).setCpuQuotaPercentage(Mockito.anyDouble());
}
@Test(expected = CloudRuntimeException.class)
@Test
public void testSetVmQuotaPercentageNullHost() {
Mockito.when(hostDao.findById(hostId)).thenReturn(null);
guru.setVmQuotaPercentage(vmTO, vmProfile);
Mockito.verify(vmTO, Mockito.never()).setCpuQuotaPercentage(Mockito.anyDouble());
}
@Test

View File

@ -788,11 +788,8 @@ public class VirtualMachineMO extends BaseMO {
cloneSpec.setMemory(false);
cloneSpec.setConfig(vmConfigSpec);
ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
boolean result = cloneVM(cloneName, morFolder, cloneSpec);
if (result) {
_context.waitForTaskProgressDone(morTask);
VirtualMachineMO clonedVm = dcMo.findVm(cloneName);
if (clonedVm == null) {
logger.error(String.format("Failed to clone Instance %s", cloneName));
@ -802,10 +799,9 @@ public class VirtualMachineMO extends BaseMO {
clonedVm.tagAsWorkerVM();
makeSureVMHasOnlyRequiredDisk(clonedVm, requiredDisk, dsMo, dcMo);
return clonedVm;
} else {
logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
return null;
}
return null;
}
private void makeSureVMHasOnlyRequiredDisk(VirtualMachineMO clonedVm, VirtualDisk requiredDisk, DatastoreMO dsMo, DatacenterMO dcMo) throws Exception {
@ -852,16 +848,42 @@ public class VirtualMachineMO extends BaseMO {
setDiskProvisioningType(relocSpec, morDs, diskProvisioningType);
ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
return cloneVM(cloneName, morFolder, cloneSpec);
}
private boolean cloneVMTask(String cloneName, ManagedObjectReference morFolder, VirtualMachineCloneSpec cloneSpec) throws Exception {
ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
if (result) {
_context.waitForTaskProgressDone(morTask);
return true;
} else {
logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
}
logger.error("VMware cloneVM_Task failed due to {}", TaskMO.getTaskFailureInfo(_context, morTask));
return false;
}
private boolean cloneVM(final String cloneName, final ManagedObjectReference morFolder, final VirtualMachineCloneSpec cloneSpec) throws Exception {
final int retry = 20;
int retryAttempt = 0;
while (++retryAttempt <= retry) {
try {
logger.debug("Cloning VM {}, attempt #{}", cloneName, retryAttempt);
return cloneVMTask(cloneName, morFolder, cloneSpec);
} catch (Exception e) {
logger.info("Got exception while cloning VM {}", cloneName, e);
if (e.getMessage() != null && e.getMessage().contains("Unable to access file")) {
logger.debug("Failed to clone VM {}. Retrying", cloneName);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
logger.debug("Waiting to clone VM {} been interrupted: ", cloneName);
}
} else {
throw e;
}
}
}
return false;
}
@ -925,17 +947,7 @@ public class VirtualMachineMO extends BaseMO {
cloneSpec.setLocation(rSpec);
cloneSpec.setSnapshot(morBaseSnapshot);
ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
boolean result = _context.getVimClient().waitForTask(morTask);
if (result) {
_context.waitForTaskProgressDone(morTask);
return true;
} else {
logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
}
return false;
return cloneVM(cloneName, morFolder, cloneSpec);
}
public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception {