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,37 @@
|
|
|
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 .fabrics_collector import FabricsCollector
|
|
29
|
+
from .fabricsdata import FabricsDataModel
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FabricsPlugin(InBandDataPlugin[FabricsDataModel, None, None]):
|
|
33
|
+
"""Plugin for collection of InfiniBand/RDMA fabrics configuration data"""
|
|
34
|
+
|
|
35
|
+
DATA_MODEL = FabricsDataModel
|
|
36
|
+
|
|
37
|
+
COLLECTOR = FabricsCollector
|
|
@@ -0,0 +1,140 @@
|
|
|
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 Dict, List, Optional
|
|
27
|
+
|
|
28
|
+
from pydantic import BaseModel, Field
|
|
29
|
+
|
|
30
|
+
from nodescraper.models import DataModel
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class IbstatDevice(BaseModel):
|
|
34
|
+
"""InfiniBand device information from ibstat"""
|
|
35
|
+
|
|
36
|
+
ca_name: Optional[str] = None # CA name (e.g., "mlx5_0")
|
|
37
|
+
ca_type: Optional[str] = None # CA type
|
|
38
|
+
number_of_ports: Optional[int] = None # Number of physical ports
|
|
39
|
+
firmware_version: Optional[str] = None # Firmware version
|
|
40
|
+
hardware_version: Optional[str] = None # Hardware version
|
|
41
|
+
node_guid: Optional[str] = None # Node GUID
|
|
42
|
+
system_image_guid: Optional[str] = None # System image GUID
|
|
43
|
+
ports: Dict[int, Dict[str, str]] = Field(default_factory=dict) # Port number -> port attributes
|
|
44
|
+
raw_output: str = "" # Raw command output
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class IbvDeviceInfo(BaseModel):
|
|
48
|
+
"""InfiniBand verbs device information from ibv_devinfo"""
|
|
49
|
+
|
|
50
|
+
device: Optional[str] = None # Device name (e.g., "mlx5_0")
|
|
51
|
+
node_guid: Optional[str] = None # Node GUID
|
|
52
|
+
sys_image_guid: Optional[str] = None # System image GUID
|
|
53
|
+
vendor_id: Optional[str] = None # Vendor ID
|
|
54
|
+
vendor_part_id: Optional[str] = None # Vendor part ID
|
|
55
|
+
hw_ver: Optional[str] = None # Hardware version
|
|
56
|
+
fw_ver: Optional[str] = None # Firmware version
|
|
57
|
+
node_type: Optional[str] = None # Node type
|
|
58
|
+
transport_type: Optional[str] = None # Transport type (e.g., "InfiniBand", "Ethernet")
|
|
59
|
+
ports: Dict[int, Dict[str, str]] = Field(default_factory=dict) # Port number -> port attributes
|
|
60
|
+
raw_output: str = "" # Raw command output
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class IbdevNetdevMapping(BaseModel):
|
|
64
|
+
"""Mapping between IB device and network interface"""
|
|
65
|
+
|
|
66
|
+
ib_device: str # InfiniBand device name (e.g., "mlx5_0")
|
|
67
|
+
port: int # Port number
|
|
68
|
+
netdev: Optional[str] = None # Network device name (e.g., "ib0", "eth0")
|
|
69
|
+
state: Optional[str] = None # Port state (e.g., "Up", "Down")
|
|
70
|
+
pkey: Optional[str] = None # Partition key
|
|
71
|
+
guid: Optional[str] = None # GUID
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class OfedInfo(BaseModel):
|
|
75
|
+
"""OFED version and information"""
|
|
76
|
+
|
|
77
|
+
version: Optional[str] = None # OFED version
|
|
78
|
+
raw_output: str = "" # Raw command output
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class MstDevice(BaseModel):
|
|
82
|
+
"""Mellanox Software Tools device information"""
|
|
83
|
+
|
|
84
|
+
device: str # Device path (e.g., "/dev/mst/mt4123_pciconf0")
|
|
85
|
+
pci_address: Optional[str] = None # PCI address
|
|
86
|
+
rdma_device: Optional[str] = None # RDMA device name
|
|
87
|
+
net_device: Optional[str] = None # Network device name
|
|
88
|
+
attributes: Dict[str, str] = Field(default_factory=dict) # Additional attributes
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class MstStatus(BaseModel):
|
|
92
|
+
"""Mellanox Software Tools status"""
|
|
93
|
+
|
|
94
|
+
mst_started: bool = False # Whether MST service is started
|
|
95
|
+
devices: List[MstDevice] = Field(default_factory=list) # List of MST devices
|
|
96
|
+
raw_output: str = "" # Raw command output
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class RdmaDevice(BaseModel):
|
|
100
|
+
"""RDMA device information from rdma command"""
|
|
101
|
+
|
|
102
|
+
device: str # Device name (e.g., "mlx5_0")
|
|
103
|
+
node_type: Optional[str] = None # Node type
|
|
104
|
+
transport: Optional[str] = None # Transport type
|
|
105
|
+
node_guid: Optional[str] = None # Node GUID
|
|
106
|
+
sys_image_guid: Optional[str] = None # System image GUID
|
|
107
|
+
state: Optional[str] = None # Device state
|
|
108
|
+
attributes: Dict[str, str] = Field(default_factory=dict) # Additional attributes
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class RdmaLink(BaseModel):
|
|
112
|
+
"""RDMA link information"""
|
|
113
|
+
|
|
114
|
+
device: str # Device name
|
|
115
|
+
port: int # Port number
|
|
116
|
+
state: Optional[str] = None # Link state
|
|
117
|
+
physical_state: Optional[str] = None # Physical state
|
|
118
|
+
netdev: Optional[str] = None # Associated network device
|
|
119
|
+
attributes: Dict[str, str] = Field(default_factory=dict) # Additional attributes
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class RdmaInfo(BaseModel):
|
|
123
|
+
"""Complete RDMA information from rdma command"""
|
|
124
|
+
|
|
125
|
+
devices: List[RdmaDevice] = Field(default_factory=list) # RDMA devices
|
|
126
|
+
links: List[RdmaLink] = Field(default_factory=list) # RDMA links
|
|
127
|
+
raw_output: str = "" # Raw command output
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class FabricsDataModel(DataModel):
|
|
131
|
+
"""Complete InfiniBand/RDMA fabrics configuration data"""
|
|
132
|
+
|
|
133
|
+
ibstat_devices: List[IbstatDevice] = Field(default_factory=list) # ibstat output
|
|
134
|
+
ibv_devices: List[IbvDeviceInfo] = Field(default_factory=list) # ibv_devinfo output
|
|
135
|
+
ibdev_netdev_mappings: List[IbdevNetdevMapping] = Field(
|
|
136
|
+
default_factory=list
|
|
137
|
+
) # ibdev2netdev output
|
|
138
|
+
ofed_info: Optional[OfedInfo] = None # OFED version info
|
|
139
|
+
mst_status: Optional[MstStatus] = None # MST status
|
|
140
|
+
rdma_info: Optional[RdmaInfo] = None # RDMA information
|
|
@@ -0,0 +1,28 @@
|
|
|
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 .journal_plugin import JournalPlugin
|
|
27
|
+
|
|
28
|
+
__all__ = ["JournalPlugin"]
|
|
@@ -0,0 +1,33 @@
|
|
|
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 typing import Optional
|
|
28
|
+
|
|
29
|
+
from nodescraper.models import CollectorArgs
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class JournalCollectorArgs(CollectorArgs):
|
|
33
|
+
boot: Optional[int] = None
|
|
@@ -0,0 +1,107 @@
|
|
|
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 pydantic import ValidationError
|
|
29
|
+
|
|
30
|
+
from nodescraper.base import InBandDataCollector
|
|
31
|
+
from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily
|
|
32
|
+
from nodescraper.models import TaskResult
|
|
33
|
+
from nodescraper.utils import get_exception_details
|
|
34
|
+
|
|
35
|
+
from .collector_args import JournalCollectorArgs
|
|
36
|
+
from .journaldata import JournalData
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class JournalCollector(InBandDataCollector[JournalData, JournalCollectorArgs]):
|
|
40
|
+
"""Read journal log via journalctl."""
|
|
41
|
+
|
|
42
|
+
SUPPORTED_OS_FAMILY = {OSFamily.LINUX}
|
|
43
|
+
DATA_MODEL = JournalData
|
|
44
|
+
CMD = "journalctl --no-pager --system --output=short-iso"
|
|
45
|
+
|
|
46
|
+
def _read_with_journalctl(self, args: Optional[JournalCollectorArgs] = None):
|
|
47
|
+
"""Read journal logs using journalctl
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
str|None: system journal read
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
cmd = "journalctl --no-pager --system --output=short-iso"
|
|
54
|
+
try:
|
|
55
|
+
# safe check for args.boot
|
|
56
|
+
if args is not None and getattr(args, "boot", None):
|
|
57
|
+
cmd = f"journalctl --no-pager -b {args.boot} --system --output=short-iso"
|
|
58
|
+
|
|
59
|
+
res = self._run_sut_cmd(cmd, sudo=True, log_artifact=False, strip=False)
|
|
60
|
+
|
|
61
|
+
except ValidationError as val_err:
|
|
62
|
+
self._log_event(
|
|
63
|
+
category=EventCategory.OS,
|
|
64
|
+
description="Exception while running journalctl",
|
|
65
|
+
data=get_exception_details(val_err),
|
|
66
|
+
priority=EventPriority.ERROR,
|
|
67
|
+
console_log=True,
|
|
68
|
+
)
|
|
69
|
+
self.result.message = "Could not read journalctl data"
|
|
70
|
+
self.result.status = ExecutionStatus.ERROR
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
if res.exit_code != 0:
|
|
74
|
+
self._log_event(
|
|
75
|
+
category=EventCategory.OS,
|
|
76
|
+
description="Error reading journalctl",
|
|
77
|
+
data={"command": res.command, "exit_code": res.exit_code},
|
|
78
|
+
priority=EventPriority.ERROR,
|
|
79
|
+
console_log=True,
|
|
80
|
+
)
|
|
81
|
+
self.result.message = "Could not read journalctl data"
|
|
82
|
+
self.result.status = ExecutionStatus.ERROR
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
return res.stdout
|
|
86
|
+
|
|
87
|
+
def collect_data(
|
|
88
|
+
self,
|
|
89
|
+
args: Optional[JournalCollectorArgs] = None,
|
|
90
|
+
) -> tuple[TaskResult, Optional[JournalData]]:
|
|
91
|
+
"""Collect journal logs
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
args (_type_, optional): Collection args. Defaults to None.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
tuple[TaskResult, Optional[JournalData]]: Tuple of results and data model or none.
|
|
98
|
+
"""
|
|
99
|
+
if args is None:
|
|
100
|
+
args = JournalCollectorArgs()
|
|
101
|
+
|
|
102
|
+
journal_log = self._read_with_journalctl(args)
|
|
103
|
+
if journal_log:
|
|
104
|
+
data = JournalData(journal_log=journal_log)
|
|
105
|
+
self.result.message = self.result.message or "Journal data collected"
|
|
106
|
+
return self.result, data
|
|
107
|
+
return self.result, None
|
|
@@ -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 JournalCollectorArgs
|
|
29
|
+
from .journal_collector import JournalCollector
|
|
30
|
+
from .journaldata import JournalData
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class JournalPlugin(InBandDataPlugin[JournalData, JournalCollectorArgs, None]):
|
|
34
|
+
"""Plugin for collection of journal data"""
|
|
35
|
+
|
|
36
|
+
DATA_MODEL = JournalData
|
|
37
|
+
|
|
38
|
+
COLLECTOR = JournalCollector
|
|
39
|
+
|
|
40
|
+
COLLECTOR_ARGS = JournalCollectorArgs
|
|
@@ -0,0 +1,44 @@
|
|
|
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 os
|
|
27
|
+
|
|
28
|
+
from nodescraper.models import DataModel
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class JournalData(DataModel):
|
|
32
|
+
"""Data model for journal logs"""
|
|
33
|
+
|
|
34
|
+
journal_log: str
|
|
35
|
+
|
|
36
|
+
def log_model(self, log_path: str):
|
|
37
|
+
"""Log data model to a file
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
log_path (str): log path
|
|
41
|
+
"""
|
|
42
|
+
log_name = os.path.join(log_path, "journal.log")
|
|
43
|
+
with open(log_name, "w", encoding="utf-8") as log_filename:
|
|
44
|
+
log_filename.write(self.journal_log)
|
|
@@ -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,64 @@
|
|
|
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 Union
|
|
27
|
+
|
|
28
|
+
from pydantic import Field, field_validator
|
|
29
|
+
|
|
30
|
+
from nodescraper.models import AnalyzerArgs
|
|
31
|
+
from nodescraper.plugins.inband.kernel.kerneldata import KernelDataModel
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class KernelAnalyzerArgs(AnalyzerArgs):
|
|
35
|
+
exp_kernel: Union[str, list] = Field(default_factory=list)
|
|
36
|
+
regex_match: bool = False
|
|
37
|
+
|
|
38
|
+
@field_validator("exp_kernel", mode="before")
|
|
39
|
+
@classmethod
|
|
40
|
+
def validate_exp_kernel(cls, exp_kernel: Union[str, list]) -> list:
|
|
41
|
+
"""support str or list input for exp_kernel
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
exp_kernel (Union[str, list]): exp kernel input
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
list: exp kernel list
|
|
48
|
+
"""
|
|
49
|
+
if isinstance(exp_kernel, str):
|
|
50
|
+
exp_kernel = [exp_kernel]
|
|
51
|
+
|
|
52
|
+
return exp_kernel
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def build_from_model(cls, datamodel: KernelDataModel) -> "KernelAnalyzerArgs":
|
|
56
|
+
"""build analyzer args from data model
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
datamodel (KernelDataModel): data model for plugin
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
KernelAnalyzerArgs: instance of analyzer args class
|
|
63
|
+
"""
|
|
64
|
+
return cls(exp_kernel=datamodel.kernel_version)
|
|
@@ -0,0 +1,91 @@
|
|
|
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 KernelAnalyzerArgs
|
|
34
|
+
from .kerneldata import KernelDataModel
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class KernelAnalyzer(DataAnalyzer[KernelDataModel, KernelAnalyzerArgs]):
|
|
38
|
+
"""Check kernel matches expected versions"""
|
|
39
|
+
|
|
40
|
+
DATA_MODEL = KernelDataModel
|
|
41
|
+
|
|
42
|
+
def analyze_data(
|
|
43
|
+
self, data: KernelDataModel, args: Optional[KernelAnalyzerArgs] = None
|
|
44
|
+
) -> TaskResult:
|
|
45
|
+
"""Analyze the kernel data against expected versions.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
data (KernelDataModel): Kernel data to analyze.
|
|
49
|
+
args (Optional[KernelAnalyzerArgs], optional): Kernel analysis arguments. Defaults to None.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
TaskResult: Result of the analysis containing status and message.
|
|
53
|
+
"""
|
|
54
|
+
if not args:
|
|
55
|
+
self.result.message = "Expected kernel not provided"
|
|
56
|
+
self.result.status = ExecutionStatus.NOT_RAN
|
|
57
|
+
return self.result
|
|
58
|
+
|
|
59
|
+
for kernel in args.exp_kernel:
|
|
60
|
+
if args.regex_match:
|
|
61
|
+
try:
|
|
62
|
+
regex_data = re.compile(kernel)
|
|
63
|
+
except re.error:
|
|
64
|
+
self._log_event(
|
|
65
|
+
category=EventCategory.RUNTIME,
|
|
66
|
+
description="Kernel regex is invalid",
|
|
67
|
+
data={"regex": kernel},
|
|
68
|
+
priority=EventPriority.ERROR,
|
|
69
|
+
)
|
|
70
|
+
continue
|
|
71
|
+
if regex_data.match(data.kernel_version):
|
|
72
|
+
self.result.message = "Kernel matches expected"
|
|
73
|
+
self.result.status = ExecutionStatus.OK
|
|
74
|
+
return self.result
|
|
75
|
+
elif data.kernel_version == kernel:
|
|
76
|
+
self.result.message = "Kernel matches expected"
|
|
77
|
+
self.result.status = ExecutionStatus.OK
|
|
78
|
+
return self.result
|
|
79
|
+
|
|
80
|
+
self.result.message = (
|
|
81
|
+
f"Kernel mismatch! Expected: {args.exp_kernel}, actual: {data.kernel_version}"
|
|
82
|
+
)
|
|
83
|
+
self.result.status = ExecutionStatus.ERROR
|
|
84
|
+
self._log_event(
|
|
85
|
+
category=EventCategory.OS,
|
|
86
|
+
description=f"{self.result.message}",
|
|
87
|
+
data={"expected": args.exp_kernel, "actual": data.kernel_version},
|
|
88
|
+
priority=EventPriority.CRITICAL,
|
|
89
|
+
console_log=True,
|
|
90
|
+
)
|
|
91
|
+
return self.result
|