From 3134efb971da306bab87f2bee3686e308454c534 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Mon, 4 Aug 2025 16:21:20 +0530 Subject: [PATCH 1/5] plugin-swift: handle null cache store (#11380) Fixes https://github.com/apache/cloudstack/pull/11315#pullrequestreview-3074036751 Signed-off-by: Abhishek Kumar --- .../driver/SwiftImageStoreDriverImpl.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 7e1486214bc..44f321f9543 100644 --- a/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -24,11 +24,6 @@ import java.util.UUID; import javax.inject.Inject; -import com.cloud.configuration.Config; -import com.cloud.utils.SwiftUtil; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -38,18 +33,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.log4j.Logger; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.configuration.Config; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.template.VirtualMachineTemplate; +import com.cloud.utils.SwiftUtil; import com.cloud.utils.exception.CloudRuntimeException; public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl { @@ -101,8 +99,13 @@ public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl { @Override public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback callback) { Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - VirtualMachineTemplate tmpl = _templateDao.findById(data.getId()); DataStore cacheStore = cacheManager.getCacheStorage(dataStore.getScope()); + if (cacheStore == null) { + String errMsg = String.format("No cache store found for scope: %s", + dataStore.getScope().getScopeType().name()); + s_logger.error(errMsg); + throw new CloudRuntimeException(errMsg); + } DownloadCommand dcmd = new DownloadCommand((TemplateObjectTO)(data.getTO()), maxTemplateSizeInBytes); dcmd.setCacheStore(cacheStore.getTO()); dcmd.setProxy(getHttpProxy()); From a0fd37f4955795742110a1015dfc3b0cf01694d1 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Mon, 4 Aug 2025 16:21:58 +0530 Subject: [PATCH 2/5] ui: pass validated storagepolicy for swift store (#11315) Fixes #9789 Signed-off-by: Abhishek Kumar --- ui/src/views/infra/AddSecondaryStorage.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/views/infra/AddSecondaryStorage.vue b/ui/src/views/infra/AddSecondaryStorage.vue index 4adc4e9a1d6..746af5b959d 100644 --- a/ui/src/views/infra/AddSecondaryStorage.vue +++ b/ui/src/views/infra/AddSecondaryStorage.vue @@ -295,8 +295,10 @@ export default { const swiftParams = { account: values.account, username: values.username, - key: values.key, - storagepolicy: values.storagepolicy + key: values.key + } + if (values.storagepolicy) { + swiftParams.storagepolicy = values.storagepolicy } Object.keys(swiftParams).forEach((key, index) => { data['details[' + index.toString() + '].key'] = key From 626f3de69ad332bb89c21b0bc2a220d975a1dcba Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Mon, 4 Aug 2025 16:26:37 +0530 Subject: [PATCH 3/5] Handle project delete in detailsview. (#11197) --- .../admin/acl/project/ListProjectRolesCmd.java | 2 +- ui/src/views/project/AccountsTab.vue | 12 +----------- ui/src/views/project/iam/ProjectRoleTab.vue | 12 +----------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/ListProjectRolesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/ListProjectRolesCmd.java index e876dbc9b58..dedbb410ea5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/ListProjectRolesCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/ListProjectRolesCmd.java @@ -72,7 +72,7 @@ public class ListProjectRolesCmd extends BaseListCmd { @Override public void execute() { - List projectRoles; + List projectRoles = new ArrayList<>(); if (getProjectId() != null && getProjectRoleId() != null) { projectRoles = Collections.singletonList(projRoleService.findProjectRole(getProjectRoleId(), getProjectId())); } else if (StringUtils.isNotBlank(getRoleName())) { diff --git a/ui/src/views/project/AccountsTab.vue b/ui/src/views/project/AccountsTab.vue index 8c7282b988b..ca56b8977ae 100644 --- a/ui/src/views/project/AccountsTab.vue +++ b/ui/src/views/project/AccountsTab.vue @@ -157,17 +157,6 @@ export default { this.fetchData() }, inject: ['parentFetchData'], - watch: { - resource: { - deep: true, - handler (newItem) { - if (!newItem || !newItem.id) { - return - } - this.fetchData() - } - } - }, methods: { fetchData () { const params = {} @@ -175,6 +164,7 @@ export default { params.page = this.page params.pageSize = this.pageSize this.updateProjectApi = this.$store.getters.apis.updateProject + if (!this.resource.id) return this.fetchUsers() this.fetchProjectAccounts(params) if (this.isProjectRolesSupported()) { diff --git a/ui/src/views/project/iam/ProjectRoleTab.vue b/ui/src/views/project/iam/ProjectRoleTab.vue index a0768db3164..98d542f88a2 100644 --- a/ui/src/views/project/iam/ProjectRoleTab.vue +++ b/ui/src/views/project/iam/ProjectRoleTab.vue @@ -173,17 +173,6 @@ export default { mounted () { this.fetchData() }, - watch: { - resource: { - deep: true, - handler (newItem) { - if (!newItem || !newItem.id) { - return - } - this.fetchData() - } - } - }, methods: { initForm () { this.formRef = ref() @@ -192,6 +181,7 @@ export default { }, fetchData () { this.loading = true + if (!this.resource.id) return api('listProjectRoles', { projectid: this.resource.id }).then(json => { const projectRoles = json.listprojectrolesresponse.projectrole if (!projectRoles || projectRoles.length === 0) { From de5188e50c8cbeb66a3ddada0c709412a566de4f Mon Sep 17 00:00:00 2001 From: Eduardo Vieira Date: Mon, 4 Aug 2025 08:03:30 -0300 Subject: [PATCH 4/5] fix storage pool capacity threshold flag (#11366) --- .../java/org/apache/cloudstack/metrics/MetricsServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java index 86bf2e3e351..42a2fa815e9 100644 --- a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java +++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java @@ -657,7 +657,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements metricsResponse.setStorageUsedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageThreshold); metricsResponse.setStorageUsedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold); metricsResponse.setStorageAllocatedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor(), storageThreshold); - metricsResponse.setStorageAllocatedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold); + metricsResponse.setStorageAllocatedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor(), storageDisableThreshold); metricsResponses.add(metricsResponse); } return metricsResponses; From cda3640be1590da60ecd3e1bd11a9899ca655416 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Mon, 4 Aug 2025 16:37:32 +0530 Subject: [PATCH 5/5] juniper-contrail: publish events only for the module (#11373) * juniper-contrail: publish events only for the module This plugin has an ActionEventInterceptor of its own and currently it intercepts all action events which is incorrect as all action events are already handled by com.cloud.event.ActionEventInterceptor. This PR limits publishing events on event bus by plugin's interceptor only in case the event is from the same module. Existing behaviour was causing warnings in Webhook service as event account was missing. 2025-07-31 19:18:59,391 WARN [o.a.c.m.w.WebhookServiceImpl] ... to any webhook as account ID is missing Signed-off-by: Abhishek Kumar --- .../network/contrail/management/EventUtils.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java index d47bf6eceeb..338caca1fbe 100644 --- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java +++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java @@ -48,6 +48,10 @@ public class EventUtils { private static EventDistributor eventDistributor; + private static final String MODULE_TOP_LEVEL_PACKAGE = + EventUtils.class.getPackage().getName().substring(0, + EventUtils.class.getPackage().getName().lastIndexOf('.')); + public EventUtils() { } @@ -143,6 +147,13 @@ public class EventUtils { @Override public void interceptComplete(Method method, Object target, Object event) { ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + boolean sameModule = false; + if (target != null && target.getClass().getPackage() != null) { + sameModule = target.getClass().getPackage().getName().startsWith(MODULE_TOP_LEVEL_PACKAGE); + } + if (!sameModule) { + return; + } if (actionEvent != null) { CallContext ctx = CallContext.current(); if (!actionEvent.create()) {