From d34e7984080bd7b65c9e9961bbd7b22bbd7fce73 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 28 Jul 2025 10:40:30 -0500 Subject: [PATCH 1/6] update --- nodescraper/pluginexecutor.py | 2 ++ nodescraper/plugins/inband/dimm/dimm_collector.py | 4 ++++ nodescraper/plugins/inband/dmesg/dmesg_collector.py | 6 +++++- nodescraper/plugins/inband/kernel/kernel_collector.py | 2 +- nodescraper/plugins/inband/os/os_collector.py | 3 +-- nodescraper/plugins/inband/storage/storage_collector.py | 4 ++++ 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/nodescraper/pluginexecutor.py b/nodescraper/pluginexecutor.py index 178e9bce..00aa5bc2 100644 --- a/nodescraper/pluginexecutor.py +++ b/nodescraper/pluginexecutor.py @@ -240,6 +240,8 @@ def apply_global_args_to_plugin( for key in global_args: if key in ["collection_args", "analysis_args"] and isinstance(plugin_inst, DataPlugin): continue + if key == "skip_sudo" and (global_args[key] or global_args[key] == 1): + global_args["collection_args"]["skip_sudo"] = 1 else: run_args[key] = global_args[key] diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 9d854187..232f5906 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -40,6 +40,10 @@ def collect_data( args=None, ) -> tuple[TaskResult, DimmDataModel | None]: """Collect data on installed DIMMs""" + if args and "skip_sudo" in args.keys() and args["skip_sudo"]: + self.resultmessage = "Skipping sudo plugin" + self.result.status = ExecutionStatus.NOT_RAN + return self.result, None dimm_str = None if self.system_info.os_family == OSFamily.WINDOWS: res = self._run_sut_cmd("wmic memorychip get Capacity") diff --git a/nodescraper/plugins/inband/dmesg/dmesg_collector.py b/nodescraper/plugins/inband/dmesg/dmesg_collector.py index 4f07ba11..2c21ce4f 100644 --- a/nodescraper/plugins/inband/dmesg/dmesg_collector.py +++ b/nodescraper/plugins/inband/dmesg/dmesg_collector.py @@ -24,7 +24,7 @@ # ############################################################################### from nodescraper.base import InBandDataCollector -from nodescraper.enums import EventCategory, EventPriority, OSFamily +from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult from .dmesgdata import DmesgData @@ -67,6 +67,10 @@ def collect_data( Returns: tuple[TaskResult, DmesgData | None]: tuple containing the result of the task and the dmesg data if available """ + if args and "skip_sudo" in args.keys() and args["skip_sudo"]: + self.resultmessage = "Skipping sudo plugin" + self.result.status = ExecutionStatus.NOT_RAN + return self.result, None dmesg_content = self._get_dmesg_content() if dmesg_content: diff --git a/nodescraper/plugins/inband/kernel/kernel_collector.py b/nodescraper/plugins/inband/kernel/kernel_collector.py index 6e9ec256..cdb60c23 100644 --- a/nodescraper/plugins/inband/kernel/kernel_collector.py +++ b/nodescraper/plugins/inband/kernel/kernel_collector.py @@ -53,7 +53,7 @@ def collect_data( "=" )[1] else: - res = self._run_sut_cmd("sh -c 'uname -r'", sudo=True) + res = self._run_sut_cmd("sh -c 'uname -r'") if res.exit_code == 0: kernel = res.stdout diff --git a/nodescraper/plugins/inband/os/os_collector.py b/nodescraper/plugins/inband/os/os_collector.py index 47dadc51..2a95d84f 100644 --- a/nodescraper/plugins/inband/os/os_collector.py +++ b/nodescraper/plugins/inband/os/os_collector.py @@ -84,8 +84,7 @@ def collect_data(self, args=None) -> tuple[TaskResult, OsDataModel | None]: else: PRETTY_STR = "PRETTY_NAME" # noqa: N806 res = self._run_sut_cmd( - f"sh -c '( lsb_release -ds || (cat /etc/*release | grep {PRETTY_STR}) || uname -om ) 2>/dev/null | head -n1'", - sudo=False, + f"sh -c '( lsb_release -ds || (cat /etc/*release | grep {PRETTY_STR}) || uname -om ) 2>/dev/null | head -n1'" ) # search for PRETTY_NAME in res if res.exit_code == 0: diff --git a/nodescraper/plugins/inband/storage/storage_collector.py b/nodescraper/plugins/inband/storage/storage_collector.py index 0e9eb79a..0947e92e 100644 --- a/nodescraper/plugins/inband/storage/storage_collector.py +++ b/nodescraper/plugins/inband/storage/storage_collector.py @@ -39,6 +39,10 @@ class StorageCollector(InBandDataCollector[StorageDataModel, None]): def collect_data(self, args: None = None) -> tuple[TaskResult, StorageDataModel | None]: """read storage usage data""" + if args and "skip_sudo" in args.keys() and args["skip_sudo"]: + self.resultmessage = "Skipping sudo plugin" + self.result.status = ExecutionStatus.NOT_RAN + return self.result, None storage_data = {} if self.system_info.os_family == OSFamily.WINDOWS: res = self._run_sut_cmd( From c7dc5cd1f0d78846cfb0ba4555955eb7c76d907f Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 28 Jul 2025 12:10:23 -0500 Subject: [PATCH 2/6] collector args added to sudo plugins --- nodescraper/pluginexecutor.py | 2 -- .../plugins/inband/dimm/collector_args.py | 31 +++++++++++++++++++ .../plugins/inband/dimm/dimm_collector.py | 4 +-- .../plugins/inband/dimm/dimm_plugin.py | 3 ++ .../plugins/inband/dmesg/collector_args.py | 31 +++++++++++++++++++ .../plugins/inband/dmesg/dmesg_collector.py | 4 +-- .../plugins/inband/dmesg/dmesg_plugin.py | 3 ++ .../plugins/inband/storage/collector_args.py | 31 +++++++++++++++++++ .../inband/storage/storage_collector.py | 4 +-- .../plugins/inband/storage/storage_plugin.py | 3 ++ 10 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 nodescraper/plugins/inband/dimm/collector_args.py create mode 100644 nodescraper/plugins/inband/dmesg/collector_args.py create mode 100644 nodescraper/plugins/inband/storage/collector_args.py diff --git a/nodescraper/pluginexecutor.py b/nodescraper/pluginexecutor.py index 00aa5bc2..178e9bce 100644 --- a/nodescraper/pluginexecutor.py +++ b/nodescraper/pluginexecutor.py @@ -240,8 +240,6 @@ def apply_global_args_to_plugin( for key in global_args: if key in ["collection_args", "analysis_args"] and isinstance(plugin_inst, DataPlugin): continue - if key == "skip_sudo" and (global_args[key] or global_args[key] == 1): - global_args["collection_args"]["skip_sudo"] = 1 else: run_args[key] = global_args[key] diff --git a/nodescraper/plugins/inband/dimm/collector_args.py b/nodescraper/plugins/inband/dimm/collector_args.py new file mode 100644 index 00000000..bae77c86 --- /dev/null +++ b/nodescraper/plugins/inband/dimm/collector_args.py @@ -0,0 +1,31 @@ +############################################################################### +# +# MIT License +# +# Copyright (c) 2025 Advanced Micro Devices, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +############################################################################### + +from nodescraper.models import CollectorArgs + + +class DimmCollectorArgs(CollectorArgs): + skip_sudo = False diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 232f5906..65f95e33 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -40,8 +40,8 @@ def collect_data( args=None, ) -> tuple[TaskResult, DimmDataModel | None]: """Collect data on installed DIMMs""" - if args and "skip_sudo" in args.keys() and args["skip_sudo"]: - self.resultmessage = "Skipping sudo plugin" + if args.skip_sudo: + self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None dimm_str = None diff --git a/nodescraper/plugins/inband/dimm/dimm_plugin.py b/nodescraper/plugins/inband/dimm/dimm_plugin.py index 0e838fea..fa3ee8cb 100644 --- a/nodescraper/plugins/inband/dimm/dimm_plugin.py +++ b/nodescraper/plugins/inband/dimm/dimm_plugin.py @@ -25,6 +25,7 @@ ############################################################################### from nodescraper.base import InBandDataPlugin +from .collector_args import DimmCollectorArgs from .dimm_collector import DimmCollector from .dimmdata import DimmDataModel @@ -35,3 +36,5 @@ class DimmPlugin(InBandDataPlugin[DimmDataModel, None, None]): DATA_MODEL = DimmDataModel COLLECTOR = DimmCollector + + COLLECTOR_ARGS = DimmCollectorArgs diff --git a/nodescraper/plugins/inband/dmesg/collector_args.py b/nodescraper/plugins/inband/dmesg/collector_args.py new file mode 100644 index 00000000..ca7066bf --- /dev/null +++ b/nodescraper/plugins/inband/dmesg/collector_args.py @@ -0,0 +1,31 @@ +############################################################################### +# +# MIT License +# +# Copyright (c) 2025 Advanced Micro Devices, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +############################################################################### + +from nodescraper.models import CollectorArgs + + +class DmesgCollectorArgs(CollectorArgs): + skip_sudo = False diff --git a/nodescraper/plugins/inband/dmesg/dmesg_collector.py b/nodescraper/plugins/inband/dmesg/dmesg_collector.py index 2c21ce4f..1e289e1b 100644 --- a/nodescraper/plugins/inband/dmesg/dmesg_collector.py +++ b/nodescraper/plugins/inband/dmesg/dmesg_collector.py @@ -67,8 +67,8 @@ def collect_data( Returns: tuple[TaskResult, DmesgData | None]: tuple containing the result of the task and the dmesg data if available """ - if args and "skip_sudo" in args.keys() and args["skip_sudo"]: - self.resultmessage = "Skipping sudo plugin" + if args.skip_sudo: + self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None dmesg_content = self._get_dmesg_content() diff --git a/nodescraper/plugins/inband/dmesg/dmesg_plugin.py b/nodescraper/plugins/inband/dmesg/dmesg_plugin.py index 180ae004..76cc696d 100644 --- a/nodescraper/plugins/inband/dmesg/dmesg_plugin.py +++ b/nodescraper/plugins/inband/dmesg/dmesg_plugin.py @@ -26,6 +26,7 @@ from nodescraper.base import InBandDataPlugin from .analyzer_args import DmesgAnalyzerArgs +from .collector_args import DmesgCollectorArgs from .dmesg_analyzer import DmesgAnalyzer from .dmesg_collector import DmesgCollector from .dmesgdata import DmesgData @@ -39,3 +40,5 @@ class DmesgPlugin(InBandDataPlugin[DmesgData, None, DmesgAnalyzerArgs]): COLLECTOR = DmesgCollector ANALYZER = DmesgAnalyzer + + COLLECTOR_ARGS = DmesgCollectorArgs diff --git a/nodescraper/plugins/inband/storage/collector_args.py b/nodescraper/plugins/inband/storage/collector_args.py new file mode 100644 index 00000000..305c91b2 --- /dev/null +++ b/nodescraper/plugins/inband/storage/collector_args.py @@ -0,0 +1,31 @@ +############################################################################### +# +# MIT License +# +# Copyright (c) 2025 Advanced Micro Devices, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +############################################################################### + +from nodescraper.models import CollectorArgs + + +class StorageCollectorArgs(CollectorArgs): + skip_sudo = False diff --git a/nodescraper/plugins/inband/storage/storage_collector.py b/nodescraper/plugins/inband/storage/storage_collector.py index 0947e92e..11fe26d1 100644 --- a/nodescraper/plugins/inband/storage/storage_collector.py +++ b/nodescraper/plugins/inband/storage/storage_collector.py @@ -39,8 +39,8 @@ class StorageCollector(InBandDataCollector[StorageDataModel, None]): def collect_data(self, args: None = None) -> tuple[TaskResult, StorageDataModel | None]: """read storage usage data""" - if args and "skip_sudo" in args.keys() and args["skip_sudo"]: - self.resultmessage = "Skipping sudo plugin" + if args.skip_sudo: + self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None storage_data = {} diff --git a/nodescraper/plugins/inband/storage/storage_plugin.py b/nodescraper/plugins/inband/storage/storage_plugin.py index f0848005..6911936f 100644 --- a/nodescraper/plugins/inband/storage/storage_plugin.py +++ b/nodescraper/plugins/inband/storage/storage_plugin.py @@ -26,6 +26,7 @@ from nodescraper.base import InBandDataPlugin from .analyzer_args import StorageAnalyzerArgs +from .collector_args import StorageCollectorArgs from .storage_analyzer import StorageAnalyzer from .storage_collector import StorageCollector from .storagedata import StorageDataModel @@ -39,3 +40,5 @@ class StoragePlugin(InBandDataPlugin[StorageDataModel, None, StorageAnalyzerArgs COLLECTOR = StorageCollector ANALYZER = StorageAnalyzer + + COLLECTOR_ARGS = StorageCollectorArgs From 545db4783189ef6f5dc6512c7fab09f42347fd63 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 28 Jul 2025 14:20:32 -0500 Subject: [PATCH 3/6] updates to collector args --- nodescraper/plugins/inband/dimm/collector_args.py | 2 +- nodescraper/plugins/inband/dimm/dimm_collector.py | 10 ++++++++-- nodescraper/plugins/inband/dimm/dimm_plugin.py | 2 +- nodescraper/plugins/inband/dmesg/collector_args.py | 2 +- nodescraper/plugins/inband/dmesg/dmesg_plugin.py | 2 +- nodescraper/plugins/inband/storage/collector_args.py | 2 +- nodescraper/plugins/inband/storage/storage_plugin.py | 2 +- 7 files changed, 14 insertions(+), 8 deletions(-) diff --git a/nodescraper/plugins/inband/dimm/collector_args.py b/nodescraper/plugins/inband/dimm/collector_args.py index bae77c86..6e1f6897 100644 --- a/nodescraper/plugins/inband/dimm/collector_args.py +++ b/nodescraper/plugins/inband/dimm/collector_args.py @@ -28,4 +28,4 @@ class DimmCollectorArgs(CollectorArgs): - skip_sudo = False + skip_sudo: bool = False diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 65f95e33..c36870c3 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -23,23 +23,29 @@ # SOFTWARE. # ############################################################################### +from typing import Optional + from nodescraper.base import InBandDataCollector from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult +from .collector_args import DimmCollectorArgs from .dimmdata import DimmDataModel -class DimmCollector(InBandDataCollector[DimmDataModel, None]): +class DimmCollector(InBandDataCollector[DimmDataModel, DimmCollectorArgs]): """Collect data on installed DIMMs""" DATA_MODEL = DimmDataModel def collect_data( self, - args=None, + args: Optional[DimmCollectorArgs] = None, ) -> tuple[TaskResult, DimmDataModel | None]: """Collect data on installed DIMMs""" + if args is None: + args = DimmCollectorArgs() + if args.skip_sudo: self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN diff --git a/nodescraper/plugins/inband/dimm/dimm_plugin.py b/nodescraper/plugins/inband/dimm/dimm_plugin.py index fa3ee8cb..30dcc86d 100644 --- a/nodescraper/plugins/inband/dimm/dimm_plugin.py +++ b/nodescraper/plugins/inband/dimm/dimm_plugin.py @@ -30,7 +30,7 @@ from .dimmdata import DimmDataModel -class DimmPlugin(InBandDataPlugin[DimmDataModel, None, None]): +class DimmPlugin(InBandDataPlugin[DimmDataModel, DimmCollectorArgs, None]): """Plugin for collection and analysis of DIMM data""" DATA_MODEL = DimmDataModel diff --git a/nodescraper/plugins/inband/dmesg/collector_args.py b/nodescraper/plugins/inband/dmesg/collector_args.py index ca7066bf..4863ad0f 100644 --- a/nodescraper/plugins/inband/dmesg/collector_args.py +++ b/nodescraper/plugins/inband/dmesg/collector_args.py @@ -28,4 +28,4 @@ class DmesgCollectorArgs(CollectorArgs): - skip_sudo = False + skip_sudo: bool = False diff --git a/nodescraper/plugins/inband/dmesg/dmesg_plugin.py b/nodescraper/plugins/inband/dmesg/dmesg_plugin.py index 76cc696d..b1b42900 100644 --- a/nodescraper/plugins/inband/dmesg/dmesg_plugin.py +++ b/nodescraper/plugins/inband/dmesg/dmesg_plugin.py @@ -32,7 +32,7 @@ from .dmesgdata import DmesgData -class DmesgPlugin(InBandDataPlugin[DmesgData, None, DmesgAnalyzerArgs]): +class DmesgPlugin(InBandDataPlugin[DmesgData, DmesgCollectorArgs, DmesgAnalyzerArgs]): """Plugin for collection and analysis of dmesg data""" DATA_MODEL = DmesgData diff --git a/nodescraper/plugins/inband/storage/collector_args.py b/nodescraper/plugins/inband/storage/collector_args.py index 305c91b2..3067f6a8 100644 --- a/nodescraper/plugins/inband/storage/collector_args.py +++ b/nodescraper/plugins/inband/storage/collector_args.py @@ -28,4 +28,4 @@ class StorageCollectorArgs(CollectorArgs): - skip_sudo = False + skip_sudo: bool = False diff --git a/nodescraper/plugins/inband/storage/storage_plugin.py b/nodescraper/plugins/inband/storage/storage_plugin.py index 6911936f..1687e20e 100644 --- a/nodescraper/plugins/inband/storage/storage_plugin.py +++ b/nodescraper/plugins/inband/storage/storage_plugin.py @@ -32,7 +32,7 @@ from .storagedata import StorageDataModel -class StoragePlugin(InBandDataPlugin[StorageDataModel, None, StorageAnalyzerArgs]): +class StoragePlugin(InBandDataPlugin[StorageDataModel, StorageCollectorArgs, StorageAnalyzerArgs]): """Plugin for collection and analysis of disk usage data""" DATA_MODEL = StorageDataModel From d5c2ac7d329eb37ff94254ca1d1303da7afb2e35 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 28 Jul 2025 15:31:21 -0500 Subject: [PATCH 4/6] added collector args to dimm, dmesg and storage to support skip_sudo --- nodescraper/cli/helper.py | 2 +- nodescraper/pluginexecutor.py | 12 ++++++++++-- nodescraper/plugins/inband/dimm/dimm_collector.py | 1 + nodescraper/plugins/inband/dmesg/dmesg_collector.py | 11 +++++++++-- .../plugins/inband/storage/storage_collector.py | 9 ++++++++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/nodescraper/cli/helper.py b/nodescraper/cli/helper.py index b07c1696..bf5d3989 100644 --- a/nodescraper/cli/helper.py +++ b/nodescraper/cli/helper.py @@ -331,7 +331,7 @@ def generate_reference_config( for obj in results: if obj.result_data.collection_result.status != ExecutionStatus.OK: logger.warning( - "Plugin: %s result status is %, skipping", + "Plugin: %s result status is %s, skipping", obj.source, obj.result_data.collection_result.status, ) diff --git a/nodescraper/pluginexecutor.py b/nodescraper/pluginexecutor.py index 178e9bce..43930369 100644 --- a/nodescraper/pluginexecutor.py +++ b/nodescraper/pluginexecutor.py @@ -243,7 +243,11 @@ def apply_global_args_to_plugin( else: run_args[key] = global_args[key] - if "collection_args" in global_args and hasattr(plugin_class, "COLLECTOR_ARGS"): + if ( + "collection_args" in global_args + and getattr(plugin_class, "COLLECTOR_ARGS", None) is not None + and "COLLECTOR_ARGS" in plugin_class.__dict__ + ): plugin_fields = set(plugin_class.COLLECTOR_ARGS.__fields__.keys()) filtered = { k: v for k, v in global_args["collection_args"].items() if k in plugin_fields @@ -251,7 +255,11 @@ def apply_global_args_to_plugin( if filtered: run_args["collection_args"] = filtered - if "analysis_args" in global_args and hasattr(plugin_class, "ANALYZER_ARGS"): + if ( + "analysis_args" in global_args + and getattr(plugin_class, "ANALYZER_ARGS", None) is not None + and "ANALYZER_ARGS" in plugin_class.__dict__ + ): plugin_fields = set(plugin_class.ANALYZER_ARGS.__fields__.keys()) filtered = {k: v for k, v in global_args["analysis_args"].items() if k in plugin_fields} if filtered: diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index c36870c3..1d6d40a8 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -50,6 +50,7 @@ def collect_data( self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None + dimm_str = None if self.system_info.os_family == OSFamily.WINDOWS: res = self._run_sut_cmd("wmic memorychip get Capacity") diff --git a/nodescraper/plugins/inband/dmesg/dmesg_collector.py b/nodescraper/plugins/inband/dmesg/dmesg_collector.py index 1e289e1b..9be59793 100644 --- a/nodescraper/plugins/inband/dmesg/dmesg_collector.py +++ b/nodescraper/plugins/inband/dmesg/dmesg_collector.py @@ -23,14 +23,17 @@ # SOFTWARE. # ############################################################################### +from typing import Optional + from nodescraper.base import InBandDataCollector from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult +from .collector_args import DmesgCollectorArgs from .dmesgdata import DmesgData -class DmesgCollector(InBandDataCollector[DmesgData, None]): +class DmesgCollector(InBandDataCollector[DmesgData, DmesgCollectorArgs]): """Read dmesg log""" SUPPORTED_OS_FAMILY = {OSFamily.LINUX} @@ -60,17 +63,21 @@ def _get_dmesg_content(self) -> str: def collect_data( self, - args=None, + args: Optional[DmesgCollectorArgs] = None, ) -> tuple[TaskResult, DmesgData | None]: """Collect dmesg data from the system Returns: tuple[TaskResult, DmesgData | None]: tuple containing the result of the task and the dmesg data if available """ + if args is None: + args = DmesgCollectorArgs() + if args.skip_sudo: self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None + dmesg_content = self._get_dmesg_content() if dmesg_content: diff --git a/nodescraper/plugins/inband/storage/storage_collector.py b/nodescraper/plugins/inband/storage/storage_collector.py index 11fe26d1..255c0223 100644 --- a/nodescraper/plugins/inband/storage/storage_collector.py +++ b/nodescraper/plugins/inband/storage/storage_collector.py @@ -24,11 +24,13 @@ # ############################################################################### import re +from typing import Optional from nodescraper.base import InBandDataCollector from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult +from .collector_args import StorageCollectorArgs from .storagedata import DeviceStorageData, StorageDataModel @@ -37,8 +39,13 @@ class StorageCollector(InBandDataCollector[StorageDataModel, None]): DATA_MODEL = StorageDataModel - def collect_data(self, args: None = None) -> tuple[TaskResult, StorageDataModel | None]: + def collect_data( + self, args: Optional[StorageCollectorArgs] = None + ) -> tuple[TaskResult, StorageDataModel | None]: """read storage usage data""" + if args is None: + args = StorageCollectorArgs() + if args.skip_sudo: self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN From 704fc4bdde86300376ff9bb1fd2306b2a5874246 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Fri, 8 Aug 2025 10:20:40 -0500 Subject: [PATCH 5/6] updated with cmd line arg so you can skip-sudo with plugin_config + cmd line arg --- nodescraper/cli/cli.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nodescraper/cli/cli.py b/nodescraper/cli/cli.py index ef3aad04..52ab77a5 100644 --- a/nodescraper/cli/cli.py +++ b/nodescraper/cli/cli.py @@ -154,6 +154,13 @@ def build_parser( help="Generate reference config from system. Writes to ./reference_config.json.", ) + parser.add_argument( + "--skip-sudo", + dest="skip_sudo", + action="store_true", + help="Skip plugins that require sudo permissions", + ) + subparsers = parser.add_subparsers(dest="subcmd", help="Subcommands") summary_parser = subparsers.add_parser( @@ -418,6 +425,10 @@ def main(arg_input: Optional[list[str]] = None): plugin_subparser_map=plugin_subparser_map, ) + if parsed_args.skip_sudo: + for pcfg in plugin_config_inst_list: + pcfg.global_args.setdefault("collection_args", {})["skip_sudo"] = True + log_system_info(log_path, system_info, logger) except Exception as e: parser.error(str(e)) From 2ff9c6eb569da699e48e640b5fe189a61130bac6 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 18 Aug 2025 09:31:08 -0500 Subject: [PATCH 6/6] addressed reviews --- nodescraper/cli/cli.py | 5 +++-- nodescraper/plugins/inband/dimm/dimm_collector.py | 9 ++++----- nodescraper/plugins/inband/storage/storage_collector.py | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/nodescraper/cli/cli.py b/nodescraper/cli/cli.py index 52ab77a5..727c9570 100644 --- a/nodescraper/cli/cli.py +++ b/nodescraper/cli/cli.py @@ -426,8 +426,9 @@ def main(arg_input: Optional[list[str]] = None): ) if parsed_args.skip_sudo: - for pcfg in plugin_config_inst_list: - pcfg.global_args.setdefault("collection_args", {})["skip_sudo"] = True + plugin_config_inst_list[-1].global_args.setdefault("collection_args", {})[ + "skip_sudo" + ] = True log_system_info(log_path, system_info, logger) except Exception as e: diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 1d6d40a8..a7af7117 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -46,11 +46,6 @@ def collect_data( if args is None: args = DimmCollectorArgs() - if args.skip_sudo: - self.result.message = "Skipping sudo plugin" - self.result.status = ExecutionStatus.NOT_RAN - return self.result, None - dimm_str = None if self.system_info.os_family == OSFamily.WINDOWS: res = self._run_sut_cmd("wmic memorychip get Capacity") @@ -70,6 +65,10 @@ def collect_data( for capacity, count in capacities.items(): dimm_str += f"{count} x {capacity / 1024 / 1024:.2f}GB " else: + if args.skip_sudo: + self.result.message = "Skipping sudo plugin" + self.result.status = ExecutionStatus.NOT_RAN + return self.result, None res = self._run_sut_cmd( """sh -c 'dmidecode -t 17 | tr -s " " | grep -v "Volatile\\|None\\|Module" | grep Size' 2>/dev/null""", sudo=True, diff --git a/nodescraper/plugins/inband/storage/storage_collector.py b/nodescraper/plugins/inband/storage/storage_collector.py index 255c0223..30cf2163 100644 --- a/nodescraper/plugins/inband/storage/storage_collector.py +++ b/nodescraper/plugins/inband/storage/storage_collector.py @@ -46,10 +46,6 @@ def collect_data( if args is None: args = StorageCollectorArgs() - if args.skip_sudo: - self.result.message = "Skipping sudo plugin" - self.result.status = ExecutionStatus.NOT_RAN - return self.result, None storage_data = {} if self.system_info.os_family == OSFamily.WINDOWS: res = self._run_sut_cmd( @@ -66,6 +62,10 @@ def collect_data( percent=round((int(size) - int(free_space)) / int(size) * 100, 2), ) else: + if args.skip_sudo: + self.result.message = "Skipping sudo plugin" + self.result.status = ExecutionStatus.NOT_RAN + return self.result, None res = self._run_sut_cmd("""sh -c 'df -lH -B1 | grep -v 'boot''""", sudo=True) if res.exit_code == 0: for line in res.stdout.splitlines()[1:]: