From 98d3231dbf66bb88ff1ddaeb89064bf1170b3eb3 Mon Sep 17 00:00:00 2001 From: davidjumani Date: Wed, 18 Aug 2021 13:33:03 +0530 Subject: [PATCH] Adding support for RHEL8 binary-compatible variants (#5158) * Adding support for RHEL binary-compatible variants * Skip ipmi related tests * Fixing security_groups.py --- python/lib/cloudutils/serviceConfig.py | 34 ------------- python/lib/cloudutils/utilities.py | 50 ++++++++++--------- scripts/vm/network/security_group.py | 2 +- .../smoke/test_deploy_vm_iso_uefi.py | 10 ++-- test/integration/smoke/test_hostha_kvm.py | 20 ++++++-- .../smoke/test_outofbandmanagement.py | 14 +++++- 6 files changed, 63 insertions(+), 67 deletions(-) diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index 8294914e90e..9d253a1fab5 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -23,38 +23,6 @@ from .configFileOps import configFileOps import os import shutil -# exit() error constants -Unknown = 0 -CentOS6 = 1 -CentOS7 = 2 -CentOS8 = 3 -Ubuntu = 4 -RHEL6 = 5 -RHEL7 = 6 -RHEL8 = 7 -distro = None - -#=================== DISTRIBUTION DETECTION ================= -if os.path.exists("/etc/centos-release"): - version = open("/etc/centos-release").readline() - if version.find("CentOS release 6") != -1: - distro = CentOS6 - elif version.find("CentOS Linux release 7") != -1: - distro = CentOS7 - elif version.find("CentOS Linux release 8") != -1: - distro = CentOS8 -elif os.path.exists("/etc/redhat-release"): - version = open("/etc/redhat-release").readline() - if version.find("Red Hat Enterprise Linux Server release 6") != -1: - distro = RHEL6 - elif version.find("Red Hat Enterprise Linux Server 7") != -1: - distro = RHEL7 - elif version.find("Red Hat Enterprise Linux Server 8") != -1: - distro = RHEL8 -elif os.path.exists("/etc/lsb-release") and "Ubuntu" in open("/etc/lsb-release").read(-1): distro = Ubuntu -else: distro = Unknown -#=================== DISTRIBUTION DETECTION ================= - class serviceCfgBase(object): def __init__(self, syscfg): self.status = None @@ -531,8 +499,6 @@ class libvirtConfigRedhat(serviceCfgBase): configureLibvirtConfig(self.syscfg.env.secure, self) cfo = configFileOps("/etc/sysconfig/libvirtd", self) - if distro in (CentOS6,RHEL6): - cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'") cfo.addEntry("LIBVIRTD_ARGS", "-l") cfo.save() if os.path.exists("/lib/systemd/system/libvirtd.socket"): diff --git a/python/lib/cloudutils/utilities.py b/python/lib/cloudutils/utilities.py index c0a35fea11a..3d186d898ef 100755 --- a/python/lib/cloudutils/utilities.py +++ b/python/lib/cloudutils/utilities.py @@ -5,9 +5,9 @@ # 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 @@ -53,25 +53,25 @@ class bash: except: raise CloudRuntimeException(formatExceptionInfo()) - if not self.success: + if not self.success: logging.debug("Failed to execute:" + self.getErrMsg()) def isSuccess(self): return self.success - + def getStdout(self): return self.stdout.decode('utf-8').strip('\n') - + def getLines(self): return self.stdout.decode('utf-8').strip('\n') def getStderr(self): return self.stderr.decode('utf-8').strip('\n') - + def getErrMsg(self): if self.isSuccess(): return "" - + if self.getStderr() is None or self.getStderr() == "": return self.getStdout() else: @@ -80,11 +80,11 @@ class bash: def initLoging(logFile=None): try: if logFile is None: - logging.basicConfig(level=logging.DEBUG) - else: - logging.basicConfig(filename=logFile, level=logging.DEBUG) + logging.basicConfig(level=logging.DEBUG) + else: + logging.basicConfig(filename=logFile, level=logging.DEBUG) except: - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.DEBUG) def writeProgressBar(msg, result): output = "[%-6s]\n"%"Failed" @@ -100,7 +100,7 @@ def writeProgressBar(msg, result): class UnknownSystemException(Exception): "This Excption is raised if the current operating enviornment is unknown" pass - + class Distribution: def __init__(self): self.distro = "Unknown" @@ -110,11 +110,15 @@ class Distribution: self.distro = "Fedora" elif os.path.exists("/etc/redhat-release"): version = open("/etc/redhat-release").readline() - if version.find("Red Hat Enterprise Linux Server release 6") != -1 or version.find("Scientific Linux release 6") != -1 or version.find("CentOS Linux release 6") != -1 or version.find("CentOS release 6.") != -1: + if (version.find("Red Hat Enterprise Linux Server release 6") != -1 or version.find("Scientific Linux release 6") != -1 or + version.find("CentOS Linux release 6") != -1 or version.find("CentOS release 6.") != -1): self.distro = "RHEL6" - elif version.find("Red Hat Enterprise Linux Server release 7") != -1 or version.find("Scientific Linux release 7") != -1 or version.find("CentOS Linux release 7") != -1 or version.find("CentOS release 7.") != -1: + elif (version.find("Red Hat Enterprise Linux Server release 7") != -1 or version.find("Scientific Linux release 7") != -1 or + version.find("CentOS Linux release 7") != -1 or version.find("CentOS release 7.") != -1): self.distro = "RHEL7" - elif version.find("Red Hat Enterprise Linux Server release 8") != -1 or version.find("Scientific Linux release 8") != -1 or version.find("CentOS Linux release 8") != -1 or version.find("CentOS release 8.") != -1: + elif (version.find("Red Hat Enterprise Linux Server release 8") != -1 or version.find("Scientific Linux release 8") != -1 or + version.find("CentOS Linux release 8") != -1 or version.find("CentOS release 8.") != -1 or + version.find("Linux release 8") != -1): self.distro = "RHEL8" elif version.find("CentOS") != -1: self.distro = "CentOS" @@ -134,17 +138,17 @@ class Distribution: self.distro = "Ubuntu" else: raise UnknownSystemException(distributor) - else: + else: raise UnknownSystemException def getVersion(self): - return self.distro + return self.distro def getRelease(self): return self.release def getArch(self): return self.arch - - + + class serviceOps: pass class serviceOpsRedhat(serviceOps): @@ -161,7 +165,7 @@ class serviceOpsRedhat(serviceOps): def stopService(self, servicename,force=False): if self.isServiceRunning(servicename) or force: return bash("service " + servicename +" stop").isSuccess() - + return True def disableService(self, servicename): result = self.stopService(servicename) @@ -176,13 +180,13 @@ class serviceOpsRedhat(serviceOps): def enableService(self, servicename,forcestart=False): bash("chkconfig --level 2345 " + servicename + " on") return self.startService(servicename,force=forcestart) - + def isKVMEnabled(self): if os.path.exists("/dev/kvm"): return True else: return False - + class serviceOpsUbuntu(serviceOps): def isServiceRunning(self, servicename): try: @@ -202,7 +206,7 @@ class serviceOpsUbuntu(serviceOps): result = self.stopService(servicename) bash("sudo update-rc.d -f " + servicename + " remove") return result - + def startService(self, servicename,force=True): if not self.isServiceRunning(servicename) or force: return bash("sudo /usr/sbin/service " + servicename + " start").isSuccess() diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 6732f642c05..404edd4e94d 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -185,7 +185,7 @@ def destroy_network_rules_for_nic(vm_name, vm_ip, vm_mac, vif, sec_ips): logging.debug("Ignoring failure to delete ebtable rules for vm: " + vm_name) def get_bridge_physdev(brname): - physdev = execute("bridge -o link show | awk '/master %s / && !/^[0-9]+: vnet/ {print $2}' | head -1 | cut -d ':' -f1" % brname) + physdev = execute("bridge -o link show | awk '/master %s / && !/^[0-9]+: vnet/ {print $2}' | head -1 | cut -d ':' -f1 | cut -d '@' -f1" % brname) return physdev.strip() diff --git a/test/integration/smoke/test_deploy_vm_iso_uefi.py b/test/integration/smoke/test_deploy_vm_iso_uefi.py index 7a9f32a02eb..7d3bb7f55fd 100644 --- a/test/integration/smoke/test_deploy_vm_iso_uefi.py +++ b/test/integration/smoke/test_deploy_vm_iso_uefi.py @@ -58,7 +58,7 @@ class TestDeployVMFromISOWithUefi(cloudstackTestCase): if not cls.isUefiEnabledOnAtLeastOnHost(hosts): raise unittest.SkipTest("At least one host should support UEFI") - + cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ # Create service, disk offerings etc @@ -179,12 +179,12 @@ class TestDeployVMFromISOWithUefi(cloudstackTestCase): def checkBootTypeAndMode(self, root, bootmodesecure, isWindowsIso): machine = root.find(".os/type").get("machine") - self.assertEqual(("q35" in machine), True, "The virtual machine is not with UEFI boot type") - bootmode = root.find(".os/loader").get("secure") - - self.assertEqual((bootmode == bootmodesecure), True, "The VM is not in the right boot mode") + if root.find(".os/loader") is not None : + bootmode = root.find(".os/loader").get("secure") + if bootmode is not None : + self.assertEqual((bootmode == bootmodesecure), True, "The VM is not in the right boot mode") if isWindowsIso: disks = root.findall("devices/disk") diff --git a/test/integration/smoke/test_hostha_kvm.py b/test/integration/smoke/test_hostha_kvm.py index a287ecf052f..9b131558dc2 100644 --- a/test/integration/smoke/test_hostha_kvm.py +++ b/test/integration/smoke/test_hostha_kvm.py @@ -209,6 +209,18 @@ class TestHAKVM(cloudstackTestCase): except Exception as e: raise self.skipTest("Failed to deploy VM, skipping kvm host-ha test case") + def skipIfMSIsUnsupported(self) : + os_details = SshClient(self.mgtSvrDetails["mgtSvrIp"], 22, self.mgtSvrDetails["user"], self.mgtSvrDetails["passwd"]).execute \ + ("/usr/share/cloudstack-common/scripts/vm/hypervisor/versions.sh | cut -d '=' -f2") + os = os_details[0].lower() + if 'ubuntu' in os or 'debian' in os : + return + # RHEL < 8 works fine + os_ver = os_details[1].split('.')[0] + if float(os_ver) < 8: + return + self.skipTest("Skipping since RHEL8 / SUSE have known IPMI issues") + @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_disable_oobm_ha_state_ineligible(self): """ @@ -276,10 +288,10 @@ class TestHAKVM(cloudstackTestCase): self.logger.debug("Starting test_hostha_enable_ha_when_host_in_maintenance") self.logger.debug("Pausing to wait for VMs to have finished starting") time.sleep(300) - + # Enable HA self.configureAndEnableHostHa() - + # Prepare for maintenance Host self.setHostToMaintanance(self.host.id) @@ -351,6 +363,7 @@ class TestHAKVM(cloudstackTestCase): Tests degraded HA state when agent is stopped/killed """ + self.skipIfMSIsUnsupported() self.configureAndStartIpmiServer() self.assertIssueCommandState('ON', 'On') self.configureAndEnableHostHa() @@ -387,6 +400,7 @@ class TestHAKVM(cloudstackTestCase): Tests recovery and fencing HA state transitions """ + self.skipIfMSIsUnsupported() self.configureAndStartIpmiServer() self.assertIssueCommandState('ON', 'On') self.configureAndEnableHostHa() @@ -426,7 +440,7 @@ class TestHAKVM(cloudstackTestCase): """ self.logger.debug("Starting test_ha_kvm_host_fencing") - + self.skipIfMSIsUnsupported() self.configureAndStartIpmiServer() self.assertIssueCommandState('ON', 'On') self.configureAndEnableHostHa() diff --git a/test/integration/smoke/test_outofbandmanagement.py b/test/integration/smoke/test_outofbandmanagement.py index ef5bb52ebad..59a6b9f76fc 100644 --- a/test/integration/smoke/test_outofbandmanagement.py +++ b/test/integration/smoke/test_outofbandmanagement.py @@ -42,10 +42,12 @@ class TestOutOfBandManagement(cloudstackTestCase): def setUpClass(cls): testClient = super(TestOutOfBandManagement, cls).getClsTestClient() cls.apiclient = testClient.getApiClient() + cls.mgtSvrDetails = cls.config.__dict__["mgtSvr"][0].__dict__ cls.services = testClient.getParsedTestDataConfig() cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) cls.host = None cls.cleanup = [] + cls.skipIfMSIsUnsupported(cls) # use random port for ipmisim s = socket.socket() @@ -82,7 +84,6 @@ class TestOutOfBandManagement(cloudstackTestCase): self.fakeMsId = random.randint(10000, 99999) * random.randint(10, 20) self.cleanup = [] - def tearDown(self): try: self.dbclient.execute("delete from oobm where port=%d" % self.getIpmiServerPort()) @@ -94,6 +95,17 @@ class TestOutOfBandManagement(cloudstackTestCase): except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) + def skipIfMSIsUnsupported(self) : + os_details = SshClient(self.mgtSvrDetails["mgtSvrIp"], 22, self.mgtSvrDetails["user"], self.mgtSvrDetails["passwd"]).execute \ + ("/usr/share/cloudstack-common/scripts/vm/hypervisor/versions.sh | cut -d '=' -f2") + os = os_details[0].lower() + if 'ubuntu' in os or 'debian' in os : + return + # RHEL < 8 works fine + os_ver = os_details[1].split('.')[0] + if float(os_ver) < 8: + return + self.skipTest(self, reason="Skipping since RHEL8 / SUSE have known IPMI issues") def getFakeMsId(self): return self.fakeMsId