Skip to content

Commit 31e96f4

Browse files
muhammadalihussnainnmoray
authored andcommitted
Fixed: Kdump Remote Patch (sonic-net#3835)
Link to all PRs of the KDUMP = KDUMP SONiC HLD PRs Related sonic-utilities: Fixing remote feature build failure Issue: There was a build failure for the remote variable in kdump-sonic-utilities PR Following were to be addressed, which are ADDRESSED in this PR ``` E 2025 Apr 1 04:56:08.321576 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--disable'] - failed: return code - 1, output:#012None E 2025 Apr 1 04:56:09.638838 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--memory', '0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M'] - failed: return code - 1, output:#012None E 2025 Apr 1 04:56:11.199498 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--num_dumps', '3'] - failed: return code - 1, output:#012None E 2025 Apr 1 04:56:13.969595 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--remote', 'false'] - failed: return code - 2, output:#012None E 2025 Apr 1 04:56:16.373762 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--ssh_string', 'user@localhost'] - failed: return code - 1, output:#012None E 2025 Apr 1 04:56:17.579657 vlab-02 ERR hostcfgd: ['sonic-kdump-config', '--ssh_path', '/a/b/c'] - failed: return code - 1, output:#012None
1 parent f204f99 commit 31e96f4

File tree

2 files changed

+107
-20
lines changed

2 files changed

+107
-20
lines changed

scripts/sonic-kdump-config

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,22 @@ def cmd_dump_db():
168168
else:
169169
print("empty")
170170

171+
def get_kdump_remote():
172+
"""Get the value of the remote feature from the KDUMP configuration."""
173+
config_db = ConfigDBConnector(use_unix_socket_path=True)
174+
if config_db is not None:
175+
config_db.connect()
176+
table_data = config_db.get_table('KDUMP')
177+
if table_data is not None:
178+
config_data = table_data.get('config')
179+
if config_data is not None:
180+
remote_value = config_data.get('remote')
181+
if remote_value is not None:
182+
# Return True if the remote value is 'true', otherwise False
183+
return remote_value.lower() == 'true' # Explicitly return boolean
184+
185+
return False # Default return value if no remote setting is found
186+
171187
def cmd_dump_config_json():
172188
kdump_enabled = get_kdump_administrative_mode()
173189
kdump_memory = get_kdump_memory()
@@ -320,22 +336,6 @@ def get_kdump_num_dumps():
320336
num_dumps = num
321337
return num_dumps
322338

323-
def get_kdump_remote():
324-
"""Get the value of the remote feature from the KDUMP configuration."""
325-
config_db = ConfigDBConnector(use_unix_socket_path=True)
326-
if config_db is not None:
327-
config_db.connect()
328-
table_data = config_db.get_table('KDUMP')
329-
if table_data is not None:
330-
config_data = table_data.get('config')
331-
if config_data is not None:
332-
remote_value = config_data.get('remote')
333-
if remote_value is not None:
334-
# Return True if the remote value is 'true', otherwise False
335-
return remote_value.lower() == 'true' # Explicitly return boolean
336-
337-
return False # Default return value if no remote setting is found
338-
339339
def get_kdump_ssh_string():
340340
"""Get the SSH string from the KDUMP configuration."""
341341
config_db = ConfigDBConnector(use_unix_socket_path=True)
@@ -433,7 +433,7 @@ def write_num_dumps(num_dumps):
433433
def write_kdump_remote():
434434
# Assuming there's a function that retrieves the remote value from the config database
435435
remote = get_kdump_remote() # This function needs to be implemented
436-
436+
437437
kdump_cfg = '/etc/default/kdump-tools'
438438

439439
if remote:
@@ -641,7 +641,7 @@ def cmd_kdump_config_next(verbose):
641641

642642

643643
def kdump_disable(verbose, image, booter_config_file_path):
644-
"""Unloads Kdump kernel and remove parameter `crashkernel=*` from configuration file of
644+
"""Unloads Kdump kernel and remove parameter `crashkernel=*` from configuration file of
645645
kernel boot loader.
646646
647647
Args:
@@ -826,11 +826,15 @@ def main():
826826
parser.add_argument('--num_dumps', nargs='?', type=int, action='store', default=False,
827827
help='Maximum number of kernel dump files stored')
828828

829+
parser.add_argument('--remote', action='store_true', default=False,
830+
help='Enable remote kdump via SSH')
831+
829832
parser.add_argument('--ssh_string', nargs='?', type=str, action='store', default=False,
830833
help='ssh_string for remote kdump')
831834

832835
parser.add_argument('--ssh_path', nargs='?', type=str, action='store',default=False,
833836
help='ssh_path for remote kdump')
837+
834838
# Memory allocated for capture kernel on Current Image
835839
parser.add_argument('--memory', nargs='?', type=str, action='store', default=False,
836840
help='Amount of memory reserved for the capture kernel')

tests/sonic_kdump_config_test.py

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import unittest
55
from unittest.mock import patch, mock_open, Mock
66
from utilities_common.general import load_module_from_source
7-
87
from sonic_installer.common import IMAGE_PREFIX
8+
import argparse
99

1010
TESTS_DIR_PATH = os.path.dirname(os.path.abspath(__file__))
1111
UTILITY_DIR_PATH = os.path.dirname(TESTS_DIR_PATH)
@@ -23,6 +23,32 @@
2323
sonic_kdump_config = load_module_from_source("sonic_kdump_config", sonic_kdump_config_path)
2424

2525

26+
class TestRemoteFlag(unittest.TestCase):
27+
def setUp(self):
28+
# Create a new ArgumentParser for each test
29+
self.parser = argparse.ArgumentParser(description="kdump configuration and status tool")
30+
self.parser.add_argument('--remote', action='store_true', default=False,
31+
help='Enable the Kdump remote SSH mechanism')
32+
33+
def test_remote_flag_provided(self):
34+
"""Test that the --remote flag sets the remote attribute to True."""
35+
with patch.object(sys, 'argv', ['script.py', '--remote']):
36+
args = self.parser.parse_args()
37+
self.assertTrue(args.remote)
38+
39+
def test_remote_flag_not_provided(self):
40+
"""Test that the --remote flag defaults to False when not provided."""
41+
with patch.object(sys, 'argv', ['script.py']):
42+
args = self.parser.parse_args()
43+
self.assertFalse(args.remote)
44+
45+
def test_remote_flag_with_value(self):
46+
"""Test that providing a value to the --remote flag raises an error."""
47+
with patch.object(sys, 'argv', ['script.py', '--remote', 'some_value']):
48+
with self.assertRaises(SystemExit):
49+
self.parser.parse_args()
50+
51+
2652
class TestSonicKdumpConfig(unittest.TestCase):
2753
@classmethod
2854
def setup_class(cls):
@@ -246,7 +272,7 @@ def test_cmd_kdump_ssh_string_none(self, mock_print, mock_read, mock_run):
246272
def test_cmd_kdump_ssh_string_update(self, mock_print, mock_write, mock_read, mock_run):
247273
# Mock read_ssh_string to return the current SSH string
248274
mock_read.return_value = 'old_ssh_string'
249-
# Call the function with a new SSH string
275+
# Call the function with a new SSH string to configure
250276
sonic_kdump_config.cmd_kdump_ssh_string(verbose=True, ssh_string='new_ssh_string')
251277

252278
# Check that write_ssh_string was called with the new SSH string
@@ -302,6 +328,63 @@ def test_cmd_kdump_disable(self, mock_path_exist, mock_num_dumps, mock_memory,
302328
return_result = sonic_kdump_config.cmd_kdump_disable(True)
303329
assert return_result == False
304330

331+
@patch("sonic_kdump_config.read_num_dumps")
332+
@patch("sonic_kdump_config.run_command")
333+
def test_write_num_dumps(self, mock_run_cmd, mock_read_num_dumps):
334+
# Success case: correct write and verification
335+
mock_run_cmd.side_effect = [(0, [], None)]
336+
mock_read_num_dumps.return_value = 5
337+
sonic_kdump_config.write_num_dumps(5)
338+
339+
# Case where run_command returns wrong type
340+
mock_run_cmd.side_effect = [(0, (), None)]
341+
mock_read_num_dumps.return_value = 5
342+
with self.assertRaises(SystemExit) as sys_exit:
343+
sonic_kdump_config.write_num_dumps(5)
344+
self.assertEqual(sys_exit.exception.code, 1)
345+
346+
# Case where line is non-empty
347+
mock_run_cmd.side_effect = [(0, ["Some output"], None)]
348+
mock_read_num_dumps.return_value = 5
349+
with self.assertRaises(SystemExit) as sys_exit:
350+
sonic_kdump_config.write_num_dumps(5)
351+
self.assertEqual(sys_exit.exception.code, 1)
352+
353+
# Case where read_num_dumps does not match input
354+
mock_run_cmd.side_effect = [(0, [], None)]
355+
mock_read_num_dumps.return_value = 4
356+
with self.assertRaises(SystemExit) as sys_exit:
357+
sonic_kdump_config.write_num_dumps(5)
358+
self.assertEqual(sys_exit.exception.code, 1)
359+
360+
# Case where run_command fails
361+
mock_run_cmd.side_effect = [(1, [], "Error")]
362+
mock_read_num_dumps.return_value = 5
363+
with self.assertRaises(SystemExit) as sys_exit:
364+
sonic_kdump_config.write_num_dumps(5)
365+
self.assertEqual(sys_exit.exception.code, 1)
366+
367+
# Case where lines contain non-integer
368+
mock_run_cmd.side_effect = [(0, ["NotInteger"], None)]
369+
mock_read_num_dumps.return_value = 5
370+
with self.assertRaises(SystemExit) as sys_exit:
371+
sonic_kdump_config.write_num_dumps(5)
372+
self.assertEqual(sys_exit.exception.code, 1)
373+
374+
# Edge case: empty string in output but matches value
375+
mock_run_cmd.side_effect = [(0, [""], None)]
376+
mock_read_num_dumps.return_value = 5
377+
with self.assertRaises(SystemExit) as sys_exit:
378+
sonic_kdump_config.write_num_dumps(5)
379+
self.assertEqual(sys_exit.exception.code, 1)
380+
381+
# Edge case: read_num_dumps returns matching value but run_command fails
382+
mock_run_cmd.side_effect = [(2, [], None)]
383+
mock_read_num_dumps.return_value = 5
384+
with self.assertRaises(SystemExit) as sys_exit:
385+
sonic_kdump_config.write_num_dumps(5)
386+
self.assertEqual(sys_exit.exception.code, 1)
387+
305388
@patch("sonic_kdump_config.get_bootloader")
306389
def test_get_image(self, mock_get_bootloader):
307390
"""Tests the function `get_current_image() and get_next_image()` in script `sonic-kdump-config.py`.

0 commit comments

Comments
 (0)