2323# SOFTWARE.
2424#
2525###############################################################################
26+ import re
2627from typing import Optional
2728
2829from nodescraper .base import InBandDataCollector
@@ -37,7 +38,31 @@ class KernelCollector(InBandDataCollector[KernelDataModel, None]):
3738
3839 DATA_MODEL = KernelDataModel
3940 CMD_WINDOWS = "wmic os get Version /Value"
40- CMD = "sh -c 'uname -r'"
41+ CMD = "sh -c 'uname -a'"
42+
43+ def _parse_kernel_version (self , uname_a : str ) -> Optional [str ]:
44+ """Extract the kernel release from `uname -a` output.
45+
46+ Args:
47+ uname_a (str): The full output string from the `uname -a` command.
48+
49+ Returns:
50+ Optional[str]: The parsed kernel release (e.g., "5.13.0-30-generic")
51+ if found, otherwise None.
52+ """
53+ if not uname_a :
54+ return None
55+
56+ result = uname_a .strip ().split ()
57+ if len (result ) >= 3 :
58+ return result [2 ]
59+
60+ # if some change in output look for a version-like string (e.g. 4.18.0-553.el8_10.x86_64)
61+ match = re .search (r"\d+\.\d+\.\d+[\w\-\.]*" , uname_a )
62+ if match :
63+ return match .group (0 )
64+
65+ return None
4166
4267 def collect_data (
4368 self ,
@@ -51,16 +76,28 @@ def collect_data(
5176 """
5277
5378 kernel = None
79+ kernel_info = None
80+
5481 if self .system_info .os_family == OSFamily .WINDOWS :
5582 res = self ._run_sut_cmd (self .CMD_WINDOWS )
5683 if res .exit_code == 0 :
84+ kernel_info = res .stdout
5785 kernel = [line for line in res .stdout .splitlines () if "Version=" in line ][0 ].split (
5886 "="
5987 )[1 ]
6088 else :
6189 res = self ._run_sut_cmd (self .CMD )
6290 if res .exit_code == 0 :
63- kernel = res .stdout
91+ kernel_info = res .stdout
92+ kernel = self ._parse_kernel_version (kernel_info )
93+ if not kernel :
94+ self ._log_event (
95+ category = EventCategory .OS ,
96+ description = "Could not extract kernel version from 'uname -a'" ,
97+ data = {"command" : res .command , "exit_code" : res .exit_code },
98+ priority = EventPriority .ERROR ,
99+ console_log = True ,
100+ )
64101
65102 if res .exit_code != 0 :
66103 self ._log_event (
@@ -71,8 +108,9 @@ def collect_data(
71108 console_log = True ,
72109 )
73110
74- if kernel :
75- kernel_data = KernelDataModel (kernel_version = kernel )
111+ if kernel_info and kernel :
112+
113+ kernel_data = KernelDataModel (kernel_info = kernel_info , kernel_version = kernel )
76114 self ._log_event (
77115 category = "KERNEL_READ" ,
78116 description = "Kernel version read" ,
@@ -82,6 +120,10 @@ def collect_data(
82120 else :
83121 kernel_data = None
84122
85- self .result .message = f"Kernel: { kernel } " if kernel else "Kernel not found"
86- self .result .status = ExecutionStatus .OK if kernel else ExecutionStatus .ERROR
123+ self .result .message = (
124+ "Kernel not found"
125+ if not kernel_info
126+ else f"Kernel info: { kernel_info } | Kernel version: { kernel if kernel else 'Kernel version not found' } "
127+ )
128+ self .result .status = ExecutionStatus .OK if kernel_info else ExecutionStatus .ERROR
87129 return self .result , kernel_data
0 commit comments