You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by we...@apache.org on 2024/02/13 09:40:33 UTC
(cloudstack) 01/02: Merge remote-tracking branch 'apache/4.19'
This is an automated email from the ASF dual-hosted git repository.
weizhou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 93406f5582bbccfa39b7b2cbe7d38aaef98195da
Merge: 3291a62fc12 bda49ab08ff
Author: Wei Zhou <we...@apache.org>
AuthorDate: Tue Feb 13 10:38:21 2024 +0100
Merge remote-tracking branch 'apache/4.19'
api/src/main/java/com/cloud/storage/Storage.java | 20 ++-
.../cloudstack/cluster/ClusterDrsAlgorithm.java | 192 +++++++++++++++------
.../cloudstack/cluster/ClusterDrsService.java | 23 +++
.../test/java/com/cloud/storage/StorageTest.java | 4 +-
.../cluster/ClusterDrsAlgorithmTest.java | 97 +++++++++++
debian/cloudstack-management.install | 1 +
debian/rules | 4 +
packaging/centos7/cloud.spec | 4 +
packaging/centos8/cloud.spec | 4 +
.../org/apache/cloudstack/cluster/Balanced.java | 76 ++++----
.../apache/cloudstack/cluster/BalancedTest.java | 53 ++----
.../org/apache/cloudstack/cluster/Condensed.java | 79 ++++-----
.../apache/cloudstack/cluster/CondensedTest.java | 46 ++---
.../hypervisor/kvm/resource/LibvirtVMDef.java | 4 +-
.../cloudstack/metrics/MetricsServiceImpl.java | 23 ++-
.../response/ClusterMetricsResponse.java | 12 ++
.../kvm/storage/LinstorStorageAdaptor.java | 73 +-------
.../hypervisor/kvm/storage/LinstorStoragePool.java | 132 +++++++++++++-
.../driver/LinstorPrimaryDataStoreDriverImpl.java | 2 +-
.../datastore/provider/LinstorHostListener.java | 32 ++++
.../LinstorPrimaryDatastoreProviderImpl.java | 2 +-
.../storage/datastore/util/LinstorUtil.java | 27 +--
.../configuration/ConfigurationManagerImpl.java | 1 +
.../VpcVirtualNetworkApplianceManagerImpl.java | 19 +-
.../cloudstack/backup/BackupManagerImpl.java | 4 -
.../cloudstack/cluster/ClusterDrsServiceImpl.java | 28 +--
.../cluster/ClusterDrsServiceImplTest.java | 6 +-
systemvm/debian/opt/cloud/bin/cs/CsAddress.py | 7 +-
systemvm/debian/opt/cloud/bin/cs/CsDatabag.py | 6 +
ui/public/locales/en.json | 8 +-
ui/src/components/view/ListView.vue | 3 +
ui/src/components/view/SearchView.vue | 51 +++---
ui/src/config/section/infra/clusters.js | 4 +-
ui/src/views/infra/ClusterDRSTab.vue | 18 +-
ui/src/views/infra/zone/ZoneWizardLaunchZone.vue | 3 +
.../zone/ZoneWizardPhysicalNetworkSetupStep.vue | 70 ++++++--
36 files changed, 753 insertions(+), 385 deletions(-)
diff --cc api/src/main/java/com/cloud/storage/Storage.java
index 2ef424adcb0,1163fcc892f..c997f5e1dbf
--- a/api/src/main/java/com/cloud/storage/Storage.java
+++ b/api/src/main/java/com/cloud/storage/Storage.java
@@@ -139,72 -135,37 +139,72 @@@ public class Storage
ISODISK /* Template corresponding to a iso (non root disk) present in an OVA */
}
- public static enum StoragePoolType {
- Filesystem(false, true, true), // local directory
- NetworkFilesystem(true, true, true), // NFS
- IscsiLUN(true, false, false), // shared LUN, with a clusterfs overlay
- Iscsi(true, false, false), // for e.g., ZFS Comstar
- ISO(false, false, false), // for iso image
- LVM(false, false, false), // XenServer local LVM SR
- CLVM(true, false, false),
- RBD(true, true, false), // http://libvirt.org/storage.html#StorageBackendRBD
- SharedMountPoint(true, true, true),
- VMFS(true, true, false), // VMware VMFS storage
- PreSetup(true, true, false), // for XenServer, Storage Pool is set up by customers.
- EXT(false, true, false), // XenServer local EXT SR
- OCFS2(true, false, false),
- SMB(true, false, false),
- Gluster(true, false, false),
- PowerFlex(true, true, true), // Dell EMC PowerFlex/ScaleIO (formerly VxFlexOS)
- ManagedNFS(true, false, false),
- Linstor(true, true, false),
- DatastoreCluster(true, true, false), // for VMware, to abstract pool of clusters
- StorPool(true, true, true),
- FiberChannel(true, true, false); // Fiber Channel Pool for KVM hypervisors is used to find the volume by WWN value (/dev/disk/by-id/wwn-<wwnvalue>)
-
+ /**
+ * StoragePoolTypes carry some details about the format and capabilities of a storage pool. While not necessarily a
+ * 1:1 with PrimaryDataStoreDriver (and for KVM agent, KVMStoragePool and StorageAdaptor) implementations, it is
+ * often used to decide which storage plugin or storage command to call, so it may be necessary for new storage
+ * plugins to add a StoragePoolType. This can be done by adding it below, or by creating a new public static final
+ * instance of StoragePoolType in the plugin itself, which registers it with the map.
+ *
+ * Note that if the StoragePoolType is for KVM and defined in plugin code rather than below, care must be taken to
+ * ensure this is available on the agent side as well. This is best done by defining the StoragePoolType in a common
+ * package available on both management server and agent plugin jars.
+ */
+ public static class StoragePoolType {
+ private static final Map<String, StoragePoolType> map = new LinkedHashMap<>();
+
+ public static final StoragePoolType Filesystem = new StoragePoolType("Filesystem", false, true, true);
+ public static final StoragePoolType NetworkFilesystem = new StoragePoolType("NetworkFilesystem", true, true, true);
+ public static final StoragePoolType IscsiLUN = new StoragePoolType("IscsiLUN", true, false, false);
+ public static final StoragePoolType Iscsi = new StoragePoolType("Iscsi", true, false, false);
+ public static final StoragePoolType ISO = new StoragePoolType("ISO", false, false, false);
+ public static final StoragePoolType LVM = new StoragePoolType("LVM", false, false, false);
+ public static final StoragePoolType CLVM = new StoragePoolType("CLVM", true, false, false);
+ public static final StoragePoolType RBD = new StoragePoolType("RBD", true, true, false);
- public static final StoragePoolType SharedMountPoint = new StoragePoolType("SharedMountPoint", true, false, true);
++ public static final StoragePoolType SharedMountPoint = new StoragePoolType("SharedMountPoint", true, true, true);
+ public static final StoragePoolType VMFS = new StoragePoolType("VMFS", true, true, false);
+ public static final StoragePoolType PreSetup = new StoragePoolType("PreSetup", true, true, false);
+ public static final StoragePoolType EXT = new StoragePoolType("EXT", false, true, false);
+ public static final StoragePoolType OCFS2 = new StoragePoolType("OCFS2", true, false, false);
+ public static final StoragePoolType SMB = new StoragePoolType("SMB", true, false, false);
+ public static final StoragePoolType Gluster = new StoragePoolType("Gluster", true, false, false);
+ public static final StoragePoolType PowerFlex = new StoragePoolType("PowerFlex", true, true, true);
+ public static final StoragePoolType ManagedNFS = new StoragePoolType("ManagedNFS", true, false, false);
+ public static final StoragePoolType Linstor = new StoragePoolType("Linstor", true, true, false);
+ public static final StoragePoolType DatastoreCluster = new StoragePoolType("DatastoreCluster", true, true, false);
+ public static final StoragePoolType StorPool = new StoragePoolType("StorPool", true,true,true);
+ public static final StoragePoolType FiberChannel = new StoragePoolType("FiberChannel", true,true,false);
+
+
+ private final String name;
private final boolean shared;
- private final boolean overprovisioning;
+ private final boolean overProvisioning;
private final boolean encryption;
- StoragePoolType(boolean shared, boolean overProvisioning, boolean encryption) {
+ /**
+ * New StoragePoolType, set the name to check with it in Dao (Note: Do not register it into the map of pool types).
+ * @param name name of the StoragePoolType.
+ */
+ public StoragePoolType(String name) {
+ this.name = name;
+ this.shared = false;
- this.overprovisioning = false;
++ this.overProvisioning = false;
+ this.encryption = false;
+ }
+
+ /**
+ * Define a new StoragePoolType, and register it into the map of pool types known to the management server.
+ * @param name Simple unique name of the StoragePoolType.
+ * @param shared Storage pool is shared/accessible to multiple hypervisors
- * @param overprovisioning Storage pool supports overprovisioning
++ * @param overProvisioning Storage pool supports overProvisioning
+ * @param encryption Storage pool supports encrypted volumes
+ */
- public StoragePoolType(String name, boolean shared, boolean overprovisioning, boolean encryption) {
++ public StoragePoolType(String name, boolean shared, boolean overProvisioning, boolean encryption) {
+ this.name = name;
this.shared = shared;
- this.overprovisioning = overprovisioning;
+ this.overProvisioning = overProvisioning;
this.encryption = encryption;
+ addStoragePoolType(this);
}
public boolean isShared() {
@@@ -212,52 -173,12 +212,54 @@@
}
public boolean supportsOverProvisioning() {
- return overprovisioning;
+ return overProvisioning;
}
- public boolean supportsEncryption() { return encryption; }
+ public boolean supportsEncryption() {
+ return encryption;
+ }
+
+ private static void addStoragePoolType(StoragePoolType storagePoolType) {
+ map.putIfAbsent(storagePoolType.name, storagePoolType);
+ }
+
+ public static StoragePoolType[] values() {
+ return map.values().toArray(StoragePoolType[]::new).clone();
+ }
+
+ public static StoragePoolType valueOf(String name) {
+ if (StringUtils.isBlank(name)) {
+ return null;
+ }
+
+ StoragePoolType storage = map.get(name);
+ if (storage == null) {
+ throw new IllegalArgumentException("StoragePoolType '" + name + "' not found");
+ }
+ return storage;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ StoragePoolType that = (StoragePoolType) o;
+ return Objects.equals(name, that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
}
public static List<StoragePoolType> getNonSharedStoragePoolTypes() {
diff --cc plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
index de231f3b594,101e8d3597e..f3a70b079be
--- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
+++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
@@@ -32,12 -30,9 +30,10 @@@ import org.apache.cloudstack.storage.da
import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile;
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
import org.libvirt.LibvirtException;
- import com.cloud.storage.Storage;
- import com.cloud.utils.exception.CloudRuntimeException;
import com.linbit.linstor.api.ApiClient;
import com.linbit.linstor.api.ApiException;
import com.linbit.linstor.api.Configuration;
@@@ -75,35 -65,13 +70,13 @@@ public class LinstorStorageAdaptor impl
return LinstorUtil.RSC_PREFIX + name;
}
- private String getHostname() {
- // either there is already some function for that in the agent or a better way.
- ProcessBuilder pb = new ProcessBuilder("/usr/bin/hostname");
- try
- {
- String result;
- Process p = pb.start();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- StringJoiner sj = new StringJoiner(System.getProperty("line.separator"));
- reader.lines().iterator().forEachRemaining(sj::add);
- result = sj.toString();
-
- p.waitFor();
- p.destroy();
- return result.trim();
- } catch (IOException | InterruptedException exc) {
- Thread.currentThread().interrupt();
- throw new CloudRuntimeException("Unable to run '/usr/bin/hostname' command.");
- }
- }
-
private void logLinstorAnswer(@Nonnull ApiCallRc answer) {
if (answer.isError()) {
- s_logger.error(answer.getMessage());
+ logger.error(answer.getMessage());
} else if (answer.isWarning()) {
- s_logger.warn(answer.getMessage());
+ logger.warn(answer.getMessage());
} else if (answer.isInfo()) {
- s_logger.info(answer.getMessage());
+ logger.info(answer.getMessage());
}
}
diff --cc plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
index c0c55a9ceae,e953c94db22..a8635b404b3
--- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
+++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
@@@ -146,13 -144,13 +145,13 @@@ public class LinstorUtil
null,
null);
- if (rscGrps.isEmpty()) {
- final String errMsg = String.format("Linstor: Resource group '%s' not found", rscGroupName);
- LOGGER.error(errMsg);
- throw new CloudRuntimeException(errMsg);
- }
+ if (rscGrps.isEmpty()) {
+ final String errMsg = String.format("Linstor: Resource group '%s' not found", rscGroupName);
- s_logger.error(errMsg);
++ LOGGER.error(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
- List<StoragePool> storagePools = linstorApi.viewStoragePools(
+ return api.viewStoragePools(
Collections.emptyList(),
rscGrps.get(0).getSelectFilter().getStoragePoolList(),
null,
diff --cc server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index 048dc356ff5,aebeb5c9398..a46c2fd81ea
--- a/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@@ -27,6 -27,8 +27,7 @@@ import java.util.Map
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+ import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Answer;