This is an automated email from the ASF dual-hosted git repository. DaanHoogland pushed a commit to branch ghi13324-eventEmit in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 1f522f50b845e59964f63e0d82678e8f7852fdf4 Author: Daan Hoogland <[email protected]> AuthorDate: Wed Jul 22 15:03:56 2026 +0200 add an maintenance prepare error event --- api/src/main/java/com/cloud/event/EventTypes.java | 2 ++ .../main/java/com/cloud/resource/ResourceManagerImpl.java | 3 +++ .../java/com/cloud/resource/ResourceManagerImplTest.java | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java index 81ed185dae5..3ef7db9ea82 100644 --- a/api/src/main/java/com/cloud/event/EventTypes.java +++ b/api/src/main/java/com/cloud/event/EventTypes.java @@ -458,6 +458,7 @@ public class EventTypes { public static final String EVENT_MAINTENANCE_CANCEL = "MAINT.CANCEL"; public static final String EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE = "MAINT.CANCEL.PS"; public static final String EVENT_MAINTENANCE_PREPARE = "MAINT.PREPARE"; + public static final String EVENT_MAINTENANCE_PREPARE_ERROR = "MAINT.PREPARE.ERROR"; public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS"; // Primary storage pool @@ -1046,6 +1047,7 @@ public class EventTypes { entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class); entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class); entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class); + entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_ERROR, Host.class); entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class); // Primary storage pool diff --git a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java index 6e78e3bea83..3e7cd8ca0bc 100755 --- a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java @@ -1726,6 +1726,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, logger.debug("Host {} entering in PrepareForMaintenanceWithErrors state", host); configureVncAccessForKVMHostFailedMigrations(host, errorVms); resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId); + ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(), + EventVO.LEVEL_ERROR, EventTypes.EVENT_MAINTENANCE_PREPARE_ERROR, + String.format("failed to prepare host %s for maintenance due to migration or VM state errors", host), host.getId(), null, 0); return false; } diff --git a/server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java b/server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java index 91e4bf7a47b..4f65720a8eb 100644 --- a/server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java +++ b/server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java @@ -22,6 +22,8 @@ import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.capacity.dao.CapacityDao; import com.cloud.event.ActionEventUtils; +import com.cloud.event.EventTypes; +import com.cloud.event.EventVO; import com.cloud.exception.InvalidParameterValueException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.Host; @@ -78,6 +80,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -442,6 +445,7 @@ public class ResourceManagerImplTest { } private void verifyErrorInPrepareForMaintenanceCalls() throws NoTransitionException { + when(host.getResourceState()).thenReturn(ResourceState.PrepareForMaintenance); boolean enterMaintenanceMode = resourceManager.checkAndMaintain(hostId); verify(resourceManager).attemptMaintain(host); verify(resourceManager).setHostIntoErrorInPrepareForMaintenance(eq(host), any()); @@ -449,9 +453,18 @@ public class ResourceManagerImplTest { verify(resourceManager, never()).setHostIntoErrorInMaintenance(any(), any()); verify(resourceManager, never()).setHostIntoPrepareForMaintenanceAfterErrorsFixed(any()); verify(resourceManager).resourceStateTransitTo(eq(host), eq(UnableToMigrate), anyLong()); + String expectedDescription = String.format("failed to prepare host %s for maintenance due to migration or VM state errors", host); + actionEventUtilsMocked.verify(() -> ActionEventUtils.onCompletedActionEvent( + anyLong(), anyLong(), eq(EventVO.LEVEL_ERROR), eq(EventTypes.EVENT_MAINTENANCE_PREPARE_ERROR), + eq(expectedDescription), eq(hostId), isNull(), eq(0L))); Assert.assertFalse(enterMaintenanceMode); } + @Test + public void testMaintenancePrepareErrorEventMapsToHostEntity() { + Assert.assertEquals(Host.class, EventTypes.getEntityClassForEvent(EventTypes.EVENT_MAINTENANCE_PREPARE_ERROR)); + } + private void verifyReturnToPrepareForMaintenanceCalls() throws NoTransitionException { boolean enterMaintenanceMode = resourceManager.checkAndMaintain(hostId); verify(resourceManager).attemptMaintain(host);
