Skip to content

Commit 41e0a24

Browse files
committed
moved data into datamodel
1 parent 44558bb commit 41e0a24

File tree

3 files changed

+434
-13
lines changed

3 files changed

+434
-13
lines changed

nodescraper/plugins/inband/kernel_module/kernel_module_collector.py

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily
3232
from nodescraper.models import TaskResult
3333

34-
from .kernel_module_data import KernelModuleDataModel
34+
from .kernel_module_data import KernelModuleDataModel, ModuleInfo, ModuleParameter
3535

3636

3737
class KernelModuleCollector(InBandDataCollector[KernelModuleDataModel, None]):
@@ -62,6 +62,77 @@ def parse_proc_modules(self, output: dict) -> dict:
6262
}
6363
return modules
6464

65+
def _parse_modinfo(self, output: str) -> Optional[ModuleInfo]:
66+
"""Parse modinfo command output into structured ModuleInfo
67+
68+
Args:
69+
output (str): modinfo command output
70+
71+
Returns:
72+
Optional[ModuleInfo]: parsed module information or None if parsing fails
73+
"""
74+
if not output or not output.strip():
75+
return None
76+
77+
module_info = ModuleInfo()
78+
79+
for line in output.splitlines():
80+
line = line.strip()
81+
if not line or ":" not in line:
82+
continue
83+
84+
field, _, value = line.partition(":")
85+
field = field.strip()
86+
value = value.strip()
87+
88+
if field == "filename":
89+
module_info.filename = value
90+
elif field == "version":
91+
module_info.version = value
92+
elif field == "license":
93+
module_info.license = value
94+
elif field == "description":
95+
module_info.description = value
96+
elif field == "author":
97+
module_info.author.append(value)
98+
elif field == "firmware":
99+
module_info.firmware.append(value)
100+
elif field == "srcversion":
101+
module_info.srcversion = value
102+
elif field == "depends":
103+
if value:
104+
module_info.depends = [dep.strip() for dep in value.split(",") if dep.strip()]
105+
elif field == "name":
106+
module_info.name = value
107+
elif field == "vermagic":
108+
module_info.vermagic = value
109+
elif field == "sig_id":
110+
module_info.sig_id = value
111+
elif field == "signer":
112+
module_info.signer = value
113+
elif field == "sig_key":
114+
module_info.sig_key = value
115+
elif field == "sig_hashalgo":
116+
module_info.sig_hashalgo = value
117+
elif field == "parm":
118+
param_name, param_desc = value.split(":", 1) if ":" in value else (value, "")
119+
param_name = param_name.strip()
120+
param_desc = param_desc.strip()
121+
122+
param_type = None
123+
if param_desc and "(" in param_desc and ")" in param_desc:
124+
type_start = param_desc.rfind("(")
125+
type_end = param_desc.rfind(")")
126+
if type_start < type_end:
127+
param_type = param_desc[type_start + 1 : type_end].strip()
128+
param_desc = param_desc[:type_start].strip()
129+
130+
module_info.parm.append(
131+
ModuleParameter(name=param_name, type=param_type, description=param_desc)
132+
)
133+
134+
return module_info
135+
65136
def get_module_parameters(self, module_name: str) -> dict:
66137
"""Fetches parameter names and values for a given kernel module using _run_sut_cmd
67138
@@ -145,12 +216,23 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[KernelModuleData
145216
else:
146217
kernel_modules = self.collect_all_module_info()
147218

148-
# Collect modinfo amdgpu output as artifact
219+
amdgpu_modinfo = None
220+
if self.system_info.os_family != OSFamily.WINDOWS:
221+
# Collect and parse modinfo amdgpu output
149222
modinfo_res = self._run_sut_cmd(self.CMD_MODINFO_AMDGPU)
150223
if modinfo_res.exit_code == 0 and modinfo_res.stdout:
151-
self.result.artifacts.append(
152-
TextFileArtifact(filename="modinfo_amdgpu.txt", contents=modinfo_res.stdout)
153-
)
224+
amdgpu_modinfo = self._parse_modinfo(modinfo_res.stdout)
225+
if amdgpu_modinfo:
226+
self.result.artifacts.append(
227+
TextFileArtifact(filename="modinfo_amdgpu.txt", contents=modinfo_res.stdout)
228+
)
229+
else:
230+
self._log_event(
231+
category=EventCategory.OS,
232+
description="Could not parse modinfo amdgpu output",
233+
data={"command": modinfo_res.command},
234+
priority=EventPriority.WARNING,
235+
)
154236
else:
155237
self._log_event(
156238
category=EventCategory.OS,
@@ -164,7 +246,9 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[KernelModuleData
164246
)
165247

166248
if kernel_modules:
167-
km_data = KernelModuleDataModel(kernel_modules=kernel_modules)
249+
km_data = KernelModuleDataModel(
250+
kernel_modules=kernel_modules, amdgpu_modinfo=amdgpu_modinfo
251+
)
168252
self._log_event(
169253
category="KERNEL_READ",
170254
description="Kernel modules read",

nodescraper/plugins/inband/kernel_module/kernel_module_data.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,37 @@
2424
#
2525
###############################################################################
2626

27+
from typing import Optional
28+
29+
from pydantic import BaseModel, Field
30+
2731
from nodescraper.models import DataModel
2832

2933

34+
class ModuleParameter(BaseModel):
35+
name: str
36+
type: Optional[str] = None
37+
description: Optional[str] = None
38+
39+
40+
class ModuleInfo(BaseModel):
41+
filename: Optional[str] = None
42+
version: Optional[str] = None
43+
license: Optional[str] = None
44+
description: Optional[str] = None
45+
author: list[str] = Field(default_factory=list)
46+
firmware: list[str] = Field(default_factory=list)
47+
srcversion: Optional[str] = None
48+
depends: list[str] = Field(default_factory=list)
49+
name: Optional[str] = None
50+
vermagic: Optional[str] = None
51+
sig_id: Optional[str] = None
52+
signer: Optional[str] = None
53+
sig_key: Optional[str] = None
54+
sig_hashalgo: Optional[str] = None
55+
parm: list[ModuleParameter] = Field(default_factory=list)
56+
57+
3058
class KernelModuleDataModel(DataModel):
3159
kernel_modules: dict
60+
amdgpu_modinfo: Optional[ModuleInfo] = None

0 commit comments

Comments
 (0)