From a4b1a27c7d2d93a1da698a7115900b3205c1077e Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Mon, 19 Jan 2026 13:20:07 +0530 Subject: [PATCH 1/9] ui: fix 404 on login after forgot password (#12448) Signed-off-by: Abhishek Kumar --- ui/src/views/auth/ForgotPassword.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/auth/ForgotPassword.vue b/ui/src/views/auth/ForgotPassword.vue index 87f2d1d0c33..1e817e01a6e 100644 --- a/ui/src/views/auth/ForgotPassword.vue +++ b/ui/src/views/auth/ForgotPassword.vue @@ -162,7 +162,7 @@ export default { api('forgotPassword', {}, 'POST', loginParams) .finally(() => { this.$message.success(this.$t('message.forgot.password.success')) - this.$router.push({ path: '/login' }).catch(() => {}) + this.$router.replace({ path: '/user/login' }) }) }).catch(error => { this.formRef.value.scrollToField(error.errorFields[0].name) From 42f1e19362ab9030117dc3808dbf3854b6a9f92d Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 19 Jan 2026 18:50:18 +0530 Subject: [PATCH 2/9] Mask vncPasswd being logged in agent.log (#12404) --- .../wrapper/LibvirtMigrateCommandWrapper.java | 24 ++++++++++------- .../wrapper/LibvirtStartCommandWrapper.java | 5 ++-- .../LibvirtMigrateCommandWrapperTest.java | 26 ++++++++++++++++++- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java index 32f2a4b122c..1f14402c85e 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java @@ -158,7 +158,7 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper dpdkPortsMapping = command.getDpdkInterfaceMapping(); if (MapUtils.isNotEmpty(dpdkPortsMapping)) { if (logger.isTraceEnabled()) { - logger.trace(String.format("Changing VM [%s] DPDK interfaces during migration to host: [%s].", vmName, target)); + logger.trace("Changing VM {} DPDK interfaces during migration to host: {}.", vmName, target); } xmlDesc = replaceDpdkInterfaces(xmlDesc, dpdkPortsMapping); if (logger.isDebugEnabled()) { - logger.debug(String.format("Changed VM [%s] XML configuration of DPDK interfaces. New XML configuration is [%s].", vmName, xmlDesc)); + logger.debug("Changed VM {} XML configuration of DPDK interfaces. New XML configuration is {}.", vmName, maskSensitiveInfoInXML(xmlDesc)); } } @@ -233,7 +233,7 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper]*type=['\"]vnc['\"][^>]*passwd=['\"])([^'\"]*)(['\"])", + "$1*****$3"); + } } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java index a174c9a6f14..6e978715755 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java @@ -80,8 +80,9 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper"; + String expected2 = ""; + assertEquals(expected2, LibvirtMigrateCommandWrapper.maskSensitiveInfoInXML(xml2)); + + // Test case 3: Non-VNC graphics (should remain unchanged) + String xml3 = ""; + assertEquals(xml3, LibvirtMigrateCommandWrapper.maskSensitiveInfoInXML(xml3)); + + // Test case 4: Multiple VNC entries in one string + String xml4 = "\n" + + ""; + String expected4 = "\n" + + ""; + assertEquals(expected4, LibvirtMigrateCommandWrapper.maskSensitiveInfoInXML(xml4)); + } } From 2a6ce0c8a810e908139f06d6e12d365801af4422 Mon Sep 17 00:00:00 2001 From: Vitor Hugo Homem Marzarotto <59698484+vits-hugs@users.noreply.github.com> Date: Tue, 20 Jan 2026 04:10:42 -0300 Subject: [PATCH 3/9] Adds url kubernetes iso (#10862) Co-authored-by: Vitor Hugo Homem Marzarotto Co-authored-by: Henrique Sato --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../version/KubernetesVersionManagerImpl.java | 19 ++-- .../KubernetesSupportedVersionResponse.java | 12 +++ .../KubernetesVersionManagerImplTest.java | 6 +- .../version/KubernetesVersionServiceTest.java | 90 +++++++++++++++---- ui/public/locales/en.json | 1 + ui/public/locales/pt_BR.json | 1 + ui/src/config/section/image.js | 6 +- 8 files changed, 105 insertions(+), 31 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 4abc0d13d74..daf1bdc705d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1097,6 +1097,7 @@ public class ApiConstants { public static final String DOCKER_REGISTRY_EMAIL = "dockerregistryemail"; public static final String ISO_NAME = "isoname"; public static final String ISO_STATE = "isostate"; + public static final String ISO_URL = "isourl"; public static final String SEMANTIC_VERSION = "semanticversion"; public static final String KUBERNETES_VERSION_ID = "kubernetesversionid"; public static final String KUBERNETES_VERSION_NAME = "kubernetesversionname"; diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java index 99c9a4de051..7b126b2fba0 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java @@ -53,6 +53,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.template.TemplateApiService; import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentContext; @@ -85,7 +86,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0"; protected void updateTemplateDetailsInKubernetesSupportedVersionResponse( - final KubernetesSupportedVersion kubernetesSupportedVersion, KubernetesSupportedVersionResponse response) { + final KubernetesSupportedVersion kubernetesSupportedVersion, KubernetesSupportedVersionResponse response, boolean isRootAdmin) { TemplateJoinVO template = templateJoinDao.findById(kubernetesSupportedVersion.getIsoId()); if (template == null) { return; @@ -95,11 +96,14 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne if (template.getState() != null) { response.setIsoState(template.getState().toString()); } + if (isRootAdmin) { + response.setIsoUrl(template.getUrl()); + } response.setIsoArch(template.getArch().getType()); response.setDirectDownload(template.isDirectDownload()); } - private KubernetesSupportedVersionResponse createKubernetesSupportedVersionResponse(final KubernetesSupportedVersion kubernetesSupportedVersion) { + private KubernetesSupportedVersionResponse createKubernetesSupportedVersionResponse(final KubernetesSupportedVersion kubernetesSupportedVersion, boolean isRootAdmin) { KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse(); response.setObjectName("kubernetessupportedversion"); response.setId(kubernetesSupportedVersion.getUuid()); @@ -118,7 +122,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne response.setSupportsHA(compareSemanticVersions(kubernetesSupportedVersion.getSemanticVersion(), KubernetesClusterService.MIN_KUBERNETES_VERSION_HA_SUPPORT)>=0); response.setSupportsAutoscaling(versionSupportsAutoscaling(kubernetesSupportedVersion)); - updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, response); + updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, response, isRootAdmin); response.setCreated(kubernetesSupportedVersion.getCreated()); return response; } @@ -126,8 +130,11 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne private ListResponse createKubernetesSupportedVersionListResponse( List versions, Integer count) { List responseList = new ArrayList<>(); + Account caller = CallContext.current().getCallingAccount(); + boolean isRootAdmin = accountManager.isRootAdmin(caller.getId()); + for (KubernetesSupportedVersionVO version : versions) { - responseList.add(createKubernetesSupportedVersionResponse(version)); + responseList.add(createKubernetesSupportedVersionResponse(version, isRootAdmin)); } ListResponse response = new ListResponse<>(); response.setResponses(responseList, count); @@ -374,7 +381,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO); CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid()); - return createKubernetesSupportedVersionResponse(supportedVersionVO); + return createKubernetesSupportedVersionResponse(supportedVersionVO, true); } @Override @@ -435,7 +442,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne } version = kubernetesSupportedVersionDao.findById(versionId); } - return createKubernetesSupportedVersionResponse(version); + return createKubernetesSupportedVersionResponse(version, true); } @Override diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java index cfa3212e409..f6e1ee85944 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java @@ -50,6 +50,10 @@ public class KubernetesSupportedVersionResponse extends BaseResponse { @Param(description = "The name of the binaries ISO for Kubernetes supported version") private String isoName; + @SerializedName(ApiConstants.ISO_URL) + @Param(description = "the URL of the binaries ISO for Kubernetes supported version") + private String isoUrl; + @SerializedName(ApiConstants.ISO_STATE) @Param(description = "The state of the binaries ISO for Kubernetes supported version") private String isoState; @@ -134,6 +138,14 @@ public class KubernetesSupportedVersionResponse extends BaseResponse { this.isoName = isoName; } + public String getIsoUrl() { + return isoUrl; + } + + public void setIsoUrl(String isoUrl) { + this.isoUrl = isoUrl; + } + public String getIsoState() { return isoState; } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java index f827610c3cb..bbec555e8e5 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java @@ -48,7 +48,7 @@ public class KubernetesVersionManagerImplTest { Mockito.when(kubernetesSupportedVersion.getIsoId()).thenReturn(1L); KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse(); kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, - response); + response, true); Assert.assertNull(ReflectionTestUtils.getField(response, "isoId")); } @@ -63,13 +63,13 @@ public class KubernetesVersionManagerImplTest { Mockito.when(templateJoinVO.getUuid()).thenReturn(uuid); Mockito.when(templateJoinDao.findById(1L)).thenReturn(templateJoinVO); kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, - response); + response, true); Assert.assertEquals(uuid, ReflectionTestUtils.getField(response, "isoId")); Assert.assertNull(ReflectionTestUtils.getField(response, "isoState")); ObjectInDataStoreStateMachine.State state = ObjectInDataStoreStateMachine.State.Ready; Mockito.when(templateJoinVO.getState()).thenReturn(state); kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, - response); + response, true); Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState")); } } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java index 455df6b57d4..b874a9a0ffa 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java @@ -17,6 +17,9 @@ package com.cloud.kubernetes.version; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; import java.lang.reflect.Field; @@ -25,6 +28,11 @@ import java.util.List; import java.util.UUID; import com.cloud.cpu.CPU; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.user.UserVO; import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd; @@ -63,11 +71,6 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.template.TemplateApiService; import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.User; -import com.cloud.user.UserVO; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.Filter; @@ -95,6 +98,8 @@ public class KubernetesVersionServiceTest { private DataCenterDao dataCenterDao; @Mock private TemplateApiService templateService; + @Mock + private Account accountMock; AutoCloseable closeable; @@ -124,6 +129,7 @@ public class KubernetesVersionServiceTest { when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone); TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class); + when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com"); when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready); when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault()); when(templateJoinDao.findById(Mockito.anyLong())).thenReturn(templateJoinVO); @@ -140,19 +146,66 @@ public class KubernetesVersionServiceTest { @Test public void listKubernetesSupportedVersionsTest() { - ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class); - List versionVOs = new ArrayList<>(); - KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class); - when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION); - versionVOs.add(versionVO); - when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO); - when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(SearchCriteria.class), - Mockito.any(Filter.class))).thenReturn(new Pair<>(versionVOs, versionVOs.size())); - ListResponse versionsResponse = - kubernetesVersionService.listKubernetesSupportedVersions(cmd); - Assert.assertEquals(versionVOs.size(), versionsResponse.getCount().intValue()); - Assert.assertTrue(CollectionUtils.isNotEmpty(versionsResponse.getResponses())); - Assert.assertEquals(versionVOs.size(), versionsResponse.getResponses().size()); + CallContext callContextMock = Mockito.mock(CallContext.class); + try (MockedStatic callContextMockedStatic = Mockito.mockStatic(CallContext.class)) { + callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock); + final SearchCriteria versionSearchCriteria = Mockito.mock(SearchCriteria.class); + when(callContextMock.getCallingAccount()).thenReturn(accountMock); + ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class); + List versionVOs = new ArrayList<>(); + KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class); + when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION); + versionVOs.add(versionVO); + when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO); + when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class))) + .thenReturn(new Pair<>(versionVOs, versionVOs.size())); + ListResponse versionsResponse = + kubernetesVersionService.listKubernetesSupportedVersions(cmd); + Assert.assertEquals(versionVOs.size(), versionsResponse.getCount().intValue()); + Assert.assertTrue(CollectionUtils.isNotEmpty(versionsResponse.getResponses())); + Assert.assertEquals(versionVOs.size(), versionsResponse.getResponses().size()); + } + } + + @Test + public void listKubernetesSupportedVersionsTestWhenAdmin() { + CallContext callContextMock = Mockito.mock(CallContext.class); + try (MockedStatic callContextMockedStatic = Mockito.mockStatic(CallContext.class)) { + callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock); + ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class); + List versionVOs = new ArrayList<>(); + KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class); + when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION); + versionVOs.add(versionVO); + when(callContextMock.getCallingAccount()).thenReturn(accountMock); + when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO); + when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class))) + .thenReturn(new Pair<>(versionVOs, versionVOs.size())); + when(accountManager.isRootAdmin(anyLong())).thenReturn(true); + ListResponse response = kubernetesVersionService.listKubernetesSupportedVersions(cmd); + assertNotNull(response.getResponses().get(0).getIsoUrl()); + } + } + + @Test + public void listKubernetesSupportedVersionsTestWhenOtherUser() { + CallContext callContextMock = Mockito.mock(CallContext.class); + try (MockedStatic callContextMockedStatic = Mockito.mockStatic(CallContext.class)) { + callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock); + ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class); + List versionVOs = new ArrayList<>(); + KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class); + when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION); + versionVOs.add(versionVO); + when(callContextMock.getCallingAccount()).thenReturn(accountMock); + when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO); + when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class))) + .thenReturn(new Pair<>(versionVOs, versionVOs.size())); + when(accountManager.isRootAdmin(anyLong())).thenReturn(false); + when(accountMock.getId()).thenReturn(2L); + ListResponse response = kubernetesVersionService.listKubernetesSupportedVersions(cmd); + assertNull(response.getResponses().get(0).getIsoUrl()); + } } @Test(expected = InvalidParameterValueException.class) @@ -224,7 +277,6 @@ public class KubernetesVersionServiceTest { mockedComponentContext.when(() -> ComponentContext.inject(Mockito.any(RegisterIsoCmd.class))).thenReturn( new RegisterIsoCmd()); mockedCallContext.when(CallContext::current).thenReturn(callContext); - when(templateService.registerIso(Mockito.any(RegisterIsoCmd.class))).thenReturn( Mockito.mock(VirtualMachineTemplate.class)); VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class); diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 791091e8e2a..aaf499d2f95 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1254,6 +1254,7 @@ "label.isoname": "Attached ISO", "label.isos": "ISOs", "label.isostate": "ISO state", +"label.isourl": "ISO URL", "label.ispersistent": "Persistent ", "label.ispublic": "Public", "label.isready": "Ready", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index 4d95b341ab4..1b51bc438e5 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -874,6 +874,7 @@ "label.isoname": "Imagem ISO plugada", "label.isos": "ISOs", "label.isostate": "Estado da ISO", +"label.isourl": "URL da ISO", "label.ispersistent": "Persistente", "label.ispublic": "P\u00fablico", "label.isready": "Pronto", diff --git a/ui/src/config/section/image.js b/ui/src/config/section/image.js index 46dec2e1b24..3f8286c5fb1 100644 --- a/ui/src/config/section/image.js +++ b/ui/src/config/section/image.js @@ -60,9 +60,9 @@ export default { details: () => { var fields = ['name', 'id', 'displaytext', 'checksum', 'hypervisor', 'arch', 'format', 'ostypename', 'size', 'physicalsize', 'isready', 'passwordenabled', 'crossZones', 'templatetype', 'directdownload', 'deployasis', 'ispublic', 'isfeatured', 'isextractable', 'isdynamicallyscalable', 'crosszones', 'type', - 'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy'] + 'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy', 'url'] if (['Admin'].includes(store.getters.userInfo.roletype)) { - fields.push('templatetag', 'templatetype', 'url') + fields.push('templatetag', 'templatetype') } return fields }, @@ -372,7 +372,7 @@ export default { permission: ['listKubernetesSupportedVersions'], searchFilters: ['zoneid', 'minimumsemanticversion', 'arch'], columns: ['name', 'state', 'semanticversion', 'isostate', 'mincpunumber', 'minmemory', 'arch', 'zonename'], - details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'arch', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created'], + details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'arch', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created', 'isourl'], tabs: [ { name: 'details', From 03d24ff851d491dbc0145014b4bd967371127c50 Mon Sep 17 00:00:00 2001 From: Henrique Sato Date: Tue, 20 Jan 2026 04:12:16 -0300 Subject: [PATCH 4/9] Fix NPE on primary storage delete (#11817) --- .../main/java/com/cloud/storage/StorageManagerImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 8b5e0b24f48..8392c85527d 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -1558,14 +1558,18 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C protected String getStoragePoolNonDestroyedVolumesLog(long storagePoolId) { StringBuilder sb = new StringBuilder(); - List nonDestroyedVols = volumeDao.findByPoolId(storagePoolId, null).stream().filter(vol -> vol.getState() != Volume.State.Destroy).collect(Collectors.toList()); + List nonDestroyedVols = volumeDao.findByPoolId(storagePoolId, null); VMInstanceVO volInstance; List logMessageInfo = new ArrayList<>(); sb.append("["); for (VolumeVO vol : nonDestroyedVols) { volInstance = _vmInstanceDao.findById(vol.getInstanceId()); - logMessageInfo.add(String.format("Volume [%s] (attached to VM [%s])", vol.getUuid(), volInstance.getUuid())); + if (volInstance != null) { + logMessageInfo.add(String.format("Volume [%s] (attached to VM [%s])", vol.getUuid(), volInstance.getUuid())); + } else { + logMessageInfo.add(String.format("Volume [%s]", vol.getUuid())); + } } sb.append(String.join(", ", logMessageInfo)); sb.append("]"); From da518e903621187e4cb75af9f550b7c6d57666f9 Mon Sep 17 00:00:00 2001 From: Daman Arora <61474540+Damans227@users.noreply.github.com> Date: Tue, 20 Jan 2026 02:13:15 -0500 Subject: [PATCH 5/9] CKS: Add image store validation for Kubernetes version registration (#12418) Co-authored-by: Daman Arora --- .../version/KubernetesVersionManagerImpl.java | 33 +++++++++ .../KubernetesVersionManagerImplTest.java | 72 +++++++++++++++++++ .../version/KubernetesVersionServiceTest.java | 9 +++ 3 files changed, 114 insertions(+) diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java index 7b126b2fba0..8363f6f87e3 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java @@ -33,6 +33,9 @@ import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesS import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.cloud.api.query.dao.TemplateJoinDao; @@ -81,6 +84,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne @Inject private DataCenterDao dataCenterDao; @Inject + private ImageStoreDao imageStoreDao; + @Inject private TemplateApiService templateService; public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0"; @@ -323,6 +328,32 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second()); } + private void validateImageStoreForZone(Long zoneId, boolean directDownload) { + if (directDownload) { + return; + } + if (zoneId != null) { + List imageStores = imageStoreDao.listStoresByZoneId(zoneId); + if (CollectionUtils.isEmpty(imageStores)) { + DataCenterVO zone = dataCenterDao.findById(zoneId); + String zoneName = zone != null ? zone.getName() : String.valueOf(zoneId); + throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO. No image store available in zone: %s", zoneName)); + } + } else { + List zones = dataCenterDao.listAllZones(); + List zonesWithoutStorage = new ArrayList<>(); + for (DataCenterVO zone : zones) { + List imageStores = imageStoreDao.listStoresByZoneId(zone.getId()); + if (CollectionUtils.isEmpty(imageStores)) { + zonesWithoutStorage.add(zone.getName()); + } + } + if (!zonesWithoutStorage.isEmpty()) { + throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO for all zones. The following zones have no image store: %s", String.join(", ", zonesWithoutStorage))); + } + } + } + @Override @ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD, eventDescription = "Adding Kubernetes supported version") @@ -368,6 +399,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne } } + validateImageStoreForZone(zoneId, isDirectDownload); + VMTemplateVO template = null; try { VirtualMachineTemplate vmTemplate = registerKubernetesVersionIso(zoneId, name, isoUrl, isoChecksum, isDirectDownload, arch); diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java index bbec555e8e5..35f8e66e045 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java @@ -16,10 +16,15 @@ // under the License. package com.cloud.kubernetes.version; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.UUID; import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,6 +37,9 @@ import org.springframework.test.util.ReflectionTestUtils; import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.cpu.CPU; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.exception.InvalidParameterValueException; @RunWith(MockitoJUnitRunner.class) public class KubernetesVersionManagerImplTest { @@ -39,6 +47,12 @@ public class KubernetesVersionManagerImplTest { @Mock TemplateJoinDao templateJoinDao; + @Mock + ImageStoreDao imageStoreDao; + + @Mock + DataCenterDao dataCenterDao; + @InjectMocks KubernetesVersionManagerImpl kubernetesVersionManager = new KubernetesVersionManagerImpl(); @@ -72,4 +86,62 @@ public class KubernetesVersionManagerImplTest { response, true); Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState")); } + + @Test + public void testValidateImageStoreForZoneWithDirectDownload() { + ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", 1L, true); + } + + @Test + public void testValidateImageStoreForZoneWithValidZone() { + Long zoneId = 1L; + List imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class)); + Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(imageStores); + + ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidateImageStoreForZoneWithNoImageStore() { + Long zoneId = 1L; + DataCenterVO zone = Mockito.mock(DataCenterVO.class); + Mockito.when(zone.getName()).thenReturn("test-zone"); + Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(zone); + Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(Collections.emptyList()); + + ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false); + } + + @Test + public void testValidateImageStoreForAllZonesWithAllValid() { + DataCenterVO zone1 = Mockito.mock(DataCenterVO.class); + Mockito.when(zone1.getId()).thenReturn(1L); + DataCenterVO zone2 = Mockito.mock(DataCenterVO.class); + Mockito.when(zone2.getId()).thenReturn(2L); + List zones = Arrays.asList(zone1, zone2); + Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones); + + List imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class)); + Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores); + Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(imageStores); + + ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void testValidateImageStoreForAllZonesWithSomeMissingStorage() { + DataCenterVO zone1 = Mockito.mock(DataCenterVO.class); + Mockito.when(zone1.getId()).thenReturn(1L); + DataCenterVO zone2 = Mockito.mock(DataCenterVO.class); + Mockito.when(zone2.getId()).thenReturn(2L); + Mockito.when(zone2.getName()).thenReturn("zone-without-storage"); + List zones = Arrays.asList(zone1, zone2); + Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones); + + List imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class)); + Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores); + Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(Collections.emptyList()); + + ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false); + } } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java index b874a9a0ffa..7ba35169b9e 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java @@ -78,6 +78,9 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; + @RunWith(MockitoJUnitRunner.class) public class KubernetesVersionServiceTest { @@ -97,6 +100,8 @@ public class KubernetesVersionServiceTest { @Mock private DataCenterDao dataCenterDao; @Mock + private ImageStoreDao imageStoreDao; + @Mock private TemplateApiService templateService; @Mock private Account accountMock; @@ -128,6 +133,10 @@ public class KubernetesVersionServiceTest { DataCenterVO zone = Mockito.mock(DataCenterVO.class); when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone); + List imageStores = new ArrayList<>(); + imageStores.add(Mockito.mock(ImageStoreVO.class)); + when(imageStoreDao.listStoresByZoneId(Mockito.anyLong())).thenReturn(imageStores); + TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class); when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com"); when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready); From cf36fb00008b3f7a71e155d0e408daa907fa04e3 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Tue, 20 Jan 2026 12:55:16 +0530 Subject: [PATCH 6/9] Set nfsVersion in ssvm agent.properties only if it is not null (#12445) --- .../secondarystorage/SecondaryStorageManagerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java index 5698632249d..c9bcb911000 100644 --- a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java +++ b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java @@ -1224,8 +1224,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar if (dc.getDns2() != null) { buf.append(" dns2=").append(dc.getDns2()); } - String nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStores.get(0).getId()) : null; - buf.append(" nfsVersion=").append(nfsVersion); + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(secStores.get(0).getId()); + if (StringUtils.isNotBlank(nfsVersion)) { + buf.append(" nfsVersion=").append(nfsVersion); + } buf.append(" keystore_password=").append(VirtualMachineGuru.getEncodedString(PasswordGenerator.generateRandomPassword(16))); String bootArgs = buf.toString(); if (logger.isDebugEnabled()) { From 496bc0329cdb6fcb6cbefb463d37ba1599192176 Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Tue, 20 Jan 2026 04:56:32 -0300 Subject: [PATCH 7/9] Fix: Condition for aborting migration, resume paused VMs on destination (#12331) --- .../wrapper/LibvirtMigrateCommandWrapper.java | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java index 1f14402c85e..fe18a88fe1f 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java @@ -243,20 +243,21 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper migrateThread = executor.submit(worker); executor.shutdown(); long sleeptime = 0; + final int migrateDowntime = libvirtComputingResource.getMigrateDowntime(); + boolean isMigrateDowntimeSet = false; + while (!executor.isTerminated()) { Thread.sleep(100); sleeptime += 100; - if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state - final int migrateDowntime = libvirtComputingResource.getMigrateDowntime(); - if (migrateDowntime > 0 ) { - try { - final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime); - if (setDowntime == 0 ) { - logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms"); - } - } catch (final LibvirtException e) { - logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage()); + if (!isMigrateDowntimeSet && migrateDowntime > 0 && sleeptime >= 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state + try { + final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime); + if (setDowntime == 0 ) { + isMigrateDowntimeSet = true; + logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms"); } + } catch (final LibvirtException e) { + logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage()); } } if (sleeptime % 1000 == 0) { @@ -272,7 +273,7 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper Date: Tue, 20 Jan 2026 13:38:39 +0530 Subject: [PATCH 8/9] Storage pool monitor disconnect improvements (#12398) --- .../storage/listener/StoragePoolMonitor.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java index a0e10c646b5..6df3cbaeedf 100644 --- a/server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java @@ -21,6 +21,7 @@ import java.util.List; import javax.inject.Inject; import com.cloud.storage.StorageManager; +import com.cloud.utils.Profiler; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; @@ -144,12 +145,13 @@ public class StoragePoolMonitor implements Listener { } @Override - public synchronized boolean processDisconnect(long agentId, Status state) { + public boolean processDisconnect(long agentId, Status state) { return processDisconnect(agentId, null, null, state); } @Override - public synchronized boolean processDisconnect(long agentId, String uuid, String name, Status state) { + public boolean processDisconnect(long agentId, String uuid, String name, Status state) { + logger.debug("Starting disconnect for Agent [id: {}, uuid: {}, name: {}]", agentId, uuid, name); Host host = _storageManager.getHost(agentId); if (host == null) { logger.warn("Agent [id: {}, uuid: {}, name: {}] not found, not disconnecting pools", agentId, uuid, name); @@ -157,38 +159,52 @@ public class StoragePoolMonitor implements Listener { } if (host.getType() != Host.Type.Routing) { + logger.debug("Host [id: {}, uuid: {}, name: {}] is not of type {}, skip", agentId, uuid, name, Host.Type.Routing); return false; } + logger.debug("Looking for connected Storage Pools for Host [id: {}, uuid: {}, name: {}]", agentId, uuid, name); List storagePoolHosts = _storageManager.findStoragePoolsConnectedToHost(host.getId()); if (storagePoolHosts == null) { - if (logger.isTraceEnabled()) { - logger.trace("No pools to disconnect for host: {}", host); - } + logger.debug("No pools to disconnect for host: {}", host); return true; } + logger.debug("Found {} pools to disconnect for host: {}", storagePoolHosts.size(), host); boolean disconnectResult = true; - for (StoragePoolHostVO storagePoolHost : storagePoolHosts) { + int storagePoolHostsSize = storagePoolHosts.size(); + for (int i = 0; i < storagePoolHostsSize; i++) { + StoragePoolHostVO storagePoolHost = storagePoolHosts.get(i); + logger.debug("Processing disconnect from Storage Pool {} ({} of {}) for host: {}", storagePoolHost.getPoolId(), i, storagePoolHostsSize, host); StoragePoolVO pool = _poolDao.findById(storagePoolHost.getPoolId()); if (pool == null) { + logger.debug("No Storage Pool found with id {} ({} of {}) for host: {}", storagePoolHost.getPoolId(), i, storagePoolHostsSize, host); continue; } if (!pool.isShared()) { + logger.debug("Storage Pool {} ({}) ({} of {}) is not shared for host: {}, ignore disconnect", pool.getName(), pool.getUuid(), i, storagePoolHostsSize, host); continue; } // Handle only PowerFlex pool for now, not to impact other pools behavior if (pool.getPoolType() != StoragePoolType.PowerFlex) { + logger.debug("Storage Pool {} ({}) ({} of {}) is not of type {} for host: {}, ignore disconnect", pool.getName(), pool.getUuid(), i, storagePoolHostsSize, pool.getPoolType(), host); continue; } + logger.debug("Sending disconnect to Storage Pool {} ({}) ({} of {}) for host: {}", pool.getName(), pool.getUuid(), i, storagePoolHostsSize, host); + Profiler disconnectProfiler = new Profiler(); try { + disconnectProfiler.start(); _storageManager.disconnectHostFromSharedPool(host, pool); } catch (Exception e) { logger.error("Unable to disconnect host {} from storage pool {} due to {}", host, pool, e.toString()); disconnectResult = false; + } finally { + disconnectProfiler.stop(); + long disconnectDuration = disconnectProfiler.getDurationInMillis() / 1000; + logger.debug("Finished disconnect with result {} from Storage Pool {} ({}) ({} of {}) for host: {}, duration: {} secs", disconnectResult, pool.getName(), pool.getUuid(), i, storagePoolHostsSize, host, disconnectDuration); } } From 036489b288cef2ccd10f1f83e21a7ff34b6b6a03 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 21 Jan 2026 09:59:21 +0100 Subject: [PATCH 9/9] CKS: fix resource limitation check on cpu when scale cks cluster (#12379) --- .../cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java index e6ed850fba5..f6af2b95978 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java @@ -1383,8 +1383,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne } totalAdditionalVms += additional; - long effectiveCpu = (long) so.getCpu() * so.getSpeed(); - totalAdditionalCpuUnits += effectiveCpu * additional; + totalAdditionalCpuUnits += so.getCpu() * additional; totalAdditionalRamMb += so.getRamSize() * additional; try {