amd-node-scraper 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amd_node_scraper-0.0.1.dist-info/LICENSE +21 -0
- amd_node_scraper-0.0.1.dist-info/METADATA +424 -0
- amd_node_scraper-0.0.1.dist-info/RECORD +197 -0
- amd_node_scraper-0.0.1.dist-info/WHEEL +5 -0
- amd_node_scraper-0.0.1.dist-info/entry_points.txt +2 -0
- amd_node_scraper-0.0.1.dist-info/top_level.txt +1 -0
- nodescraper/__init__.py +32 -0
- nodescraper/base/__init__.py +34 -0
- nodescraper/base/inbandcollectortask.py +118 -0
- nodescraper/base/inbanddataplugin.py +39 -0
- nodescraper/base/regexanalyzer.py +120 -0
- nodescraper/cli/__init__.py +29 -0
- nodescraper/cli/cli.py +511 -0
- nodescraper/cli/constants.py +27 -0
- nodescraper/cli/dynamicparserbuilder.py +171 -0
- nodescraper/cli/helper.py +517 -0
- nodescraper/cli/inputargtypes.py +129 -0
- nodescraper/configbuilder.py +123 -0
- nodescraper/configregistry.py +66 -0
- nodescraper/configs/node_status.json +19 -0
- nodescraper/connection/__init__.py +25 -0
- nodescraper/connection/inband/__init__.py +46 -0
- nodescraper/connection/inband/inband.py +171 -0
- nodescraper/connection/inband/inbandlocal.py +93 -0
- nodescraper/connection/inband/inbandmanager.py +151 -0
- nodescraper/connection/inband/inbandremote.py +173 -0
- nodescraper/connection/inband/sshparams.py +43 -0
- nodescraper/constants.py +26 -0
- nodescraper/enums/__init__.py +40 -0
- nodescraper/enums/eventcategory.py +89 -0
- nodescraper/enums/eventpriority.py +42 -0
- nodescraper/enums/executionstatus.py +44 -0
- nodescraper/enums/osfamily.py +34 -0
- nodescraper/enums/systeminteraction.py +41 -0
- nodescraper/enums/systemlocation.py +33 -0
- nodescraper/generictypes.py +36 -0
- nodescraper/interfaces/__init__.py +44 -0
- nodescraper/interfaces/connectionmanager.py +143 -0
- nodescraper/interfaces/dataanalyzertask.py +138 -0
- nodescraper/interfaces/datacollectortask.py +185 -0
- nodescraper/interfaces/dataplugin.py +356 -0
- nodescraper/interfaces/plugin.py +127 -0
- nodescraper/interfaces/resultcollator.py +56 -0
- nodescraper/interfaces/task.py +164 -0
- nodescraper/interfaces/taskresulthook.py +39 -0
- nodescraper/models/__init__.py +48 -0
- nodescraper/models/analyzerargs.py +93 -0
- nodescraper/models/collectorargs.py +30 -0
- nodescraper/models/connectionconfig.py +34 -0
- nodescraper/models/datamodel.py +171 -0
- nodescraper/models/datapluginresult.py +39 -0
- nodescraper/models/event.py +158 -0
- nodescraper/models/pluginconfig.py +38 -0
- nodescraper/models/pluginresult.py +39 -0
- nodescraper/models/systeminfo.py +44 -0
- nodescraper/models/taskresult.py +185 -0
- nodescraper/models/timerangeargs.py +38 -0
- nodescraper/pluginexecutor.py +274 -0
- nodescraper/pluginregistry.py +152 -0
- nodescraper/plugins/__init__.py +25 -0
- nodescraper/plugins/inband/__init__.py +25 -0
- nodescraper/plugins/inband/amdsmi/__init__.py +28 -0
- nodescraper/plugins/inband/amdsmi/amdsmi_analyzer.py +821 -0
- nodescraper/plugins/inband/amdsmi/amdsmi_collector.py +1313 -0
- nodescraper/plugins/inband/amdsmi/amdsmi_plugin.py +43 -0
- nodescraper/plugins/inband/amdsmi/amdsmidata.py +1002 -0
- nodescraper/plugins/inband/amdsmi/analyzer_args.py +50 -0
- nodescraper/plugins/inband/amdsmi/cper.py +65 -0
- nodescraper/plugins/inband/bios/__init__.py +29 -0
- nodescraper/plugins/inband/bios/analyzer_args.py +64 -0
- nodescraper/plugins/inband/bios/bios_analyzer.py +93 -0
- nodescraper/plugins/inband/bios/bios_collector.py +93 -0
- nodescraper/plugins/inband/bios/bios_plugin.py +43 -0
- nodescraper/plugins/inband/bios/biosdata.py +30 -0
- nodescraper/plugins/inband/cmdline/__init__.py +25 -0
- nodescraper/plugins/inband/cmdline/analyzer_args.py +80 -0
- nodescraper/plugins/inband/cmdline/cmdline_analyzer.py +113 -0
- nodescraper/plugins/inband/cmdline/cmdline_collector.py +77 -0
- nodescraper/plugins/inband/cmdline/cmdline_plugin.py +43 -0
- nodescraper/plugins/inband/cmdline/cmdlinedata.py +30 -0
- nodescraper/plugins/inband/device_enumeration/__init__.py +29 -0
- nodescraper/plugins/inband/device_enumeration/analyzer_args.py +73 -0
- nodescraper/plugins/inband/device_enumeration/device_enumeration_analyzer.py +81 -0
- nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +176 -0
- nodescraper/plugins/inband/device_enumeration/device_enumeration_plugin.py +45 -0
- nodescraper/plugins/inband/device_enumeration/deviceenumdata.py +36 -0
- nodescraper/plugins/inband/dimm/__init__.py +25 -0
- nodescraper/plugins/inband/dimm/collector_args.py +31 -0
- nodescraper/plugins/inband/dimm/dimm_collector.py +151 -0
- nodescraper/plugins/inband/dimm/dimm_plugin.py +40 -0
- nodescraper/plugins/inband/dimm/dimmdata.py +30 -0
- nodescraper/plugins/inband/dkms/__init__.py +25 -0
- nodescraper/plugins/inband/dkms/analyzer_args.py +85 -0
- nodescraper/plugins/inband/dkms/dkms_analyzer.py +106 -0
- nodescraper/plugins/inband/dkms/dkms_collector.py +76 -0
- nodescraper/plugins/inband/dkms/dkms_plugin.py +43 -0
- nodescraper/plugins/inband/dkms/dkmsdata.py +33 -0
- nodescraper/plugins/inband/dmesg/__init__.py +28 -0
- nodescraper/plugins/inband/dmesg/analyzer_args.py +33 -0
- nodescraper/plugins/inband/dmesg/collector_args.py +39 -0
- nodescraper/plugins/inband/dmesg/dmesg_analyzer.py +503 -0
- nodescraper/plugins/inband/dmesg/dmesg_collector.py +164 -0
- nodescraper/plugins/inband/dmesg/dmesg_plugin.py +44 -0
- nodescraper/plugins/inband/dmesg/dmesgdata.py +116 -0
- nodescraper/plugins/inband/fabrics/__init__.py +28 -0
- nodescraper/plugins/inband/fabrics/fabrics_collector.py +726 -0
- nodescraper/plugins/inband/fabrics/fabrics_plugin.py +37 -0
- nodescraper/plugins/inband/fabrics/fabricsdata.py +140 -0
- nodescraper/plugins/inband/journal/__init__.py +28 -0
- nodescraper/plugins/inband/journal/collector_args.py +33 -0
- nodescraper/plugins/inband/journal/journal_collector.py +107 -0
- nodescraper/plugins/inband/journal/journal_plugin.py +40 -0
- nodescraper/plugins/inband/journal/journaldata.py +44 -0
- nodescraper/plugins/inband/kernel/__init__.py +25 -0
- nodescraper/plugins/inband/kernel/analyzer_args.py +64 -0
- nodescraper/plugins/inband/kernel/kernel_analyzer.py +91 -0
- nodescraper/plugins/inband/kernel/kernel_collector.py +129 -0
- nodescraper/plugins/inband/kernel/kernel_plugin.py +43 -0
- nodescraper/plugins/inband/kernel/kerneldata.py +32 -0
- nodescraper/plugins/inband/kernel_module/__init__.py +25 -0
- nodescraper/plugins/inband/kernel_module/analyzer_args.py +59 -0
- nodescraper/plugins/inband/kernel_module/kernel_module_analyzer.py +211 -0
- nodescraper/plugins/inband/kernel_module/kernel_module_collector.py +264 -0
- nodescraper/plugins/inband/kernel_module/kernel_module_data.py +60 -0
- nodescraper/plugins/inband/kernel_module/kernel_module_plugin.py +43 -0
- nodescraper/plugins/inband/memory/__init__.py +25 -0
- nodescraper/plugins/inband/memory/analyzer_args.py +45 -0
- nodescraper/plugins/inband/memory/memory_analyzer.py +98 -0
- nodescraper/plugins/inband/memory/memory_collector.py +330 -0
- nodescraper/plugins/inband/memory/memory_plugin.py +43 -0
- nodescraper/plugins/inband/memory/memorydata.py +90 -0
- nodescraper/plugins/inband/network/__init__.py +28 -0
- nodescraper/plugins/inband/network/network_collector.py +1828 -0
- nodescraper/plugins/inband/network/network_plugin.py +37 -0
- nodescraper/plugins/inband/network/networkdata.py +319 -0
- nodescraper/plugins/inband/nvme/__init__.py +28 -0
- nodescraper/plugins/inband/nvme/nvme_collector.py +167 -0
- nodescraper/plugins/inband/nvme/nvme_plugin.py +37 -0
- nodescraper/plugins/inband/nvme/nvmedata.py +45 -0
- nodescraper/plugins/inband/os/__init__.py +25 -0
- nodescraper/plugins/inband/os/analyzer_args.py +64 -0
- nodescraper/plugins/inband/os/os_analyzer.py +73 -0
- nodescraper/plugins/inband/os/os_collector.py +131 -0
- nodescraper/plugins/inband/os/os_plugin.py +43 -0
- nodescraper/plugins/inband/os/osdata.py +31 -0
- nodescraper/plugins/inband/package/__init__.py +25 -0
- nodescraper/plugins/inband/package/analyzer_args.py +48 -0
- nodescraper/plugins/inband/package/package_analyzer.py +253 -0
- nodescraper/plugins/inband/package/package_collector.py +273 -0
- nodescraper/plugins/inband/package/package_plugin.py +43 -0
- nodescraper/plugins/inband/package/packagedata.py +41 -0
- nodescraper/plugins/inband/pcie/__init__.py +29 -0
- nodescraper/plugins/inband/pcie/analyzer_args.py +63 -0
- nodescraper/plugins/inband/pcie/pcie_analyzer.py +1081 -0
- nodescraper/plugins/inband/pcie/pcie_collector.py +690 -0
- nodescraper/plugins/inband/pcie/pcie_data.py +2017 -0
- nodescraper/plugins/inband/pcie/pcie_plugin.py +43 -0
- nodescraper/plugins/inband/process/__init__.py +25 -0
- nodescraper/plugins/inband/process/analyzer_args.py +45 -0
- nodescraper/plugins/inband/process/collector_args.py +31 -0
- nodescraper/plugins/inband/process/process_analyzer.py +91 -0
- nodescraper/plugins/inband/process/process_collector.py +115 -0
- nodescraper/plugins/inband/process/process_plugin.py +46 -0
- nodescraper/plugins/inband/process/processdata.py +34 -0
- nodescraper/plugins/inband/rocm/__init__.py +25 -0
- nodescraper/plugins/inband/rocm/analyzer_args.py +66 -0
- nodescraper/plugins/inband/rocm/rocm_analyzer.py +100 -0
- nodescraper/plugins/inband/rocm/rocm_collector.py +205 -0
- nodescraper/plugins/inband/rocm/rocm_plugin.py +43 -0
- nodescraper/plugins/inband/rocm/rocmdata.py +62 -0
- nodescraper/plugins/inband/storage/__init__.py +25 -0
- nodescraper/plugins/inband/storage/analyzer_args.py +38 -0
- nodescraper/plugins/inband/storage/collector_args.py +31 -0
- nodescraper/plugins/inband/storage/storage_analyzer.py +152 -0
- nodescraper/plugins/inband/storage/storage_collector.py +110 -0
- nodescraper/plugins/inband/storage/storage_plugin.py +44 -0
- nodescraper/plugins/inband/storage/storagedata.py +70 -0
- nodescraper/plugins/inband/sysctl/__init__.py +29 -0
- nodescraper/plugins/inband/sysctl/analyzer_args.py +67 -0
- nodescraper/plugins/inband/sysctl/sysctl_analyzer.py +81 -0
- nodescraper/plugins/inband/sysctl/sysctl_collector.py +101 -0
- nodescraper/plugins/inband/sysctl/sysctl_plugin.py +43 -0
- nodescraper/plugins/inband/sysctl/sysctldata.py +42 -0
- nodescraper/plugins/inband/syslog/__init__.py +28 -0
- nodescraper/plugins/inband/syslog/syslog_collector.py +121 -0
- nodescraper/plugins/inband/syslog/syslog_plugin.py +37 -0
- nodescraper/plugins/inband/syslog/syslogdata.py +46 -0
- nodescraper/plugins/inband/uptime/__init__.py +25 -0
- nodescraper/plugins/inband/uptime/uptime_collector.py +88 -0
- nodescraper/plugins/inband/uptime/uptime_plugin.py +37 -0
- nodescraper/plugins/inband/uptime/uptimedata.py +31 -0
- nodescraper/resultcollators/__init__.py +25 -0
- nodescraper/resultcollators/tablesummary.py +159 -0
- nodescraper/taskresulthooks/__init__.py +28 -0
- nodescraper/taskresulthooks/filesystemloghook.py +88 -0
- nodescraper/typeutils.py +171 -0
- nodescraper/utils.py +412 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from typing import Optional
|
|
27
|
+
|
|
28
|
+
from nodescraper.models import DataModel
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DeviceEnumerationDataModel(DataModel):
|
|
32
|
+
cpu_count: Optional[int] = None
|
|
33
|
+
gpu_count: Optional[int] = None
|
|
34
|
+
vf_count: Optional[int] = None
|
|
35
|
+
lscpu_output: Optional[str] = None
|
|
36
|
+
lshw_output: Optional[str] = None
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
|
|
27
|
+
from nodescraper.models import CollectorArgs
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DimmCollectorArgs(CollectorArgs):
|
|
31
|
+
skip_sudo: bool = False
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from typing import Optional
|
|
27
|
+
|
|
28
|
+
from nodescraper.base import InBandDataCollector
|
|
29
|
+
from nodescraper.connection.inband import TextFileArtifact
|
|
30
|
+
from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily
|
|
31
|
+
from nodescraper.models import TaskResult
|
|
32
|
+
|
|
33
|
+
from .collector_args import DimmCollectorArgs
|
|
34
|
+
from .dimmdata import DimmDataModel
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DimmCollector(InBandDataCollector[DimmDataModel, DimmCollectorArgs]):
|
|
38
|
+
"""Collect data on installed DIMMs"""
|
|
39
|
+
|
|
40
|
+
DATA_MODEL = DimmDataModel
|
|
41
|
+
|
|
42
|
+
CMD_WINDOWS = "wmic memorychip get Capacity"
|
|
43
|
+
CMD = """sh -c 'dmidecode -t 17 | tr -s " " | grep -v "Volatile\\|None\\|Module" | grep Size' 2>/dev/null"""
|
|
44
|
+
CMD_DMIDECODE_FULL = "dmidecode"
|
|
45
|
+
|
|
46
|
+
def collect_data(
|
|
47
|
+
self,
|
|
48
|
+
args: Optional[DimmCollectorArgs] = None,
|
|
49
|
+
) -> tuple[TaskResult, Optional[DimmDataModel]]:
|
|
50
|
+
"""Collect data on installed DIMMs"""
|
|
51
|
+
if args is None:
|
|
52
|
+
args = DimmCollectorArgs()
|
|
53
|
+
|
|
54
|
+
dimm_str = None
|
|
55
|
+
if self.system_info.os_family == OSFamily.WINDOWS:
|
|
56
|
+
res = self._run_sut_cmd(self.CMD_WINDOWS)
|
|
57
|
+
if res.exit_code == 0:
|
|
58
|
+
capacities = {}
|
|
59
|
+
total = 0
|
|
60
|
+
for line in res.stdout.splitlines():
|
|
61
|
+
value = line.strip()
|
|
62
|
+
if value.isdigit():
|
|
63
|
+
value = int(value)
|
|
64
|
+
total += value
|
|
65
|
+
if value not in capacities:
|
|
66
|
+
capacities[value] = 1
|
|
67
|
+
else:
|
|
68
|
+
capacities[value] += 1
|
|
69
|
+
dimm_str = f"{total / 1024 / 1024:.2f}GB @ "
|
|
70
|
+
for capacity, count in capacities.items():
|
|
71
|
+
dimm_str += f"{count} x {capacity / 1024 / 1024:.2f}GB "
|
|
72
|
+
else:
|
|
73
|
+
if args.skip_sudo:
|
|
74
|
+
self.result.message = "Skipping sudo plugin"
|
|
75
|
+
self.result.status = ExecutionStatus.NOT_RAN
|
|
76
|
+
return self.result, None
|
|
77
|
+
|
|
78
|
+
# Collect full dmidecode output as artifact
|
|
79
|
+
dmidecode_full_res = self._run_sut_cmd(self.CMD_DMIDECODE_FULL, sudo=True)
|
|
80
|
+
if dmidecode_full_res.exit_code == 0 and dmidecode_full_res.stdout:
|
|
81
|
+
self.result.artifacts.append(
|
|
82
|
+
TextFileArtifact(filename="dmidecode.txt", contents=dmidecode_full_res.stdout)
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
self._log_event(
|
|
86
|
+
category=EventCategory.OS,
|
|
87
|
+
description="Could not collect full dmidecode output",
|
|
88
|
+
data={
|
|
89
|
+
"command": dmidecode_full_res.command,
|
|
90
|
+
"exit_code": dmidecode_full_res.exit_code,
|
|
91
|
+
"stderr": dmidecode_full_res.stderr,
|
|
92
|
+
},
|
|
93
|
+
priority=EventPriority.WARNING,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
res = self._run_sut_cmd(self.CMD, sudo=True)
|
|
97
|
+
if res.exit_code == 0:
|
|
98
|
+
total = 0
|
|
99
|
+
topology = {}
|
|
100
|
+
size = None
|
|
101
|
+
for d in res.stdout.splitlines():
|
|
102
|
+
split = d.split()
|
|
103
|
+
size = split[2]
|
|
104
|
+
key = split[1] + split[2]
|
|
105
|
+
if not topology.get(key, None):
|
|
106
|
+
topology[key] = 1
|
|
107
|
+
else:
|
|
108
|
+
topology[key] += 1
|
|
109
|
+
num_gb = int(split[1])
|
|
110
|
+
total += num_gb
|
|
111
|
+
topology["total"] = total
|
|
112
|
+
topology["size"] = size
|
|
113
|
+
total_gb = topology.pop("total")
|
|
114
|
+
size = topology.pop("size")
|
|
115
|
+
dimm_str = str(total_gb) + size + " @"
|
|
116
|
+
for size, count in topology.items():
|
|
117
|
+
dimm_str += f" {count} x {size}"
|
|
118
|
+
|
|
119
|
+
if res.exit_code != 0:
|
|
120
|
+
self._log_event(
|
|
121
|
+
category=EventCategory.OS,
|
|
122
|
+
description="Error checking dimms",
|
|
123
|
+
data={
|
|
124
|
+
"command": res.command,
|
|
125
|
+
"exit_code": res.exit_code,
|
|
126
|
+
"stderr": res.stderr,
|
|
127
|
+
},
|
|
128
|
+
priority=EventPriority.ERROR,
|
|
129
|
+
console_log=True,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
if dimm_str:
|
|
133
|
+
dimm_data = DimmDataModel(dimms=dimm_str)
|
|
134
|
+
self._log_event(
|
|
135
|
+
category=EventCategory.IO,
|
|
136
|
+
description="Installed DIMM check",
|
|
137
|
+
data=dimm_data.model_dump(),
|
|
138
|
+
priority=EventPriority.INFO,
|
|
139
|
+
)
|
|
140
|
+
self.result.message = f"DIMM: {dimm_str}"
|
|
141
|
+
else:
|
|
142
|
+
dimm_data = None
|
|
143
|
+
self._log_event(
|
|
144
|
+
category=EventCategory.IO,
|
|
145
|
+
description="DIMM info not found",
|
|
146
|
+
priority=EventPriority.CRITICAL,
|
|
147
|
+
)
|
|
148
|
+
self.result.message = "DIMM info not found"
|
|
149
|
+
self.result.status = ExecutionStatus.ERROR
|
|
150
|
+
|
|
151
|
+
return self.result, dimm_data
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from nodescraper.base import InBandDataPlugin
|
|
27
|
+
|
|
28
|
+
from .collector_args import DimmCollectorArgs
|
|
29
|
+
from .dimm_collector import DimmCollector
|
|
30
|
+
from .dimmdata import DimmDataModel
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class DimmPlugin(InBandDataPlugin[DimmDataModel, DimmCollectorArgs, None]):
|
|
34
|
+
"""Plugin for collection and analysis of DIMM data"""
|
|
35
|
+
|
|
36
|
+
DATA_MODEL = DimmDataModel
|
|
37
|
+
|
|
38
|
+
COLLECTOR = DimmCollector
|
|
39
|
+
|
|
40
|
+
COLLECTOR_ARGS = DimmCollectorArgs
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from nodescraper.models import DataModel
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DimmDataModel(DataModel):
|
|
30
|
+
dimms: str
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from typing import Any, Union
|
|
27
|
+
|
|
28
|
+
from pydantic import Field, field_validator
|
|
29
|
+
|
|
30
|
+
from nodescraper.models import AnalyzerArgs
|
|
31
|
+
from nodescraper.plugins.inband.dkms.dkmsdata import DkmsDataModel
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DkmsAnalyzerArgs(AnalyzerArgs):
|
|
35
|
+
dkms_status: Union[str, list] = Field(default_factory=list)
|
|
36
|
+
dkms_version: Union[str, list] = Field(default_factory=list)
|
|
37
|
+
regex_match: bool = False
|
|
38
|
+
|
|
39
|
+
def model_post_init(self, __context: Any) -> None:
|
|
40
|
+
if not self.dkms_status and not self.dkms_version:
|
|
41
|
+
raise ValueError("At least one of dkms_status or dkms_version must be provided")
|
|
42
|
+
|
|
43
|
+
@field_validator("dkms_status", mode="before")
|
|
44
|
+
@classmethod
|
|
45
|
+
def validate_dkms_status(cls, dkms_status: Union[str, list]) -> list:
|
|
46
|
+
"""support str or list input for dkms_status
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
dkms_status (Union[str, list]): dkms status to check
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
list: list of dkms status
|
|
53
|
+
"""
|
|
54
|
+
if isinstance(dkms_status, str):
|
|
55
|
+
dkms_status = [dkms_status]
|
|
56
|
+
|
|
57
|
+
return dkms_status
|
|
58
|
+
|
|
59
|
+
@field_validator("dkms_version", mode="before")
|
|
60
|
+
@classmethod
|
|
61
|
+
def validate_dkms_version(cls, dkms_version: Union[str, list]) -> list:
|
|
62
|
+
"""support str or list input for dkms_version
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
dkms_version (Union[str, list]): dkms version to check
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
list: list of dkms version
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(dkms_version, str):
|
|
71
|
+
dkms_version = [dkms_version]
|
|
72
|
+
|
|
73
|
+
return dkms_version
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def build_from_model(cls, datamodel: DkmsDataModel) -> "DkmsAnalyzerArgs":
|
|
77
|
+
"""build analyzer args from data model
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
datamodel (DkmsDataModel): data model for plugin
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
DkmsAnalyzerArgs: instance of analyzer args class
|
|
84
|
+
"""
|
|
85
|
+
return cls(dkms_status=datamodel.status, dkms_version=datamodel.version)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
import re
|
|
27
|
+
from typing import Optional
|
|
28
|
+
|
|
29
|
+
from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus
|
|
30
|
+
from nodescraper.interfaces import DataAnalyzer
|
|
31
|
+
from nodescraper.models import TaskResult
|
|
32
|
+
|
|
33
|
+
from .analyzer_args import DkmsAnalyzerArgs
|
|
34
|
+
from .dkmsdata import DkmsDataModel
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DkmsAnalyzer(DataAnalyzer[DkmsDataModel, DkmsAnalyzerArgs]):
|
|
38
|
+
"""Check dkms matches expected status and version"""
|
|
39
|
+
|
|
40
|
+
DATA_MODEL = DkmsDataModel
|
|
41
|
+
|
|
42
|
+
def analyze_data(
|
|
43
|
+
self, data: DkmsDataModel, args: Optional[DkmsAnalyzerArgs] = None
|
|
44
|
+
) -> TaskResult:
|
|
45
|
+
"""
|
|
46
|
+
Analyze the provided DKMS data against the expected status and version.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
data (DkmsDataModel): Dkms data to analyze.
|
|
50
|
+
args (Optional[DkmsAnalyzerArgs], optional): Dkms analysis arguments. Defaults to None.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
TaskResult: The result of the analysis containing status and message.
|
|
54
|
+
"""
|
|
55
|
+
# Check if the required data is provided
|
|
56
|
+
if not args:
|
|
57
|
+
self.result.message = "DKMS analysis args not provided"
|
|
58
|
+
self.result.status = ExecutionStatus.NOT_RAN
|
|
59
|
+
return self.result
|
|
60
|
+
|
|
61
|
+
# Convert the status and version to lists if they are not already
|
|
62
|
+
check_map = {
|
|
63
|
+
"status": args.dkms_status,
|
|
64
|
+
"version": args.dkms_version,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
error_state = False
|
|
68
|
+
|
|
69
|
+
actual_values = []
|
|
70
|
+
expected_values = []
|
|
71
|
+
for check, accepted_values in check_map.items():
|
|
72
|
+
actual_value = getattr(data, check)
|
|
73
|
+
for accepted_value in accepted_values:
|
|
74
|
+
if args.regex_match:
|
|
75
|
+
try:
|
|
76
|
+
regex_data = re.compile(accepted_value)
|
|
77
|
+
except re.error:
|
|
78
|
+
self._log_event(
|
|
79
|
+
category=EventCategory.RUNTIME,
|
|
80
|
+
description=f"DKMS {check} regex is invalid",
|
|
81
|
+
data={"regex": accepted_value},
|
|
82
|
+
priority=EventPriority.ERROR,
|
|
83
|
+
)
|
|
84
|
+
if regex_data.match(actual_value):
|
|
85
|
+
break
|
|
86
|
+
elif actual_value == accepted_value:
|
|
87
|
+
break
|
|
88
|
+
else:
|
|
89
|
+
expected_values.append(accepted_values)
|
|
90
|
+
actual_values.append(actual_value)
|
|
91
|
+
self._log_event(
|
|
92
|
+
category=EventCategory.SW_DRIVER,
|
|
93
|
+
description=f"DKMS {check} has an unexpected value",
|
|
94
|
+
data={"expected": accepted_values, "actual": actual_value},
|
|
95
|
+
priority=EventPriority.CRITICAL,
|
|
96
|
+
console_log=True,
|
|
97
|
+
)
|
|
98
|
+
error_state = True
|
|
99
|
+
|
|
100
|
+
if error_state:
|
|
101
|
+
self.result.status = ExecutionStatus.ERROR
|
|
102
|
+
self.result.message = (
|
|
103
|
+
f"DKMS data mismatch. \nActual: {actual_values}.\nExpected: {expected_values}"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return self.result
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from typing import Optional
|
|
27
|
+
|
|
28
|
+
from nodescraper.base import InBandDataCollector
|
|
29
|
+
from nodescraper.enums import EventPriority, ExecutionStatus, OSFamily
|
|
30
|
+
from nodescraper.models import TaskResult
|
|
31
|
+
|
|
32
|
+
from .dkmsdata import DkmsDataModel
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DkmsCollector(InBandDataCollector[DkmsDataModel, None]):
|
|
36
|
+
"""Collect DKMS status and version data"""
|
|
37
|
+
|
|
38
|
+
SUPPORTED_OS_FAMILY = {OSFamily.LINUX}
|
|
39
|
+
|
|
40
|
+
DATA_MODEL = DkmsDataModel
|
|
41
|
+
|
|
42
|
+
CMD_STATUS = "dkms status"
|
|
43
|
+
CMD_VERSION = "dkms --version"
|
|
44
|
+
|
|
45
|
+
def collect_data(
|
|
46
|
+
self,
|
|
47
|
+
args=None,
|
|
48
|
+
) -> tuple[TaskResult, Optional[DkmsDataModel]]:
|
|
49
|
+
"""
|
|
50
|
+
Collect DKMS status and version information.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
tuple[TaskResult, Optional[DkmsDataModel]]: tuple containing the task result and DKMS data model if available.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
dkms_data = DkmsDataModel()
|
|
57
|
+
dkms_status = self._run_sut_cmd(self.CMD_STATUS)
|
|
58
|
+
dkms_version = self._run_sut_cmd(self.CMD_VERSION)
|
|
59
|
+
|
|
60
|
+
if dkms_status.exit_code == 0:
|
|
61
|
+
dkms_data.status = dkms_status.stdout
|
|
62
|
+
|
|
63
|
+
if dkms_version.exit_code == 0:
|
|
64
|
+
dkms_data.version = dkms_version.stdout
|
|
65
|
+
|
|
66
|
+
dkms = bool(dkms_data.model_fields_set)
|
|
67
|
+
if dkms:
|
|
68
|
+
self._log_event(
|
|
69
|
+
category="DKMS_READ",
|
|
70
|
+
description="DKMS data read",
|
|
71
|
+
data=dkms_data.model_dump(),
|
|
72
|
+
priority=EventPriority.INFO,
|
|
73
|
+
)
|
|
74
|
+
self.result.message = f"DKMS: {dkms_data.model_dump()}" if dkms else "DKMS info not found"
|
|
75
|
+
self.result.status = ExecutionStatus.OK if dkms else ExecutionStatus.ERROR
|
|
76
|
+
return self.result, dkms_data if dkms else None
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2025 Advanced Micro Devices, Inc.
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
###############################################################################
|
|
26
|
+
from nodescraper.base import InBandDataPlugin
|
|
27
|
+
|
|
28
|
+
from .analyzer_args import DkmsAnalyzerArgs
|
|
29
|
+
from .dkms_analyzer import DkmsAnalyzer
|
|
30
|
+
from .dkms_collector import DkmsCollector
|
|
31
|
+
from .dkmsdata import DkmsDataModel
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DkmsPlugin(InBandDataPlugin[DkmsDataModel, None, DkmsAnalyzerArgs]):
|
|
35
|
+
"""Plugin for collection and analysis of DKMS data"""
|
|
36
|
+
|
|
37
|
+
DATA_MODEL = DkmsDataModel
|
|
38
|
+
|
|
39
|
+
COLLECTOR = DkmsCollector
|
|
40
|
+
|
|
41
|
+
ANALYZER = DkmsAnalyzer
|
|
42
|
+
|
|
43
|
+
ANALYZER_ARGS = DkmsAnalyzerArgs
|