import rteval-3.5-4.el8

This commit is contained in:
CentOS Sources 2023-05-16 06:03:18 +00:00 committed by Stepan Oksanichenko
parent d26034a5ae
commit a902b70c43
7 changed files with 834 additions and 6 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/rteval-3.4.tar.xz
SOURCES/rteval-3.5.tar.xz

View File

@ -1 +1 @@
0e04e697615aff39a95dfd864c6bf504bf0ac7c4 SOURCES/rteval-3.4.tar.xz
3aee70e8cca181b05b522acab8a44d45fb876e28 SOURCES/rteval-3.5.tar.xz

View File

@ -0,0 +1,165 @@
From 149c119df7c7a8ddfd1abc7a127d536cc0674230 Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Tue, 23 Aug 2022 14:57:37 -0400
Subject: [PATCH 1/3] rteval: Fix "DMI WARNING" when not running as root
In some cases it is not necessary to run as root, for example when
running -Z (--summarize) to summarize an existing report.
In such cases we do not want to see the message:
** DMI WARNING ** Failed to open memory buffer (/dev/mem): Permission denied
The fix here is to surpresses that message.
In addition:
- the unused "config" option to DMIinfo.__init__ is removed
- A few strings are converted to f-strings
- "with" is used to open the xsltfile
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/sysinfo/__init__.py | 6 ++---
rteval/sysinfo/dmi.py | 45 +++++++++++++++++++-------------------
2 files changed, 26 insertions(+), 25 deletions(-)
diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py
index 0436ebb350d9..a4359382f006 100644
--- a/rteval/sysinfo/__init__.py
+++ b/rteval/sysinfo/__init__.py
@@ -42,7 +42,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology,
self.__logger = logger
KernelInfo.__init__(self, logger=logger)
SystemServices.__init__(self, logger=logger)
- dmi.DMIinfo.__init__(self, config, logger=logger)
+ dmi.DMIinfo.__init__(self, logger=logger)
CPUtopology.__init__(self)
OSInfo.__init__(self, logger=logger)
cmdlineInfo.__init__(self, logger=logger)
@@ -80,8 +80,8 @@ if __name__ == "__main__":
cfg.installdir = "."
si = SystemInfo(cfg, logger=l)
- print("\tRunning on %s" % si.get_base_os())
- print("\tNUMA nodes: %d" % si.mem_get_numa_nodes())
+ print(f"\tRunning on {si.get_base_os()}")
+ print(f"\tNUMA nodes: {si.mem_get_numa_nodes()}")
print("\tMemory available: %03.2f %s\n" % si.mem_get_size())
print("\tServices: ")
diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py
index 80cf3c723b36..5965c128c093 100644
--- a/rteval/sysinfo/dmi.py
+++ b/rteval/sysinfo/dmi.py
@@ -1,6 +1,4 @@
#
-# dmi.py - class to wrap DMI Table information
-#
# Copyright 2009 - 2013 Clark Williams <williams@redhat.com>
# Copyright 2009 - 2013 David Sommerseth <davids@redhat.com>
#
@@ -24,6 +22,7 @@
# including keys needed to generate an equivalently functional executable
# are deemed to be part of the source code.
#
+""" dmi.py class to wrap DMI Table Information """
import sys
import os
@@ -52,16 +51,18 @@ def ProcessWarnings():
if warnings is None:
return
+ ignore1 = '/dev/mem: Permission denied'
+ ignore2 = 'No SMBIOS nor DMI entry point found, sorry.'
+ ignore3 = 'Failed to open memory buffer (/dev/mem): Permission denied'
+ ignore = (ignore1, ignore2, ignore3)
for warnline in warnings.split('\n'):
# Ignore these warnings, as they are "valid" if not running as root
- if warnline == '/dev/mem: Permission denied':
- continue
- if warnline == 'No SMBIOS nor DMI entry point found, sorry.':
+ if warnline in ignore:
continue
# All other warnings will be printed
if len(warnline) > 0:
- print("** DMI WARNING ** %s" % warnline)
+ print(f"** DMI WARNING ** {warnline}")
dmidecode.clear_warnings()
@@ -69,8 +70,7 @@ def ProcessWarnings():
class DMIinfo:
'''class used to obtain DMI info via python-dmidecode'''
- # TODO: Remove unnecessary config
- def __init__(self, config, logger):
+ def __init__(self, logger):
self.__version = '0.5'
if not dmidecode_loaded:
@@ -83,22 +83,24 @@ class DMIinfo:
self.__xsltparser = self.__load_xslt('rteval_dmi.xsl')
- def __load_xslt(self, fname):
- xsltfile = None
+ @staticmethod
+ def __load_xslt(fname):
+ xsltf = None
if os.path.exists(fname):
- xsltfile = open(fname, "r")
- elif rtevalConfig.default_config_search([fname], os.path.isfile):
- xsltfile = open(rtevalConfig.default_config_search([fname], os.path.isfile), "r")
-
- if xsltfile:
- xsltdoc = lxml.etree.parse(xsltfile)
- ret = lxml.etree.XSLT(xsltdoc)
- xsltfile.close()
+ xsltf = fname
+ else:
+ xsltf = rtevalConfig.default_config_search([fname], os.path.isfile)
+
+ if xsltf:
+ with open(xsltf, "r") as xsltfile:
+ xsltdoc = lxml.etree.parse(xsltfile)
+ ret = lxml.etree.XSLT(xsltdoc)
return ret
raise RuntimeError(f'Could not locate XSLT template for DMI data ({fname})')
def MakeReport(self):
+ """ Add DMI information to final report """
rep_n = libxml2.newNode("DMIinfo")
rep_n.newProp("version", self.__version)
if self.__fake:
@@ -113,7 +115,7 @@ class DMIinfo:
return rep_n
def unit_test(rootdir):
- """ unit_test for dmi.py, looks a little crufty! """
+ """ unit_test for dmi.py """
class UnittestConfigDummy:
def __init__(self, rootdir):
@@ -132,15 +134,14 @@ def unit_test(rootdir):
log = Log()
log.SetLogVerbosity(Log.DEBUG|Log.INFO)
- cfg = UnittestConfigDummy(rootdir)
- d = DMIinfo(cfg, log)
+ d = DMIinfo(log)
dx = d.MakeReport()
x = libxml2.newDoc("1.0")
x.setRootElement(dx)
x.saveFormatFileEnc("-", "UTF-8", 1)
return 0
except Exception as e:
- print("** EXCEPTION: %s" % str(e))
+ print(f"** EXCEPTION: {str(e)}")
return 1
if __name__ == '__main__':
--
2.37.3

View File

@ -0,0 +1,54 @@
From eacf0f1e55fa0e7217133172808bfef2c59242fb Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Thu, 2 Feb 2023 00:47:31 -0500
Subject: [PATCH] rteval: Catch failures in python-dmidecode
python-dmidecode can generate incorrect xml,
namely Attribute unit redefined
Although useful, the dmidecode is not critical to rteval reporting.
Therefore catch this, and first see if we can at least query the bios.
If that works report the bios instead of all, and if that
doesn't work, just continue without the dmidecode report.
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/sysinfo/dmi.py | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py
index 83f347623b58..89a7faae06b1 100644
--- a/rteval/sysinfo/dmi.py
+++ b/rteval/sysinfo/dmi.py
@@ -79,6 +79,7 @@ class DMIinfo:
def __init__(self, logger=None):
self.__version = '0.6'
+ self._log = logger
if not dmidecode_avail:
logger.log(Log.DEBUG, "DMI info unavailable, ignoring DMI tables")
@@ -115,7 +116,18 @@ class DMIinfo:
rep_n.newProp("not_available", "1")
else:
self.__dmixml.SetResultType(dmidecode.DMIXML_DOC)
- dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all'))
+ try:
+ dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all'))
+ except Exception as ex1:
+ self._log.log(Log.DEBUG, f'** EXCEPTION {str(ex1)}, will query BIOS only')
+ try:
+ # If we can't query 'all', at least query 'bios'
+ dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('bios'))
+ except Exception as ex2:
+ rep_n.addContent("No DMI tables available")
+ rep_n.newProp("not_available", "1")
+ self._log.log(Log.DEBUG, f'** EXCEPTION {str(ex2)}, dmi info will not be reported')
+ return rep_n
resdoc = self.__xsltparser(dmiqry)
dmi_n = xmlout.convert_lxml_to_libxml2_nodes(resdoc.getroot())
rep_n.addChild(dmi_n)
--
2.39.0

View File

@ -0,0 +1,169 @@
From bce23ecc5d8bb6cab86843f7a42164ee44ef091f Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Thu, 27 Oct 2022 11:14:27 -0400
Subject: [PATCH 3/3] rteval: Don't attempt to get DMIinfo if there are dmi
warnings
If the python module dmidecode is available, but produces warnings,
you can get a traceback. This happens on some arm boxes,
as shown in the traceback below.
Fix this by treating any warnings that are not listed in the
ignorable warnings as if dmi info is not available.
Also add logging to dmi.ProcessWarnings()
./rteval-cmd -d10s
** DMI WARNING ** /sys/firmware/efi/systab: SMBIOS entry point missing
got system topology: 1 node system (4 cores per node)
rteval run on 5.19.16-200.fc36.aarch64 started at Fri Oct 21 16:11:51 2022
started 3 loads on 4 cores
started measurement threads on 4 cores
Run duration: 10.0 seconds
stopping run at Fri Oct 21 16:13:26 2022
Traceback (most recent call last):
File "/root/src/rteval/./rteval-cmd", line 402, in <module>
ec = rteval.Measure()
File "/root/src/rteval/rteval/__init__.py", line 286, in Measure
self._report(measure_start, self.__rtevcfg.xslt_report)
File "/root/src/rteval/rteval/rtevalReport.py", line 76, in _report
self.__xmlreport.AppendXMLnodes(self._sysinfo.MakeReport())
File "/root/src/rteval/rteval/sysinfo/__init__.py", line 69, in MakeReport
report_n.addChild(dmi.DMIinfo.MakeReport(self))
File "/root/src/rteval/rteval/sysinfo/dmi.py", line 111, in MakeReport
dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all'))
File "/usr/lib64/python3.10/site-packages/dmidecode.py", line 64, in QuerySection
ret = libxml2.xmlDoc( _obj = xmlapi(query_type='s',
RuntimeError: [src/dmidecodemodule.c:331] Error decoding DMI data
** COLLECTED WARNINGS **
/sys/firmware/efi/systab: SMBIOS entry point missing
** END OF WARNINGS **
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval-cmd | 4 ++--
rteval/sysinfo/__init__.py | 2 +-
rteval/sysinfo/dmi.py | 34 +++++++++++++++++++++-------------
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/rteval-cmd b/rteval-cmd
index 6a928362828f..1e6a7fc86baa 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -210,8 +210,6 @@ def remove_offline(cpulist):
if __name__ == '__main__':
from rteval.sysinfo import dmi
- dmi.ProcessWarnings()
-
# set LD_BIND_NOW to resolve shared library symbols
# note: any string will do, nothing significant about 'rteval'
@@ -261,6 +259,8 @@ if __name__ == '__main__':
| (rtevcfg.debugging and Log.DEBUG)
logger.SetLogVerbosity(loglev)
+ dmi.ProcessWarnings(logger=logger)
+
# Load modules
loadmods = LoadModules(config, logger=logger)
measuremods = MeasurementModules(config, logger=logger)
diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py
index bb1d00810856..5767e5b7f6fe 100644
--- a/rteval/sysinfo/__init__.py
+++ b/rteval/sysinfo/__init__.py
@@ -49,7 +49,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology,
NetworkInfo.__init__(self, logger=logger)
# Parse initial DMI decoding errors
- dmi.ProcessWarnings()
+ dmi.ProcessWarnings(logger=logger)
# Parse CPU info
CPUtopology._parse(self)
diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py
index 5965c128c093..83f347623b58 100644
--- a/rteval/sysinfo/dmi.py
+++ b/rteval/sysinfo/dmi.py
@@ -1,6 +1,7 @@
#
# Copyright 2009 - 2013 Clark Williams <williams@redhat.com>
# Copyright 2009 - 2013 David Sommerseth <davids@redhat.com>
+# Copyright 2022 John Kacur <jkacur@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -34,14 +35,19 @@ from rteval import rtevalConfig
try:
import dmidecode
- dmidecode_loaded = True
+ dmidecode_avail = True
except ModuleNotFoundError:
- dmidecode_loaded = False
+ dmidecode_avail = False
-def ProcessWarnings():
+def set_dmidecode_avail(val):
+ """ Used to set global variable dmidecode_avail from a function """
+ global dmidecode_avail
+ dmidecode_avail = val
+
+def ProcessWarnings(logger=None):
""" Process Warnings from dmidecode """
- if not dmidecode_loaded:
+ if not dmidecode_avail:
return
if not hasattr(dmidecode, 'get_warnings'):
@@ -62,7 +68,8 @@ def ProcessWarnings():
# All other warnings will be printed
if len(warnline) > 0:
- print(f"** DMI WARNING ** {warnline}")
+ logger.log(Log.DEBUG, f"** DMI WARNING ** {warnline}")
+ set_dmidecode_avail(False)
dmidecode.clear_warnings()
@@ -70,11 +77,11 @@ def ProcessWarnings():
class DMIinfo:
'''class used to obtain DMI info via python-dmidecode'''
- def __init__(self, logger):
- self.__version = '0.5'
+ def __init__(self, logger=None):
+ self.__version = '0.6'
- if not dmidecode_loaded:
- logger.log(Log.DEBUG|Log.WARN, "No dmidecode module found, ignoring DMI tables")
+ if not dmidecode_avail:
+ logger.log(Log.DEBUG, "DMI info unavailable, ignoring DMI tables")
self.__fake = True
return
@@ -127,14 +134,15 @@ def unit_test(rootdir):
self.__dict__[k] = self.config[k]
try:
- ProcessWarnings()
+ log = Log()
+ log.SetLogVerbosity(Log.DEBUG|Log.INFO)
+
+ ProcessWarnings(logger=log)
if os.getuid() != 0:
print("** ERROR ** Must be root to run this unit_test()")
return 1
- log = Log()
- log.SetLogVerbosity(Log.DEBUG|Log.INFO)
- d = DMIinfo(log)
+ d = DMIinfo(logger=log)
dx = d.MakeReport()
x = libxml2.newDoc("1.0")
x.setRootElement(dx)
--
2.37.3

View File

@ -0,0 +1,399 @@
From d0552193364d160252d117c5bf2e298a31550e3c Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Mon, 10 Oct 2022 09:49:47 -0400
Subject: [PATCH] rteval: Replace python-ethtool with inline code
This patch adds the file newnet.py to replace the use of python-ethtool
The information it generates will appear in the summary.xml
You can also test the functionality by running
python rteval/sysinfo/newnet.py
Signed-off-by: John Kacur <jkacur@redhat.com>
- V2 Add SPDX license identifier
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/sysinfo/__init__.py | 3 +-
rteval/sysinfo/network.py | 117 -------------------
rteval/sysinfo/newnet.py | 225 +++++++++++++++++++++++++++++++++++++
3 files changed, 227 insertions(+), 118 deletions(-)
delete mode 100644 rteval/sysinfo/network.py
create mode 100644 rteval/sysinfo/newnet.py
diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py
index a4359382f006..bb1d00810856 100644
--- a/rteval/sysinfo/__init__.py
+++ b/rteval/sysinfo/__init__.py
@@ -32,7 +32,7 @@ from rteval.sysinfo.services import SystemServices
from rteval.sysinfo.cputopology import CPUtopology
from rteval.sysinfo.memory import MemoryInfo
from rteval.sysinfo.osinfo import OSInfo
-from rteval.sysinfo.network import NetworkInfo
+from rteval.sysinfo.newnet import NetworkInfo
from rteval.sysinfo.cmdline import cmdlineInfo
from rteval.sysinfo import dmi
@@ -46,6 +46,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology,
CPUtopology.__init__(self)
OSInfo.__init__(self, logger=logger)
cmdlineInfo.__init__(self, logger=logger)
+ NetworkInfo.__init__(self, logger=logger)
# Parse initial DMI decoding errors
dmi.ProcessWarnings()
diff --git a/rteval/sysinfo/network.py b/rteval/sysinfo/network.py
deleted file mode 100644
index ce9989a1240b..000000000000
--- a/rteval/sysinfo/network.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2009 - 2013 David Sommerseth <davids@redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# For the avoidance of doubt the "preferred form" of this code is one which
-# is in an open unpatent encumbered format. Where cryptographic key signing
-# forms part of the process of creating an executable the information
-# including keys needed to generate an equivalently functional executable
-# are deemed to be part of the source code.
-#
-
-import ethtool, libxml2
-
-class NetworkInfo(object):
- def __init__(self):
- pass
-
- def net_GetDefaultGW(self):
- # Get the interface name for the IPv4 default gw
- route = open('/proc/net/route')
- defgw4 = None
- if route:
- rl = route.readline()
- while rl != '' :
- rl = route.readline()
- splt = rl.split("\t")
- # Only catch default route
- if len(splt) > 2 and splt[2] != '00000000' and splt[1] == '00000000':
- defgw4 = splt[0]
- break
- route.close()
- return (defgw4, None) # IPv6 gw not yet implemented
-
- def MakeReport(self):
- ncfg_n = libxml2.newNode("NetworkConfig")
- (defgw4, defgw6) = self.net_GetDefaultGW()
-
- # Make an interface tag for each device found
- if hasattr(ethtool, 'get_interfaces_info'):
- # Using the newer python-ethtool API (version >= 0.4)
- for dev in ethtool.get_interfaces_info(ethtool.get_devices()):
- if dev.device == 'lo':
- continue
-
- intf_n = libxml2.newNode('interface')
- intf_n.newProp('device', dev.device)
- intf_n.newProp('hwaddr', dev.mac_address)
- ncfg_n.addChild(intf_n)
-
- # Protcol configurations
- if dev.ipv4_address:
- ipv4_n = libxml2.newNode('IPv4')
- ipv4_n.newProp('ipaddr', dev.ipv4_address)
- ipv4_n.newProp('netmask', str(dev.ipv4_netmask))
- ipv4_n.newProp('broadcast', dev.ipv4_broadcast)
- ipv4_n.newProp('defaultgw', (defgw4 == dev.device) and '1' or '0')
- intf_n.addChild(ipv4_n)
-
- for ip6 in dev.get_ipv6_addresses():
- ipv6_n = libxml2.newNode('IPv6')
- ipv6_n.newProp('ipaddr', ip6.address)
- ipv6_n.newProp('netmask', str(ip6.netmask))
- ipv6_n.newProp('scope', ip6.scope)
- intf_n.addChild(ipv6_n)
-
- else: # Fall back to older python-ethtool API (version < 0.4)
- ifdevs = ethtool.get_active_devices()
- ifdevs.remove('lo')
- ifdevs.sort()
-
- for dev in ifdevs:
- intf_n = libxml2.newNode('interface')
- intf_n.newProp('device', dev.device)
- intf_n.newProp('hwaddr', dev.mac_address)
- ncfg_n.addChild(intf_n)
-
- ipv4_n = libxml2.newNode('IPv4')
- ipv4_n.newProp('ipaddr', ethtool.get_ipaddr(dev))
- ipv4_n.newProp('netmask', str(ethtool.get_netmask(dev)))
- ipv4_n.newProp('defaultgw', (defgw4 == dev) and '1' or '0')
- intf_n.addChild(ipv4_n)
-
- return ncfg_n
-
-
-def unit_test(rootdir):
- import sys
- try:
- net = NetworkInfo()
- doc = libxml2.newDoc('1.0')
- cfg = net.MakeReport()
- doc.setRootElement(cfg)
- doc.saveFormatFileEnc('-', 'UTF-8', 1)
-
- except Exception as e:
- import traceback
- traceback.print_exc(file=sys.stdout)
- print("** EXCEPTION %s", str(e))
- return 1
-
-if __name__ == '__main__':
- unit_test(None)
-
diff --git a/rteval/sysinfo/newnet.py b/rteval/sysinfo/newnet.py
new file mode 100644
index 000000000000..63417d9e59f1
--- /dev/null
+++ b/rteval/sysinfo/newnet.py
@@ -0,0 +1,225 @@
+''' Module to obtain network information for the rteval report '''
+#
+# Copyright 2022 John Kacur <jkacur@redhat.com
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+import os
+import socket
+import ipaddress
+import sys
+import libxml2
+from rteval.Log import Log
+
+def get_active_devices():
+ ''' returns a list of active network devices, similar to ethtool '''
+ ret = []
+
+ for device in socket.if_nameindex():
+ ret.append(device[1])
+
+ return ret
+
+def compress_iv6(addr):
+ ''' inserts colons into an ipv6address and returns it in compressed form '''
+ retaddr = ''
+ # Insert colons into the number
+ for i in range(4,33,4):
+ if i == 32:
+ retaddr += addr[i-4:i]
+ else:
+ retaddr += addr[i-4:i] + ':'
+ addr = ipaddress.IPv6Network(retaddr)
+ retaddr = str(ipaddress.IPv6Address(retaddr))
+ return retaddr
+
+def get_defaultgw():
+ ''' return the ipv4address of the default gateway '''
+ defaultgw = None
+ with open('/proc/net/route') as f:
+ line = f.readline().strip()
+ while len(line) > 0:
+ (iface, dest, gateway, _, _, _, _, _, _, _, _) = line.split()
+ if iface == 'Iface':
+ line = f.readline().strip()
+ continue
+ if dest == '00000000' and gateway != '00000000':
+ addr = int(gateway, base=16)
+ defaultgw = str(ipaddress.IPv4Address(socket.ntohl(addr)))
+ return defaultgw
+ line = f.readline().strip()
+ return defaultgw
+
+class IPv6Addresses():
+ ''' Obtains a list of IPv6 addresses from the proc file system '''
+
+ def __init__(self):
+ self.data = {}
+ IPv6Addresses.load(self)
+
+ def __contains__(self, dev):
+ return dev in self.data
+
+ def __getitem__(self, dev):
+ return self.data.get(dev, None)
+
+ def __iter__(self):
+ return iter(self.data)
+
+ def load(self):
+ '''
+ Called by init to load the self.data dictionary with device keys
+ and a list of ipv6addresses
+ '''
+ MYP = '/proc/net/if_inet6'
+ with open(MYP, 'r') as f:
+ mystr = f.readline().strip()
+ while len(mystr) > 0:
+ ipv6addr , _, _, _, _, intf = mystr.split()
+ ipv6addr = compress_iv6(ipv6addr)
+ if intf == 'lo':
+ mystr = f.readline().strip()
+ continue
+ if intf not in self.data:
+ self.data[intf] = [ipv6addr]
+ else:
+ self.data[intf].append(ipv6addr)
+ mystr = f.readline().strip()
+
+class IPv4Addresses():
+ ''' Obtains a list of IPv4 addresses from the proc file system '''
+
+ def __init__(self):
+ self.data = {}
+ IPv4Addresses.load(self)
+
+ def __contains__(self, dev):
+ return dev in self.data
+
+ def __getitem__(self, dev):
+ return self.data[dev]
+
+ def __iter__(self):
+ return iter(self.data)
+
+ def load(self):
+ '''
+ Called by init to load the self.data dictionary with
+ device keys, and value consisting of a list of
+ ipv4address, netmask and broadcast address
+ '''
+ MYP = '/proc/net/route'
+ with open(MYP, 'r') as f:
+ mystr = f.readline().strip()
+ while len(mystr) > 0:
+ intf, dest, _, _, _, _, _, mask, _, _, _ = mystr.split()
+ # Skip over the head of the table an the gateway line
+ if intf == "Iface" or dest == '00000000':
+ mystr = f.readline().strip()
+ continue
+ d1 = int(dest, base=16)
+ m1 = int(mask, base=16)
+ addr = str(ipaddress.IPv4Address(socket.ntohl(d1)))
+ netmask = str(ipaddress.IPv4Address(socket.ntohl(m1)))
+ addr_with_mask = ipaddress.ip_network(addr + '/' + netmask)
+ broadcast = str(addr_with_mask.broadcast_address)
+ if intf not in self.data:
+ self.data[intf] = [(addr, netmask, broadcast)]
+ else:
+ self.data[intf].append((addr, netmask, broadcast))
+ mystr = f.readline().strip()
+
+
+class MacAddresses():
+ ''' Obtains a list of hardware addresses of network devices '''
+
+ def __init__(self):
+ self.mac_address = {}
+ self.path = None
+ MacAddresses.load(self)
+
+ def load(self):
+ '''
+ called by init to load self.mac_address as a dictionary of
+ device keys, and mac or hardware addresses as values
+ '''
+ nics = get_active_devices()
+ for nic in nics:
+ self.path = f'/sys/class/net/{nic}'
+ hwaddr = MacAddresses.set_val(self, 'address')
+ self.mac_address[nic] = hwaddr
+
+ def set_val(self, val):
+ ''' Return the result of reading self.path/val '''
+ val_path = f'{self.path}/{val}'
+ if os.path.exists(val_path):
+ with open(val_path, 'r') as f:
+ return f.readline().strip()
+ return None
+
+ def __contains__(self, dev):
+ return dev in self.mac_address
+
+ def __getitem__(self, dev):
+ return self.mac_address[dev]
+
+ def __iter__(self):
+ return iter(self.mac_address)
+
+class NetworkInfo():
+ ''' Creates an xml report of the network for rteval '''
+
+ def __init__(self, logger):
+ self.defgw4 = get_defaultgw()
+ self.__logger = logger
+
+ def MakeReport(self):
+ ''' Make an xml report for rteval '''
+ ncfg_n = libxml2.newNode("NetworkConfig")
+ defgw4 = self.defgw4
+
+ mads = MacAddresses()
+ for device in mads:
+ if device == 'lo':
+ continue
+ intf_n = libxml2.newNode('interface')
+ intf_n.newProp('device', device)
+ intf_n.newProp('hwaddr', mads[device])
+ ncfg_n.addChild(intf_n)
+
+ ipv4ads = IPv4Addresses()
+ ipv6ads = IPv6Addresses()
+ for dev in ipv4ads:
+ if dev != device:
+ continue
+ for lelem in ipv4ads[dev]:
+ ipv4_n = libxml2.newNode('IPv4')
+ (ipaddr, netmask, broadcast) = lelem
+ ipv4_n.newProp('ipaddr', ipaddr)
+ ipv4_n.newProp('netmask', netmask)
+ ipv4_n.newProp('broadcast', broadcast)
+ ipv4_n.newProp('defaultgw', (defgw4 == ipaddr) and '1' or '0')
+ intf_n.addChild(ipv4_n)
+ if ipv6ads[dev]:
+ for lelem in ipv6ads[dev]:
+ ipv6_n = libxml2.newNode('IPv6')
+ ipaddr = lelem
+ ipv6_n.newProp('ipaddr', ipaddr)
+ intf_n.addChild(ipv6_n)
+ return ncfg_n
+
+if __name__ == "__main__":
+
+ try:
+ log = Log()
+ log.SetLogVerbosity(Log.DEBUG|Log.INFO)
+ net = NetworkInfo(logger=log)
+ doc = libxml2.newDoc('1.0')
+ cfg = net.MakeReport()
+ doc.setRootElement(cfg)
+ doc.saveFormatFileEnc('-', 'UTF-8', 1)
+
+ except Exception as e:
+ import traceback
+ traceback.print_exc(file=sys.stdout)
+ print(f"** EXCEPTION {str(e)}")
--
2.37.3

View File

@ -1,6 +1,6 @@
Name: rteval
Version: 3.4
Release: 2%{?dist}
Version: 3.5
Release: 4%{?dist}
Summary: Utility to evaluate system suitability for RT Linux
Group: Development/Tools
@ -11,9 +11,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: python3-devel
Requires: platform-python
Requires: python3-ethtool
Requires: python3-lxml
Requires: python3-libxml2
Requires: python3-dmidecode >= 3.10
Requires: python3-requests
Requires: rt-tests >= 1.5-11
Requires: rteval-loads >= 1.6-2
Requires: sysstat
@ -32,6 +33,10 @@ Requires: libmpc libmpc-devel
Obsoletes: rteval-common <= 3.1
#Patches
Patch1: rteval-Replace-python-ethtool-with-inline-code.patch
Patch2: Fix-DMI-WARNING-when-not-running-as-root.patch
Patch3: rteval-Don-t-attempt-to-get-DMIinfo-if-there-are-dmi.patch
Patch4: rteval-Catch-failures-in-python-dmidecode.patch
%description
The rteval script is a utility for measuring various aspects of
@ -44,6 +49,10 @@ to the screen.
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
%{__python3} setup.py build
@ -62,7 +71,6 @@ to the screen.
%{python3_sitelib}/rteval/rtevalXMLRPC.py*
%{python3_sitelib}/rteval/version.py*
%{python3_sitelib}/rteval/Log.py*
%{python3_sitelib}/rteval/misc.py*
%{python3_sitelib}/rteval/systopology.py*
%{_mandir}/man8/rteval.8.gz
%config(noreplace) %{_sysconfdir}/rteval.conf
@ -78,6 +86,39 @@ to the screen.
%{python3_sitelib}/rteval/__pycache__/*
%changelog
* Wed Feb 08 2023 John Kacur <jkacur@redhat.com> - 3.5-4
- Add check to catch python-dmidecode if it fails
Resolves: rhbz#2168373
jiraProject == RHELPLAN-148048
* Thu Oct 27 2022 John Kacur <jkacur@redhat.com> - 3.5-3
- Fix "DMI WARNING" when not running as root
- Don't attempt to get DMI info if dmidecode returns warnings
Resolves: rhbz#2136926
* Mon Oct 17 2022 John Kacur <jkacur@redhat.com> - 3.5-2
- Remove dependency on python-ethtool by using inline code
- Add Requires of python-libxml2
Resolves: rhbz#2131377
* Fri Sep 23 2022 John Kacur <jkacur@redhat.com> - 3.5-1
- Rebase to rteval-3.5 upstream
Resolves: rhbz#2119172
* Thu Sep 22 2022 Leah Leshchinsky <lleshchi@redhat.com> - 3.4-5
- Add measurement and load location to run report
Resolves: rhbz#2082260
* Tue Sep 13 2022 John Kacur <jkacur@redhat.com> - 3.4-4
- Make use of systopology instead of misc everywhere
- Allow user to enter compressed form of cpulist
Resolves: rhbz#2121535
* Mon Sep 12 2022 John Kacur <jkacur@redhat.com> - 3.4-3
- Add option for downloading the kernel to compile as a load
- Add a manpage entry for the kernel download option
Resolves: rhbz#2107710
* Tue Jun 28 2022 John Kacur <jkacur@redhat.com> - 3.4-2
- Add back __pycache__ to the rhel-8.7 spec file
Resolves: rhbz#2069354