diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 167913b5..a3ee84ee 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -26,6 +26,7 @@ from typing import Optional from nodescraper.base import InBandDataCollector +from nodescraper.connection.inband import TextFileArtifact from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult @@ -40,6 +41,7 @@ class DimmCollector(InBandDataCollector[DimmDataModel, DimmCollectorArgs]): CMD_WINDOWS = "wmic memorychip get Capacity" CMD = """sh -c 'dmidecode -t 17 | tr -s " " | grep -v "Volatile\\|None\\|Module" | grep Size' 2>/dev/null""" + CMD_DMIDECODE_FULL = "dmidecode" def collect_data( self, @@ -72,6 +74,25 @@ def collect_data( self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None + + # Collect full dmidecode output as artifact + dmidecode_full_res = self._run_sut_cmd(self.CMD_DMIDECODE_FULL, sudo=True) + if dmidecode_full_res.exit_code == 0 and dmidecode_full_res.stdout: + self.result.artifacts.append( + TextFileArtifact(filename="dmidecode.txt", contents=dmidecode_full_res.stdout) + ) + else: + self._log_event( + category=EventCategory.OS, + description="Could not collect full dmidecode output", + data={ + "command": dmidecode_full_res.command, + "exit_code": dmidecode_full_res.exit_code, + "stderr": dmidecode_full_res.stderr, + }, + priority=EventPriority.WARNING, + ) + res = self._run_sut_cmd(self.CMD, sudo=True) if res.exit_code == 0: total = 0 diff --git a/test/unit/plugin/test_dimms_collector.py b/test/unit/plugin/test_dimms_collector.py index ac7aa98d..eeaa15ff 100644 --- a/test/unit/plugin/test_dimms_collector.py +++ b/test/unit/plugin/test_dimms_collector.py @@ -68,10 +68,16 @@ def test_run_linux(collector, system_info): system_info.os_family = OSFamily.LINUX collector._run_sut_cmd = MagicMock( - return_value=MagicMock( - exit_code=0, - stdout="Size: 64 GB\nSize: 64 GB\nSize: 128 GB\n", - ) + side_effect=[ + MagicMock( + exit_code=0, + stdout="Full dmidecode output...", + ), + MagicMock( + exit_code=0, + stdout="Size: 64 GB\nSize: 64 GB\nSize: 128 GB\n", + ), + ] ) result, data = collector.collect_data() @@ -84,15 +90,23 @@ def test_run_linux_error(collector, system_info): system_info.os_family = OSFamily.LINUX collector._run_sut_cmd = MagicMock( - return_value=MagicMock( - exit_code=1, - stderr="Error occurred", - ) + side_effect=[ + MagicMock( + exit_code=1, + stderr="Error occurred", + command="dmidecode", + ), + MagicMock( + exit_code=1, + stderr="Error occurred", + command="sh -c 'dmidecode -t 17 | ...'", + ), + ] ) result, data = collector.collect_data() assert result.status == ExecutionStatus.ERROR assert data is None - assert result.events[0].category == EventCategory.OS.value - assert result.events[0].description == "Error checking dimms" + assert result.events[1].category == EventCategory.OS.value + assert result.events[1].description == "Error checking dimms"