This is an automated email from the ASF dual-hosted git repository.

Pearl1594 pushed a commit to branch fix-mshost-duplicate-registration
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit c64d1feb79302a857e013bc2c4f3a2f8fbfd098f
Author: mprokopchuk <[email protected]>
AuthorDate: Mon Feb 16 22:24:30 2026 +0100

    Handle multiple active entries for same hostname in k8s setup
---
 .../java/com/cloud/cluster/ClusterManagerImpl.java |  4 ++--
 .../cloud/cluster/dao/ManagementServerHostDao.java |  2 +-
 .../cluster/dao/ManagementServerHostDaoImpl.java   | 25 +++++-----------------
 .../dao/ManagementServerHostDaoImplTest.java       | 19 ++++++++--------
 4 files changed, 18 insertions(+), 32 deletions(-)

diff --git 
a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java 
b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
index 997fe6de48a..2856b0a23f2 100644
--- a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
@@ -1050,8 +1050,8 @@ public class ClusterManagerImpl extends ManagerBase 
implements ClusterManager, C
 
                 // Look for duplicate hostname in the case of kubernetes setup 
where ip/mac changes but hostname is constant.
                 if (mshost == null && StringUtils.isNotBlank(currentHostname)) 
{
-                    ManagementServerHostVO activeEntry = 
_mshostDao.findByName(currentHostname);
-                    if (activeEntry != null) {
+                    List<ManagementServerHostVO> activeEntries = 
_mshostDao.findAllByName(currentHostname);
+                    for (ManagementServerHostVO activeEntry : activeEntries) {
                         // Found an active entry with this hostname but 
different MSID
                         // This happens when a pod restarts with a new MAC 
address (new MSID)
                         if (activeEntry.getMsid() != _msId) {
diff --git 
a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
 
b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
index adcabc93028..439e8d21ef5 100644
--- 
a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
+++ 
b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
@@ -31,7 +31,7 @@ public interface ManagementServerHostDao extends 
GenericDao<ManagementServerHost
 
     ManagementServerHostVO findByMsid(long msid);
 
-    ManagementServerHostVO findByName(String name);
+    List<ManagementServerHostVO> findAllByName(String name);
 
     int increaseAlertCount(long id);
 
diff --git 
a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
 
b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
index 0eeced4044b..ca3a6155107 100644
--- 
a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
+++ 
b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
@@ -26,6 +26,7 @@ import java.util.TimeZone;
 
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import com.cloud.cluster.ClusterInvalidSessionException;
 import org.apache.cloudstack.management.ManagementServerHost;
@@ -77,29 +78,13 @@ public class ManagementServerHostDaoImpl extends 
GenericDaoBase<ManagementServer
     }
 
     @Override
-    public ManagementServerHostVO findByName(String name) {
-        if (name == null || name.trim().isEmpty()) {
-            return null;
+    public List<ManagementServerHostVO> findAllByName(String name) {
+        if (StringUtils.isBlank(name)) {
+            return List.of();
         }
-
         SearchCriteria<ManagementServerHostVO> sc = NameSearch.create();
         sc.setParameters("name", name);
-        // Only search for active (non-removed) entries to avoid 
non-deterministic results
-        // when multiple removed entries exist for the same hostname
-        sc.addAnd("removed", SearchCriteria.Op.NULL);
-
-        List<ManagementServerHostVO> l = listBy(sc);
-        if (l != null && l.size() > 0) {
-            if (l.size() > 1) {
-                s_logger.error(String.format(
-                    "Data corruption detected: Found %d active entries for 
hostname '%s'. " +
-                    "This should never happen and indicates duplicate mshost 
records.",
-                    l.size(), name));
-            }
-            return l.get(0);
-        }
-
-        return null;
+        return listBy(sc);
     }
 
     @Override
diff --git 
a/framework/cluster/src/test/java/com/cloud/cluster/dao/ManagementServerHostDaoImplTest.java
 
b/framework/cluster/src/test/java/com/cloud/cluster/dao/ManagementServerHostDaoImplTest.java
index 1f284cd55a8..9fa0660c1cb 100644
--- 
a/framework/cluster/src/test/java/com/cloud/cluster/dao/ManagementServerHostDaoImplTest.java
+++ 
b/framework/cluster/src/test/java/com/cloud/cluster/dao/ManagementServerHostDaoImplTest.java
@@ -22,7 +22,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
 
-import static org.junit.Assert.assertNull;
+import java.util.List;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Unit tests for ManagementServerHostDaoImpl focusing on the new findByName 
method added in PR #641.
@@ -39,26 +40,26 @@ public class ManagementServerHostDaoImplTest {
 
     @Test
     public void testFindByName_ReturnsNullForNullHostname() {
-        ManagementServerHostVO result = dao.findByName(null);
-        assertNull("Result should be null for null hostname", result);
+        List<ManagementServerHostVO> result = dao.findAllByName(null);
+        assertEquals(0, result.size());
     }
 
     @Test
     public void testFindByName_ReturnsNullForEmptyHostname() {
-        ManagementServerHostVO result = dao.findByName("");
-        assertNull("Result should be null for empty hostname", result);
+        List<ManagementServerHostVO> result = dao.findAllByName("");
+        assertEquals(0, result.size());
     }
 
     @Test
     public void testFindByName_ReturnsNullForWhitespaceHostname() {
-        ManagementServerHostVO result = dao.findByName("   ");
-        assertNull("Result should be null for whitespace-only hostname", 
result);
+        List<ManagementServerHostVO> result = dao.findAllByName("   ");
+        assertEquals(0, result.size());
     }
 
     @Test
     public void testFindByName_ReturnsNullForTabAndSpaceHostname() {
-        ManagementServerHostVO result = dao.findByName(" \t  ");
-        assertNull("Result should be null for tab/space-only hostname", 
result);
+        List<ManagementServerHostVO> result = dao.findAllByName(" \t  ");
+        assertEquals(0, result.size());
     }
 
     /**

Reply via email to