diff --git a/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index e9f0d5f58e4..927637ab918 100644 --- a/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -63,6 +63,7 @@ import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.UUID; @@ -72,6 +73,10 @@ import static com.cloud.configuration.ConfigurationManagerImpl.ADD_HOST_ON_SERVI public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(LibvirtServerDiscoverer.class); private final int _waitTime = 5; /* wait for 5 minutes */ + + private final static HashSet COMPATIBLE_HOST_OSES = new HashSet<>(Arrays.asList("Rocky", "Rocky Linux", + "Red", "Red Hat Enterprise Linux", "Oracle", "Oracle Linux Server", "AlmaLinux")); + private String _kvmPrivateNic; private String _kvmPublicNic; private String _kvmGuestNic; @@ -470,7 +475,7 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements _hostDao.loadDetails(oneHost); String hostOsInCluster = oneHost.getDetail("Host.OS"); String hostOs = ssCmd.getHostDetails().get("Host.OS"); - if (!hostOsInCluster.equalsIgnoreCase(hostOs)) { + if (!isHostOsCompatibleWithOtherHost(hostOsInCluster, hostOs)) { String msg = String.format("host: %s with hostOS, \"%s\"into a cluster, in which there are \"%s\" hosts added", firstCmd.getPrivateIpAddress(), hostOs, hostOsInCluster); if (hostOs != null && hostOs.startsWith(hostOsInCluster)) { s_logger.warn(String.format("Adding %s. This may or may not be ok!", msg)); @@ -485,6 +490,17 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements return _resourceMgr.fillRoutingHostVO(host, ssCmd, getHypervisorType(), host.getDetails(), null); } + protected boolean isHostOsCompatibleWithOtherHost(String hostOsInCluster, String hostOs) { + if (hostOsInCluster.equalsIgnoreCase(hostOs)) { + return true; + } + if (COMPATIBLE_HOST_OSES.contains(hostOsInCluster) && COMPATIBLE_HOST_OSES.contains(hostOs)) { + s_logger.info(String.format("The host OS (%s) is compatible with the existing host OS (%s) in the cluster.", hostOs, hostOsInCluster)); + return true; + } + return false; + } + @Override public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { // TODO Auto-generated method stub diff --git a/server/src/test/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscovererTest.java b/server/src/test/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscovererTest.java new file mode 100644 index 00000000000..aaf5a04b74a --- /dev/null +++ b/server/src/test/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscovererTest.java @@ -0,0 +1,54 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.hypervisor.kvm.discoverer; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class LibvirtServerDiscovererTest { + + @Spy + private LibvirtServerDiscoverer libvirtServerDiscoverer; + + @Test + public void validateCompatibleOses() { + validateCompatibleOs("Rocky Linux", "Rocky Linux", true); + validateCompatibleOs("Rocky", "Rocky Linux", true); + validateCompatibleOs("Red", "Red Hat Enterprise Linux", true); + validateCompatibleOs("Oracle", "Oracle Linux Server", true); + validateCompatibleOs("Rocky Linux", "Red Hat Enterprise Linux", true); + validateCompatibleOs("AlmaLinux", "Red Hat Enterprise Linux", true); + + validateCompatibleOs("Windows", "Rocky Linux", false); + validateCompatibleOs("SUSE", "Rocky Linux", false); + } + + private void validateCompatibleOs(String hostOsInCluster, String hostOs, boolean expected) { + if (expected) { + Assert.assertTrue(libvirtServerDiscoverer.isHostOsCompatibleWithOtherHost(hostOsInCluster, hostOs)); + } else { + Assert.assertFalse(libvirtServerDiscoverer.isHostOsCompatibleWithOtherHost(hostOsInCluster, hostOs)); + } + } +}