Merge pull request #25 from shapeblue/netris-420-backport

Update netris-release to the 4.20.0.0 release
This commit is contained in:
Nicolas Vazquez 2024-12-03 15:50:04 +01:00 committed by GitHub
commit d24b6f229d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
231 changed files with 1531 additions and 447 deletions

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<dependencies>
<dependency>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<dependencies>
<dependency>

View File

@ -116,6 +116,8 @@ public interface AccountService {
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource);
Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
/**

View File

@ -82,7 +82,7 @@ public class ListBackupScheduleCmd extends BaseCmd {
List<BackupSchedule> schedules = backupManager.listBackupSchedule(getVmId());
ListResponse<BackupScheduleResponse> response = new ListResponse<>();
List<BackupScheduleResponse> scheduleResponses = new ArrayList<>();
if (CollectionUtils.isNullOrEmpty(schedules)) {
if (!CollectionUtils.isNullOrEmpty(schedules)) {
for (BackupSchedule schedule : schedules) {
scheduleResponses.add(_responseGenerator.createBackupScheduleResponse(schedule));
}

View File

@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<dependencies>
<dependency>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<dependencies>
<dependency>

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
cloudstack (4.20.0.0) unstable; urgency=low
* Update the version to 4.20.0.0
-- the Apache CloudStack project <dev@cloudstack.apache.org> Tue, 19 Nov 2024 08:54:07 -0300
cloudstack (4.20.0.0-SNAPSHOT) unstable; urgency=low
* Update the version to 4.20.0.0-SNAPSHOT

2
debian/control vendored
View File

@ -24,7 +24,7 @@ Description: CloudStack server library
Package: cloudstack-agent
Architecture: all
Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, rsync, lsb-release, ufw, apparmor, cpu-checker
Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, rsync, lsb-release, ufw, apparmor, cpu-checker, libvirt-daemon-driver-storage-rbd
Recommends: init-system-helpers
Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
Description: CloudStack agent

View File

@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<dependencies>
<dependency>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<build>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -126,14 +126,7 @@ public class VolumeStatsDaoImpl extends GenericDaoBase<VolumeStatsVO, Long> impl
logger.debug(String.format("Starting to remove all volume_stats rows older than [%s].", limitDate));
long totalRemoved = 0;
long removed;
do {
removed = expunge(sc, limitPerQuery);
totalRemoved += removed;
logger.trace(String.format("Removed [%s] volume_stats rows on the last update and a sum of [%s] volume_stats rows older than [%s] until now.", removed, totalRemoved, limitDate));
} while (limitPerQuery > 0 && removed >= limitPerQuery);
long totalRemoved = batchExpunge(sc, limitPerQuery);
logger.info(String.format("Removed a total of [%s] volume_stats rows older than [%s].", totalRemoved, limitDate));
}

View File

@ -123,14 +123,7 @@ public class VmStatsDaoImpl extends GenericDaoBase<VmStatsVO, Long> implements V
logger.debug(String.format("Starting to remove all vm_stats rows older than [%s].", limitDate));
long totalRemoved = 0;
long removed;
do {
removed = expunge(sc, limitPerQuery);
totalRemoved += removed;
logger.trace(String.format("Removed [%s] vm_stats rows on the last update and a sum of [%s] vm_stats rows older than [%s] until now.", removed, totalRemoved, limitDate));
} while (limitPerQuery > 0 && removed >= limitPerQuery);
long totalRemoved = batchExpunge(sc, limitPerQuery);
logger.info(String.format("Removed a total of [%s] vm_stats rows older than [%s].", totalRemoved, limitDate));
}

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<artifactId>cloud-engine-service</artifactId>
<packaging>war</packaging>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -1958,25 +1958,26 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
* - Full clones (no backing file): Take snapshot of the VM prior disk creation
* Return this information
*/
protected void setVolumeMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
VirtualMachineTO vmTO, Host srcHost, StoragePoolVO destStoragePool) {
if (!destStoragePool.isManaged()) {
String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo);
String srcPoolUuid = srcVolumeInfo.getDataStore().getUuid();
StoragePoolVO srcPool = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
Storage.StoragePoolType srcPoolType = srcPool.getPoolType();
MigrationOptions migrationOptions;
if (StringUtils.isNotBlank(srcVolumeBackingFile)) {
migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo,
srcVolumeBackingFile, srcPoolUuid, srcPoolType);
} else {
migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPoolUuid, srcPoolType);
}
migrationOptions.setTimeout(StorageManager.KvmStorageOnlineMigrationWait.value());
destVolumeInfo.setMigrationOptions(migrationOptions);
protected void setVolumeMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, VirtualMachineTO vmTO, Host srcHost, StoragePoolVO destStoragePool,
MigrationOptions.Type migrationType) {
if (destStoragePool.isManaged()) {
return;
}
String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo);
String srcPoolUuid = srcVolumeInfo.getDataStore().getUuid();
StoragePoolVO srcPool = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
Storage.StoragePoolType srcPoolType = srcPool.getPoolType();
MigrationOptions migrationOptions;
if (MigrationOptions.Type.LinkedClone.equals(migrationType)) {
migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo, srcVolumeBackingFile, srcPoolUuid, srcPoolType);
} else {
migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPoolUuid, srcPoolType);
}
migrationOptions.setTimeout(StorageManager.KvmStorageOnlineMigrationWait.value());
destVolumeInfo.setMigrationOptions(migrationOptions);
}
/**
@ -2007,6 +2008,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo = new HashMap<>();
boolean managedStorageDestination = false;
boolean migrateNonSharedInc = false;
for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) {
VolumeInfo srcVolumeInfo = entry.getKey();
DataStore destDataStore = entry.getValue();
@ -2024,15 +2026,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
continue;
}
VMTemplateVO vmTemplate = _vmTemplateDao.findById(vmInstance.getTemplateId());
if (srcVolumeInfo.getTemplateId() != null &&
Objects.nonNull(vmTemplate) &&
!Arrays.asList(KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME, VM_IMPORT_DEFAULT_TEMPLATE_NAME).contains(vmTemplate.getName())) {
logger.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId()));
copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost);
} else {
logger.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a template.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId()));
}
MigrationOptions.Type migrationType = decideMigrationTypeAndCopyTemplateIfNeeded(destHost, vmInstance, srcVolumeInfo, sourceStoragePool, destStoragePool, destDataStore);
migrateNonSharedInc = migrateNonSharedInc || MigrationOptions.Type.LinkedClone.equals(migrationType);
VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool);
VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
@ -2044,7 +2039,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
// move the volume from Ready to Migrating
destVolumeInfo.processEvent(Event.MigrationRequested);
setVolumeMigrationOptions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost, destStoragePool);
setVolumeMigrationOptions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost, destStoragePool, migrationType);
// create a volume on the destination storage
destDataStore.getDriver().createAsync(destDataStore, destVolumeInfo, null);
@ -2059,7 +2054,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
_volumeDao.update(destVolume.getId(), destVolume);
postVolumeCreationActions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost);
postVolumeCreationActions(srcVolumeInfo, destVolumeInfo);
destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
@ -2083,8 +2078,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
migrateDiskInfo = configureMigrateDiskInfo(srcVolumeInfo, destPath, backingPath);
migrateDiskInfo.setSourceDiskOnStorageFileSystem(isStoragePoolTypeOfFile(sourceStoragePool));
migrateDiskInfoList.add(migrateDiskInfo);
prepareDiskWithSecretConsumerDetail(vmTO, srcVolumeInfo, destVolumeInfo.getPath());
}
prepareDiskWithSecretConsumerDetail(vmTO, srcVolumeInfo, destVolumeInfo.getPath());
migrateStorage.put(srcVolumeInfo.getPath(), migrateDiskInfo);
@ -2110,8 +2105,6 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
VMInstanceVO vm = _vmDao.findById(vmTO.getId());
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
boolean migrateNonSharedInc = isSourceAndDestinationPoolTypeOfNfs(volumeDataStoreMap);
MigrateCommand migrateCommand = new MigrateCommand(vmTO.getName(), destHost.getPrivateIpAddress(), isWindows, vmTO, true);
migrateCommand.setWait(StorageManager.KvmStorageOnlineMigrationWait.value());
migrateCommand.setMigrateStorage(migrateStorage);
@ -2161,6 +2154,22 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
}
}
private MigrationOptions.Type decideMigrationTypeAndCopyTemplateIfNeeded(Host destHost, VMInstanceVO vmInstance, VolumeInfo srcVolumeInfo, StoragePoolVO sourceStoragePool, StoragePoolVO destStoragePool, DataStore destDataStore) {
VMTemplateVO vmTemplate = _vmTemplateDao.findById(vmInstance.getTemplateId());
String srcVolumeBackingFile = getVolumeBackingFile(srcVolumeInfo);
if (StringUtils.isNotBlank(srcVolumeBackingFile) && supportStoragePoolType(destStoragePool.getPoolType(), StoragePoolType.Filesystem) &&
srcVolumeInfo.getTemplateId() != null &&
Objects.nonNull(vmTemplate) &&
!Arrays.asList(KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME, VM_IMPORT_DEFAULT_TEMPLATE_NAME).contains(vmTemplate.getName())) {
logger.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId()));
copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost);
return MigrationOptions.Type.LinkedClone;
}
logger.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a " +
"template or we are doing full clone migration.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId()));
return MigrationOptions.Type.FullClone;
}
protected String formatMigrationElementsAsJsonToDisplayOnLog(String objectName, Object object, Object from, Object to){
return String.format("{%s: \"%s\", from: \"%s\", to:\"%s\"}", objectName, object, from, to);
}
@ -2422,7 +2431,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
/**
* Handle post destination volume creation actions depending on the migrating volume type: full clone or linked clone
*/
protected void postVolumeCreationActions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, VirtualMachineTO vmTO, Host srcHost) {
protected void postVolumeCreationActions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) {
MigrationOptions migrationOptions = destVolumeInfo.getMigrationOptions();
if (migrationOptions != null) {
if (migrationOptions.getType() == MigrationOptions.Type.LinkedClone && migrationOptions.isCopySrcTemplate()) {
@ -2470,7 +2479,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
throw new CloudRuntimeException("Destination storage pool with ID " + dataStore.getId() + " was not located.");
}
if (srcStoragePoolVO.isManaged() && srcStoragePoolVO.getId() != destStoragePoolVO.getId()) {
boolean isSrcAndDestPoolPowerFlexStorage = srcStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex) && destStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex);
if (srcStoragePoolVO.isManaged() && !isSrcAndDestPoolPowerFlexStorage && srcStoragePoolVO.getId() != destStoragePoolVO.getId()) {
throw new CloudRuntimeException("Migrating a volume online with KVM from managed storage is not currently supported.");
}

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -533,6 +533,11 @@ public class TemplateServiceImpl implements TemplateService {
logger.info("Skip downloading template " + tmplt.getUniqueName() + " since no url is specified.");
continue;
}
// if this is private template, skip sync to a new image store
if (isSkipTemplateStoreDownload(tmplt, zoneId)) {
logger.info("Skip sync downloading private template " + tmplt.getUniqueName() + " to a new image store");
continue;
}
// if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which
// means that this is a duplicate entry from migration of previous NFS to staging.

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>cloud-engine</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<artifactId>cloudstack-framework</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -247,14 +247,6 @@ public interface GenericDao<T, ID extends Serializable> {
int expungeList(List<ID> ids);
/**
* Delete the entity beans specified by the search criteria with a given limit
* @param sc Search criteria
* @param limit Maximum number of rows that will be affected
* @return Number of rows deleted
*/
int expunge(SearchCriteria<T> sc, long limit);
/**
* expunge the removed rows.
*/

View File

@ -1244,13 +1244,6 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
}
// FIXME: Does not work for joins.
@Override
public int expunge(final SearchCriteria<T> sc, long limit) {
Filter filter = new Filter(limit);
return expunge(sc, filter);
}
@Override
public int expunge(final SearchCriteria<T> sc, final Filter filter) {
if (sc == null) {
@ -1400,22 +1393,39 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
onClause.append("?");
joinAttrList.add(join.getFirstAttributes()[i]);
} else {
onClause.append(joinedTableNames.getOrDefault(join.getFirstAttributes()[i].table, join.getFirstAttributes()[i].table))
.append(".")
.append(join.getFirstAttributes()[i].columnName);
}
onClause.append("=");
if (join.getSecondAttribute()[i].getValue() != null) {
onClause.append("?");
joinAttrList.add(join.getSecondAttribute()[i]);
} else {
if(!joinTableAlias.equals(joinTableName)) {
onClause.append(joinTableAlias);
if ((join.getFirstAttributes()[i].table == null && join.getFirstAttributes()[i].value == null) ||
(join.getSecondAttribute()[i].table == null && join.getSecondAttribute()[i].value == null)) {
onClause.append(joinedTableNames.getOrDefault(join.getSecondAttribute()[i].table, join.getFirstAttributes()[i].table))
.append(".");
if (join.getFirstAttributes()[i].table == null && join.getFirstAttributes()[i].value == null) {
onClause.append(join.getSecondAttribute()[i].columnName);
} else {
onClause.append(join.getFirstAttributes()[i].columnName);
}
} else {
onClause.append(joinTableName);
onClause.append(joinedTableNames.getOrDefault(join.getFirstAttributes()[i].table, join.getFirstAttributes()[i].table))
.append(".")
.append(join.getFirstAttributes()[i].columnName);
}
}
if ((join.getFirstAttributes()[i].table == null && join.getFirstAttributes()[i].value == null) ||
(join.getSecondAttribute()[i].table == null && join.getSecondAttribute()[i].value == null)) {
onClause.append(" IS NULL");
} else {
onClause.append("=");
if (join.getSecondAttribute()[i].getValue() != null) {
onClause.append("?");
joinAttrList.add(join.getSecondAttribute()[i]);
} else {
if (!joinTableAlias.equals(joinTableName)) {
onClause.append(joinTableAlias);
} else {
onClause.append(joinTableName);
}
onClause.append(".")
.append(join.getSecondAttribute()[i].columnName);
}
onClause.append(".")
.append(join.getSecondAttribute()[i].columnName);
}
}
onClause.append(" ");

View File

@ -32,7 +32,7 @@
<parent>
<artifactId>cloudstack-framework</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
</parent>
<build>
<plugins>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>cloud-framework-rest</artifactId>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-framework</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -102,6 +102,7 @@ Requires: java-17-openjdk
Requires: tzdata-java
Requires: %{name}-common = %{_ver}
Requires: libvirt
Requires: libvirt-daemon-driver-storage-rbd
Requires: ebtables
Requires: iptables
Requires: ethtool

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -32,7 +32,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<build>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -25,7 +25,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -25,7 +25,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>cloudstack-plugins</artifactId>
<groupId>org.apache.cloudstack</groupId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -21,6 +21,9 @@ import java.util.List;
import javax.inject.Inject;
import com.cloud.user.Account;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
@ -40,6 +43,7 @@ public class QuotaBalanceCmd extends BaseCmd {
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Account Id for which statement needs to be generated")
private String accountName;
@ACL
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "If domain Id is given and the caller is domain admin then the statement is generated for domain.")
private Long domainId;
@ -51,6 +55,7 @@ public class QuotaBalanceCmd extends BaseCmd {
ApiConstants.PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS)
private Date startDate;
@ACL
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")
private Long accountId;
@ -104,7 +109,14 @@ public class QuotaBalanceCmd extends BaseCmd {
@Override
public long getEntityOwnerId() {
return _accountService.getActiveAccountByName(accountName, domainId).getAccountId();
if (accountId != null) {
return accountId;
}
Account account = _accountService.getActiveAccountByName(accountName, domainId);
if (account != null) {
return account.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM;
}
@Override

View File

@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command;
import com.cloud.user.Account;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -46,6 +47,7 @@ public class QuotaCreditsCmd extends BaseCmd {
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Account Id for which quota credits need to be added")
private String accountName;
@ACL
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Domain for which quota credits need to be added")
private Long domainId;
@ -130,6 +132,10 @@ public class QuotaCreditsCmd extends BaseCmd {
@Override
public long getEntityOwnerId() {
Account account = _accountService.getActiveAccountByName(accountName, domainId);
if (account != null) {
return account.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM;
}

View File

@ -21,6 +21,7 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
@ -42,6 +43,7 @@ public class QuotaStatementCmd extends BaseCmd {
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Optional, Account Id for which statement needs to be generated")
private String accountName;
@ACL
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
private Long domainId;
@ -56,6 +58,7 @@ public class QuotaStatementCmd extends BaseCmd {
@Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "List quota usage records for the specified usage type")
private Integer usageType;
@ACL
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")
private Long accountId;
@ -112,6 +115,9 @@ public class QuotaStatementCmd extends BaseCmd {
@Override
public long getEntityOwnerId() {
if (accountId != null) {
return accountId;
}
Account activeAccountByName = _accountService.getActiveAccountByName(accountName, domainId);
if (activeAccountByName != null) {
return activeAccountByName.getAccountId();

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -27,7 +27,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
</project>

View File

@ -27,7 +27,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>cloud-plugin-hypervisor-baremetal</artifactId>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
<version>4.20.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>

View File

@ -381,6 +381,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected static final String DEFAULT_TUNGSTEN_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.VRouterVifDriver";
private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING = 6003000;
private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING = 5000000;
private final static long HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED = 7000000;
protected HypervisorType hypervisorType;
protected String hypervisorURI;
@ -3050,7 +3051,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
} else if (volume.getType() != Volume.Type.ISO) {
final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
physicalDisk = storagePoolManager.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
physicalDisk = getStoragePoolMgr().getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
pool = physicalDisk.getPool();
}
@ -3152,6 +3153,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
else {
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
}
if (pool.getType() == StoragePoolType.Linstor && isQemuDiscardBugFree(diskBusType)) {
disk.setDiscard(DiscardType.UNMAP);
}
} else {
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
@ -3296,6 +3300,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return isUbuntuHost() || isIoUringSupportedByQemu();
}
/**
* Qemu has a bug with discard enabled on IDE bus devices if qemu version < 7.0.
* <a href="https://bugzilla.redhat.com/show_bug.cgi?id=2029980">redhat bug entry</a>
* @param diskBus used for the disk
* @return true if it is safe to enable discard, otherwise false.
*/
public boolean isQemuDiscardBugFree(DiskDef.DiskBus diskBus) {
return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED;
}
public boolean isUbuntuHost() {
Map<String, String> versionString = getVersionStrings();
String hostKey = "Host.OS";
@ -3498,6 +3512,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
} else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
if (attachingPool.getType() == StoragePoolType.Linstor) {
diskdef.setDiscard(DiscardType.UNMAP);
}
}
if (bytesReadRate != null && bytesReadRate > 0) {
diskdef.setBytesReadRate(bytesReadRate);

View File

@ -24,7 +24,7 @@ import org.apache.commons.collections.CollectionUtils;
public class LibvirtStoragePoolDef {
public enum PoolType {
ISCSI("iscsi"), NETFS("netfs"), loggerICAL("logical"), DIR("dir"), RBD("rbd"), GLUSTERFS("glusterfs"), POWERFLEX("powerflex");
ISCSI("iscsi"), NETFS("netfs"), LOGICAL("logical"), DIR("dir"), RBD("rbd"), GLUSTERFS("glusterfs"), POWERFLEX("powerflex");
String _poolType;
PoolType(String poolType) {

View File

@ -123,8 +123,10 @@ public class MigrateKVMAsync implements Callable<Domain> {
if (migrateNonSharedInc) {
flags |= VIR_MIGRATE_PERSIST_DEST;
flags |= VIR_MIGRATE_NON_SHARED_INC;
logger.debug("Setting VIR_MIGRATE_NON_SHARED_INC for linked clone migration.");
} else {
flags |= VIR_MIGRATE_NON_SHARED_DISK;
logger.debug("Setting VIR_MIGRATE_NON_SHARED_DISK for full clone migration.");
}
}

View File

@ -89,7 +89,7 @@ public final class LibvirtOvsFetchInterfaceCommandWrapper extends CommandWrapper
@Override
public Answer execute(final OvsFetchInterfaceCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String label = "'" + command.getLabel() + "'";
final String label = command.getLabel();
logger.debug("Will look for network with name-label:" + label);
try {

View File

@ -43,7 +43,7 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor {
private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>();
@Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details) {
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details, boolean isPrimaryStorage) {
IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this);
MapStorageUuidToStoragePool.put(uuid, storagePool);

View File

@ -389,7 +389,7 @@ public class KVMStoragePoolManager {
//Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced.
private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean primaryStorage) {
StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details);
KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details, primaryStorage);
// LibvirtStorageAdaptor-specific statement
if (pool.isPoolSupportHA() && primaryStorage) {

View File

@ -26,9 +26,11 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
@ -63,15 +65,19 @@ import org.apache.cloudstack.storage.command.ResignatureCommand;
import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
import org.apache.cloudstack.storage.command.SyncVolumePathCommand;
import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.cryptsetup.KeyFile;
import org.apache.cloudstack.utils.qemu.QemuImageOptions;
import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.cloudstack.utils.qemu.QemuObject;
import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.BooleanUtils;
@ -80,6 +86,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo;
@ -134,10 +141,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import com.cloud.utils.storage.S3.S3Utils;
import com.cloud.vm.VmDetailConstants;
import org.apache.cloudstack.utils.cryptsetup.KeyFile;
import org.apache.cloudstack.utils.qemu.QemuImageOptions;
import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat;
import java.util.ArrayList;
public class KVMStorageProcessor implements StorageProcessor {
protected Logger logger = LogManager.getLogger(getClass());
@ -1447,6 +1451,9 @@ public class KVMStorageProcessor implements StorageProcessor {
diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
} else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
if (attachingPool.getType() == StoragePoolType.Linstor && resource.isQemuDiscardBugFree(busT)) {
diskdef.setDiscard(DiscardType.UNMAP);
}
}
if (encryptDetails != null) {
@ -2449,6 +2456,22 @@ public class KVMStorageProcessor implements StorageProcessor {
template = storagePoolMgr.createPhysicalDiskFromDirectDownloadTemplate(tempFilePath, destTemplatePath, destPool, cmd.getFormat(), cmd.getWaitInMillSeconds());
String templatePath = template.getPath();
if (templatePath != null) {
try {
Qcow2Inspector.validateQcow2File(templatePath);
} catch (RuntimeException e) {
try {
Files.deleteIfExists(Path.of(templatePath));
} catch (IOException ioException) {
logger.warn("Unable to remove file [{}]; consider removing it manually.", templatePath, ioException);
}
logger.error("The downloaded file [{}] is not a valid QCOW2.", templatePath, e);
return new DirectDownloadAnswer(false, "The downloaded file is not a valid QCOW2. Ask the administrator to check the logs for more details.", true);
}
}
if (!storagePoolMgr.disconnectPhysicalDisk(pool.getPoolType(), pool.getUuid(), destTemplatePath)) {
logger.warn("Unable to disconnect physical disk at path: " + destTemplatePath + ", in storage pool id: " + pool.getUuid());
}

View File

@ -73,6 +73,7 @@ import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@ -81,6 +82,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
private StorageLayer _storageLayer;
private String _mountPoint = "/mnt";
private String _manageSnapshotPath;
private static final ConcurrentHashMap<String, Integer> storagePoolRefCounts = new ConcurrentHashMap<>();
private String rbdTemplateSnapName = "cloudstack-base-snap";
private static final int RBD_FEATURE_LAYERING = 1;
@ -350,7 +352,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
String volgroupName = path;
volgroupName = volgroupName.replaceFirst("/", "");
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.loggerICAL, volgroupName, uuid, host, volgroupPath, volgroupPath);
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.LOGICAL, volgroupName, uuid, host, volgroupPath, volgroupPath);
StoragePool sp = null;
try {
logger.debug(spd.toString());
@ -542,7 +544,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
type = StoragePoolType.Filesystem;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.RBD) {
type = StoragePoolType.RBD;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.loggerICAL) {
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.LOGICAL) {
type = StoragePoolType.CLVM;
} else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.GLUSTERFS) {
type = StoragePoolType.Gluster;
@ -644,8 +646,44 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
}
/**
* adjust refcount
*/
private int adjustStoragePoolRefCount(String uuid, int adjustment) {
final String mutexKey = storagePoolRefCounts.keySet().stream()
.filter(k -> k.equals(uuid))
.findFirst()
.orElse(uuid);
synchronized (mutexKey) {
// some access on the storagePoolRefCounts.key(mutexKey) element
int refCount = storagePoolRefCounts.computeIfAbsent(mutexKey, k -> 0);
refCount += adjustment;
if (refCount < 1) {
storagePoolRefCounts.remove(mutexKey);
} else {
storagePoolRefCounts.put(mutexKey, refCount);
}
return refCount;
}
}
/**
* Thread-safe increment storage pool usage refcount
* @param uuid UUID of the storage pool to increment the count
*/
private void incStoragePoolRefCount(String uuid) {
adjustStoragePoolRefCount(uuid, 1);
}
/**
* Thread-safe decrement storage pool usage refcount for the given uuid and return if storage pool still in use.
* @param uuid UUID of the storage pool to decrement the count
* @return true if the storage pool is still used, else false.
*/
private boolean decStoragePoolRefCount(String uuid) {
return adjustStoragePoolRefCount(uuid, -1) > 0;
}
@Override
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details) {
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt");
StoragePool sp = null;
@ -751,6 +789,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
try {
if (!isPrimaryStorage) {
// only ref count storage pools for secondary storage, as primary storage is assumed
// to be always mounted, as long the primary storage isn't fully deleted.
incStoragePoolRefCount(name);
}
if (sp.isActive() == 0) {
logger.debug("Attempting to activate pool " + name);
sp.create(0);
@ -762,6 +806,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
return getStoragePool(name);
} catch (LibvirtException e) {
decStoragePoolRefCount(name);
String error = e.toString();
if (error.contains("Storage source conflict")) {
throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " +
@ -812,6 +857,13 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
@Override
public boolean deleteStoragePool(String uuid) {
logger.info("Attempting to remove storage pool " + uuid + " from libvirt");
// decrement and check if storage pool still in use
if (decStoragePoolRefCount(uuid)) {
logger.info(String.format("deleteStoragePool: Storage pool %s still in use", uuid));
return true;
}
Connect conn = null;
try {
conn = LibvirtConnection.getConnection();

View File

@ -56,7 +56,7 @@ public class ManagedNfsStorageAdaptor implements StorageAdaptor {
}
@Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details) {
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details, boolean isPrimaryStorage) {
LibvirtStoragePool storagePool = new LibvirtStoragePool(uuid, path, StoragePoolType.ManagedNFS, this, null);
storagePool.setSourceHost(host);

View File

@ -169,7 +169,7 @@ public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
}
@Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details) {
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
LOGGER.info(String.format("createStoragePool(uuid,host,port,path,type) called with args (%s, %s, %s, %s, %s)", uuid, host, ""+port, path, type));
MultipathSCSIPool storagePool = new MultipathSCSIPool(uuid, host, port, path, type, details, this);
MapStorageUuidToStoragePool.put(uuid, storagePool);

View File

@ -146,7 +146,7 @@ public class ScaleIOStorageAdaptor implements StorageAdaptor {
}
@Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details) {
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
ScaleIOStoragePool storagePool = new ScaleIOStoragePool(uuid, host, port, path, type, details, this);
MapStorageUuidToStoragePool.put(uuid, storagePool);
return storagePool;

View File

@ -40,7 +40,7 @@ public interface StorageAdaptor {
// it with info from local disk, and return it
public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool);
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details);
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage);
public boolean deleteStoragePool(String uuid);

Some files were not shown because too many files have changed in this diff Show More