diff --git a/insights/combiners/modinfo.py b/insights/combiners/modinfo.py index 024f9d5099..b63f1e4691 100644 --- a/insights/combiners/modinfo.py +++ b/insights/combiners/modinfo.py @@ -1,14 +1,27 @@ """ -ModInfo -======= +Combiners for the parsers which parse the output of ``modinfo `` +============================================================================= +ModInfo +------- The ModInfo combiner gathers all the ModInfoEach parsers into a dictionary indexed by the module name. +ModulesInfo +----------- +The ModulesInfo combines the collected modules info. +It combines the result of ``KernelModulesInfo``, ``ModInfoI40e``, +``ModInfoIgb``, ``ModInfoIxgbe``, ``ModInfoVeth``, ``ModInfoVmxnet3`` +if they exists. """ from insights.core.plugins import combiner +from insights.parsers import SkipException from insights.parsers.modinfo import ModInfoEach, ModInfoAll +from insights.parsers.modinfo import ( + KernelModulesInfo, ModInfoI40e, ModInfoIgb, ModInfoIxgbe, ModInfoVeth, + ModInfoVmxnet3 +) from insights import SkipComponent from insights.util import deprecated @@ -18,7 +31,7 @@ class ModInfo(dict): """ .. warning:: This combiner is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Combiner for accessing all the modinfo outputs. @@ -78,3 +91,45 @@ def data(self): (dict): Dict with the module name as the key and the module details as the value. """ return self + + +@combiner( + [ + KernelModulesInfo, ModInfoI40e, ModInfoIgb, ModInfoIxgbe, ModInfoVeth, + ModInfoVmxnet3 + ]) +class ModulesInfo(dict): + """ + Combiner to combine the result of KernelModulesInfo which supports filter + and the parsers which only support one single module. It refers + ``KernelModulesInfo`` first. + + Examples: + >>> type(modules_obj) + + >>> 'i40e' in modules_obj + True + >>> 'bnx2x' in modules_obj.retpoline_y + False + + Raises: + SkipException: When content is empty. + + Attributes: + retpoline_y (set): A set of names of the modules with the attribute "retpoline: Y". + retpoline_n (set): A set of names of the modules with the attribute "retpoline: N". + """ + def __init__(self, filtered_modules_info, i40e_info, igb_info, ixgbe_info, veth_info, vmxnet3_info): + self.retpoline_y = set() + self.retpoline_n = set() + if filtered_modules_info: + self.update(filtered_modules_info) + self.retpoline_n = filtered_modules_info.retpoline_n + self.retpoline_y = filtered_modules_info.retpoline_y + for item in filter(None, [i40e_info, igb_info, ixgbe_info, veth_info, vmxnet3_info]): + name = item.module_name + self[name] = item + self.retpoline_y.add(name) if item.get('retpoline') == 'Y' else None + self.retpoline_n.add(name) if item.get('retpoline') == 'N' else None + if not self: + raise SkipException diff --git a/insights/parsers/modinfo.py b/insights/parsers/modinfo.py index 1f0467db87..1bfe0cd34a 100644 --- a/insights/parsers/modinfo.py +++ b/insights/parsers/modinfo.py @@ -1,4 +1,30 @@ """ +Parsers to parse the output of ``modinfo `` +======================================================== + +ModInfoI40e - Command ``modinfo i40e`` +-------------------------------------- + +ModInfoVmxnet3 - Command ``modinfo vmxnet3`` +-------------------------------------------- + +ModInfoIgb - Command ``modinfo igb`` +------------------------------------ + +ModInfoIxgbe - Command ``modinfo ixgbe`` +---------------------------------------- + +ModInfoVeth - Command ``modinfo veth`` +-------------------------------------- + +ModInfoEach - Command ``modinfo *`` +----------------------------------- +for any module listed by ``lsmod`` + +ModInfoAll - Command ``modinfo *(all modules)`` +----------------------------------------------- +for all modules listed by ``lsmod`` + KernelModulesInfo - Command ``modinfo filtered_modules`` -------------------------------------------------------- """ @@ -224,7 +250,7 @@ class ModInfoAll(KernelModulesInfo): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Class to parse the information about all kernel modules, the module info will be stored in dictionary format. @@ -297,7 +323,7 @@ class ModInfoAll(KernelModulesInfo): def __init__(self, *args, **kwargs): deprecated( ModInfoAll, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoAll, self).__init__(*args, **kwargs) @@ -307,7 +333,7 @@ class ModInfoEach(CommandParser, ModInfo): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses the output of ``modinfo %s`` command, where %s is any of the loaded modules. @@ -357,7 +383,7 @@ class ModInfoEach(CommandParser, ModInfo): def __init__(self, *args, **kwargs): deprecated( ModInfoEach, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoEach, self).__init__(*args, **kwargs) @@ -377,7 +403,7 @@ class ModInfoI40e(ModInfoEach): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses output of ``modinfo i40e`` command. Sample ``modinfo i40e`` output:: @@ -425,7 +451,7 @@ class ModInfoI40e(ModInfoEach): def __init__(self, *args, **kwargs): deprecated( ModInfoI40e, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoI40e, self).__init__(*args, **kwargs) @@ -435,7 +461,7 @@ class ModInfoVmxnet3(ModInfoEach): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses output of ``modinfo vmxnet3`` command. Sample ``modinfo vmxnet3`` output:: @@ -472,7 +498,7 @@ class ModInfoVmxnet3(ModInfoEach): def __init__(self, *args, **kwargs): deprecated( ModInfoVmxnet3, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoVmxnet3, self).__init__(*args, **kwargs) @@ -482,7 +508,7 @@ class ModInfoIgb(ModInfoEach): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses output of ``modinfo igb`` command. Sample ``modinfo igb`` output:: @@ -520,7 +546,7 @@ class ModInfoIgb(ModInfoEach): def __init__(self, *args, **kwargs): deprecated( ModInfoIgb, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoIgb, self).__init__(*args, **kwargs) @@ -530,7 +556,7 @@ class ModInfoIxgbe(ModInfoEach): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses output of ``modinfo ixgbe`` command. Sample ``modinfo ixgbe`` output:: @@ -568,7 +594,7 @@ class ModInfoIxgbe(ModInfoEach): def __init__(self, *args, **kwargs): deprecated( ModInfoIxgbe, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoIxgbe, self).__init__(*args, **kwargs) @@ -578,7 +604,7 @@ class ModInfoVeth(ModInfoEach): """ .. warning:: This parser is deprecated, please use - :py:class:`insights.parsers.modinfo.KernelModulesInfo` instead. + :py:class:`insights.combiners.modinfo.ModulesInfo` instead. Parses output of ``modinfo veth`` command. Sample ``modinfo veth`` output:: @@ -608,6 +634,6 @@ class ModInfoVeth(ModInfoEach): def __init__(self, *args, **kwargs): deprecated( ModInfoVeth, - 'Please use the :class:`insights.parsers.modinfo.KernelModulesInfo` instead.' + 'Please use the :class:`insights.combiners.modinfo.ModulesInfo` instead.' ) super(ModInfoVeth, self).__init__(*args, **kwargs) diff --git a/insights/tests/combiners/test_modinfo.py b/insights/tests/combiners/test_modinfo.py index fac496ffb1..9b07b4d45b 100644 --- a/insights/tests/combiners/test_modinfo.py +++ b/insights/tests/combiners/test_modinfo.py @@ -1,5 +1,9 @@ -from insights.parsers.modinfo import ModInfoEach, ModInfoAll -from insights.combiners.modinfo import ModInfo +from insights.parsers.modinfo import ( + ModInfoEach, ModInfoAll, KernelModulesInfo, + ModInfoI40e, ModInfoIgb, ModInfoIxgbe, ModInfoVeth, + ModInfoVmxnet3 +) +from insights.combiners.modinfo import ModInfo, ModulesInfo from insights.tests.parsers.test_modinfo import ( MODINFO_I40E, MODINFO_INTEL, MODINFO_BNX2X, MODINFO_IGB, MODINFO_IXGBE, @@ -210,6 +214,45 @@ def test_modinfo_doc_examples(): modinfo_vmxnet3, modinfo_veth] ) - env = {'modinfo_obj': comb} + modinfo_i40e = ModInfoI40e(context_wrap(MODINFO_I40E)) + modinfo_igb = ModInfoIgb(context_wrap(MODINFO_IGB)) + modinfo_ixgbe = ModInfoIxgbe(context_wrap(MODINFO_IXGBE)) + modinfo_vmxnet3 = ModInfoVmxnet3(context_wrap(MODINFO_VMXNET3)) + modinfo_veth = ModInfoVeth(context_wrap(MODINFO_VETH)) + filter_modules = KernelModulesInfo(context_wrap( + '{0}\n{1}\n{2}'.format( + MODINFO_I40E, + MODINFO_INTEL, + MODINFO_BNX2X) + )) + combiner_obj = ModulesInfo( + filter_modules, modinfo_i40e, modinfo_igb, modinfo_ixgbe, modinfo_vmxnet3, modinfo_veth + ) + env = { + 'modinfo_obj': comb, + 'modules_obj': combiner_obj + } failed, total = doctest.testmod(modinfo, globs=env) assert failed == 0 + + +def test_modules_info(): + modinfo_i40e = ModInfoI40e(context_wrap(MODINFO_I40E)) + modinfo_igb = ModInfoIgb(context_wrap(MODINFO_IGB)) + modinfo_ixgbe = ModInfoIxgbe(context_wrap(MODINFO_IXGBE)) + modinfo_vmxnet3 = ModInfoVmxnet3(context_wrap(MODINFO_VMXNET3)) + modinfo_veth = ModInfoVeth(context_wrap(MODINFO_VETH)) + filter_modules = KernelModulesInfo(context_wrap( + '{0}\n{1}\n{2}'.format( + MODINFO_I40E, + MODINFO_INTEL, + MODINFO_BNX2X) + )) + combiner_obj = ModulesInfo( + filter_modules, modinfo_i40e, modinfo_igb, modinfo_ixgbe, modinfo_vmxnet3, modinfo_veth + ) + assert 'i40e' in combiner_obj + assert combiner_obj['i40e']['signer'] == 'Red Hat Enterprise Linux kernel signing key' + assert len(combiner_obj) == 7 + assert 'abc' not in combiner_obj + assert 'i40e' in combiner_obj.retpoline_y