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 2025/09/11 14:30:50 UTC
(cloudstack) branch main updated (b46e29dc677 -> 70a4503ea16)
This is an automated email from the ASF dual-hosted git repository.
weizhou pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
from b46e29dc677 Improvement: SSL offloading with Virtual Router (#11468)
add e3681a04bb8 server: allow migration of vm with snapshots for vmware (#9305)
add 5d32492676a IPv6 firewall: accept packets from related and established connections (#10970)
add e64e94ad3f7 Import KVM VM: Autodetect vlan id from bridge name (#11507)
add 036fd001705 kvm: Fix NPE in case host UEFI detail is not set on agent connection (#11610)
add 7c727a34406 CKS: Fix transition exception when scaling Stopped k8s clusters (#11598)
add 38006b2e03d ssvm: use mgmt network if no storage network (#10735)
new 70a4503ea16 Merge remote-tracking branch 'apache/4.20'
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../main/java/com/cloud/hypervisor/Hypervisor.java | 6 ++-
.../kubernetes/cluster/KubernetesCluster.java | 4 ++
.../com/cloud/agent/manager/AgentManagerImpl.java | 2 +-
.../kvm/resource/LibvirtComputingResource.java | 14 ++++++
...LibvirtGetUnmanagedInstancesCommandWrapper.java | 8 +++-
.../KubernetesClusterScaleWorker.java | 5 +-
.../main/java/com/cloud/vm/UserVmManagerImpl.java | 3 +-
.../resource/NfsSecondaryStorageResource.java | 22 +++++++--
.../resource/NfsSecondaryStorageResourceTest.java | 56 +++++++++++++++++++---
systemvm/debian/opt/cloud/bin/cs/CsNetfilter.py | 2 +
.../views/compute/wizard/MultiNetworkSelection.vue | 16 ++++++-
11 files changed, 119 insertions(+), 19 deletions(-)
(cloudstack) 01/01: Merge remote-tracking branch 'apache/4.20'
Posted by we...@apache.org.
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 70a4503ea16db57dbcd2535a55f90dbad538a52f
Merge: b46e29dc677 38006b2e03d
Author: Wei Zhou <we...@apache.org>
AuthorDate: Thu Sep 11 14:04:52 2025 +0200
Merge remote-tracking branch 'apache/4.20'
.../main/java/com/cloud/hypervisor/Hypervisor.java | 6 ++-
.../kubernetes/cluster/KubernetesCluster.java | 4 ++
.../com/cloud/agent/manager/AgentManagerImpl.java | 2 +-
.../kvm/resource/LibvirtComputingResource.java | 14 ++++++
...LibvirtGetUnmanagedInstancesCommandWrapper.java | 8 +++-
.../KubernetesClusterScaleWorker.java | 5 +-
.../main/java/com/cloud/vm/UserVmManagerImpl.java | 3 +-
.../resource/NfsSecondaryStorageResource.java | 22 +++++++--
.../resource/NfsSecondaryStorageResourceTest.java | 56 +++++++++++++++++++---
systemvm/debian/opt/cloud/bin/cs/CsNetfilter.py | 2 +
.../views/compute/wizard/MultiNetworkSelection.vue | 16 ++++++-
11 files changed, 119 insertions(+), 19 deletions(-)
diff --cc api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
index 8b5551d6a8e,379a0db2ccd..571d993c7a1
--- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
+++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
@@@ -60,9 -58,8 +60,10 @@@ public interface KubernetesCluster exte
Stopping("Resources for the Kubernetes cluster are being destroyed"),
Stopped("All resources for the Kubernetes cluster are destroyed, Kubernetes cluster may still have ephemeral resource like persistent volumes provisioned"),
Scaling("Transient state in which resources are either getting scaled up/down"),
+ ScalingStoppedCluster("Transient state in which the service offerings of stopped clusters are getting scaled"),
Upgrading("Transient state in which cluster is getting upgraded"),
+ Importing("Transient state in which additional nodes are added as worker nodes to a cluster"),
+ RemovingNodes("Transient state in which additional nodes are removed from a cluster"),
Alert("State to represent Kubernetes clusters which are not in expected desired state (operationally in active control place, stopped cluster VM's etc)."),
Recovering("State in which Kubernetes cluster is recovering from alert state"),
Destroyed("End state of Kubernetes cluster in which all resources are destroyed, cluster will not be usable further"),
diff --cc plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java
index 3461d5c0634,f6828e3b203..0938fd44554
--- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java
+++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java
@@@ -355,10 -282,10 +355,11 @@@ public class KubernetesClusterScaleWork
}
}
- private void scaleKubernetesClusterOffering() throws CloudRuntimeException {
+ private void scaleKubernetesClusterOffering(KubernetesClusterNodeType nodeType, ServiceOffering serviceOffering,
+ boolean updateNodeOffering, boolean updateClusterOffering) throws CloudRuntimeException {
validateKubernetesClusterScaleOfferingParameters();
- if (!kubernetesCluster.getState().equals(KubernetesCluster.State.Scaling)) {
+ List<KubernetesCluster.State> scalingStates = List.of(KubernetesCluster.State.Scaling, KubernetesCluster.State.ScalingStoppedCluster);
+ if (!scalingStates.contains(kubernetesCluster.getState())) {
stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.ScaleUpRequested);
}
if (KubernetesCluster.State.Created.equals(originalState)) {
@@@ -532,58 -447,38 +533,60 @@@
}
scaleTimeoutTime = System.currentTimeMillis() + KubernetesClusterService.KubernetesClusterScaleTimeout.value() * 1000;
final long originalClusterSize = kubernetesCluster.getNodeCount();
- final ServiceOffering existingServiceOffering = serviceOfferingDao.findById(kubernetesCluster.getServiceOfferingId());
- if (existingServiceOffering == null) {
- logAndThrow(Level.ERROR, String.format("Scaling Kubernetes cluster %s failed, service offering for the Kubernetes cluster not found!", kubernetesCluster));
+
+ // DEFAULT node type means only the global service offering has been set for the Kubernetes cluster
+ boolean scaleClusterDefaultOffering = serviceOfferingNodeTypeMap.containsKey(DEFAULT.name());
+ if (scaleClusterDefaultOffering) {
+ final ServiceOffering existingServiceOffering = serviceOfferingDao.findById(kubernetesCluster.getServiceOfferingId());
+ final ServiceOffering existingControlOffering = serviceOfferingDao.findById(kubernetesCluster.getControlNodeServiceOfferingId());
+ final ServiceOffering existingWorkerOffering = serviceOfferingDao.findById(kubernetesCluster.getWorkerNodeServiceOfferingId());
+ if (existingServiceOffering == null && ObjectUtils.anyNull(existingControlOffering, existingWorkerOffering)) {
+ logAndThrow(Level.ERROR, String.format("Scaling Kubernetes cluster : %s failed, service offering for the Kubernetes cluster not found!", kubernetesCluster.getName()));
+ }
}
+
final boolean autoscalingChanged = isAutoscalingChanged();
- final boolean serviceOfferingScalingNeeded = serviceOffering != null && serviceOffering.getId() != existingServiceOffering.getId();
+ ServiceOffering defaultServiceOffering = serviceOfferingNodeTypeMap.getOrDefault(DEFAULT.name(), null);
+
+ for (KubernetesClusterNodeType nodeType : Arrays.asList(CONTROL, ETCD, WORKER)) {
+ boolean isWorkerNode = WORKER == nodeType;
+ final long newVMRequired = (!isWorkerNode || clusterSize == null) ? 0 : clusterSize - originalClusterSize;
+ if (!scaleClusterDefaultOffering && !serviceOfferingNodeTypeMap.containsKey(nodeType.name()) && newVMRequired == 0) {
+ continue;
+ }
+
+ ServiceOffering existingServiceOffering = getExistingServiceOfferingForNodeType(nodeType, kubernetesCluster);
+ ServiceOffering scalingServiceOffering = serviceOfferingNodeTypeMap.getOrDefault(nodeType.name(), defaultServiceOffering);
+ boolean isNodeOfferingScalingNeeded = isServiceOfferingScalingNeededForNodeType(existingServiceOffering, scalingServiceOffering);
+ boolean updateNodeOffering = serviceOfferingNodeTypeMap.containsKey(nodeType.name()) || isNodeOfferingScalingNeeded;
- if (autoscalingChanged) {
- boolean autoScaled = autoscaleCluster(this.isAutoscalingEnabled, minSize, maxSize);
- if (autoScaled && serviceOfferingScalingNeeded) {
- scaleKubernetesClusterOffering();
+ boolean updateClusterOffering = isWorkerNode && scaleClusterDefaultOffering;
+ if (isWorkerNode && autoscalingChanged) {
+ boolean autoScaled = autoscaleCluster(this.isAutoscalingEnabled, minSize, maxSize);
+ if (autoScaled && isNodeOfferingScalingNeeded) {
+ scaleKubernetesClusterOffering(nodeType, scalingServiceOffering, updateNodeOffering, updateClusterOffering);
+ }
+ stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.OperationSucceeded);
+ return autoScaled;
}
- stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.OperationSucceeded);
- return autoScaled;
- }
- final boolean clusterSizeScalingNeeded = clusterSize != null && clusterSize != originalClusterSize;
- final long newVMRequired = clusterSize == null ? 0 : clusterSize - originalClusterSize;
- if (serviceOfferingScalingNeeded && clusterSizeScalingNeeded) {
- if (newVMRequired > 0) {
- scaleKubernetesClusterOffering();
- scaleKubernetesClusterSize();
+ final boolean clusterSizeScalingNeeded = isWorkerNode && clusterSize != null && clusterSize != originalClusterSize;
+ if (isNodeOfferingScalingNeeded && clusterSizeScalingNeeded) {
+ if (newVMRequired > 0) {
+ scaleKubernetesClusterOffering(nodeType, scalingServiceOffering, updateNodeOffering, updateClusterOffering);
+ scaleKubernetesClusterSize(nodeType);
+ } else {
+ scaleKubernetesClusterSize(nodeType);
+ scaleKubernetesClusterOffering(nodeType, scalingServiceOffering, updateNodeOffering, updateClusterOffering);
+ }
+ } else if (isNodeOfferingScalingNeeded) {
+ scaleKubernetesClusterOffering(nodeType, scalingServiceOffering, updateNodeOffering, updateClusterOffering);
+ } else if (clusterSizeScalingNeeded) {
+ scaleKubernetesClusterSize(nodeType);
+ } else {
- scaleKubernetesClusterSize();
- scaleKubernetesClusterOffering();
++ return true;
}
- } else if (serviceOfferingScalingNeeded) {
- scaleKubernetesClusterOffering();
- } else if (clusterSizeScalingNeeded) {
- scaleKubernetesClusterSize();
- } else {
- return true;
}
+
stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.OperationSucceeded);
return true;
}
diff --cc services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
index 6d474ddcc92,9f510f25b12..17414c60f20
--- a/services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
+++ b/services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
@@@ -18,10 -18,10 +18,9 @@@
*/
package org.apache.cloudstack.storage.resource;
- import org.apache.logging.log4j.Logger;
import static org.mockito.ArgumentMatchers.any;
- import org.mockito.Mock;
import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.spy;
+ import static org.mockito.Mockito.times;
import java.io.File;
import java.nio.file.Files;