Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kdump enhancement for remote ssh, cli subcommands added. #3317

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
9cb79de
changes so far for the kdump new attributes for remote ssh usecase
bilal-ismail May 6, 2024
8b1c9ce
Merge remote-tracking branch 'origin/master' into kdump_cli_updates
bilal-ismail May 6, 2024
4e6d827
Merge branch 'master' of https://github.com/bilal-ismail/sonic-utilit…
bilal-ismail May 7, 2024
718aa95
interim changes saved to kdump-CLI modifications
bilal-ismail May 7, 2024
ab41345
changes for incorporating remote ssh commands for sonic cli
bilal-ismail May 12, 2024
a6c8a57
Merge branch 'master' of https://github.com/bilal-ismail/sonic-utilit…
bilal-ismail May 12, 2024
6ecf018
changed the version of tabulate from 0.9.0 to a range flexible "tabu…
bilal-ismail May 12, 2024
3466128
slight improvements and changes in config/kdump.py to incorporate new…
bilal-ismail May 12, 2024
b28973b
arguments error corrected for remote subcommand
bilal-ismail May 12, 2024
56049df
Comments Added
Ghulam-Bahoo May 13, 2024
d569767
Comments Add
Ghulam-Bahoo May 13, 2024
4353241
Comments Add
Ghulam-Bahoo May 13, 2024
d3f0024
Indentation
Ghulam-Bahoo May 13, 2024
ec47095
Edited Function Name
Ghulam-Bahoo May 13, 2024
0ff3c06
Edited Function Name
Ghulam-Bahoo May 13, 2024
7fb33f1
Edited Function Name
Ghulam-Bahoo May 13, 2024
83ad22e
Added a check
Ghulam-Bahoo May 14, 2024
18c64de
Added a check
Ghulam-Bahoo May 14, 2024
c707840
Added a check
Ghulam-Bahoo May 14, 2024
68e8694
Added a check
Ghulam-Bahoo May 14, 2024
c9b2e01
Error Correction
Ghulam-Bahoo Jun 4, 2024
630f389
Merge branch 'master' into kdump_cli_updates
Ghulam-Bahoo Jun 4, 2024
f4bf076
Error Correction
Ghulam-Bahoo Jun 4, 2024
d95aa96
Merge branch 'kdump_cli_updates' of https://github.com/bilal-ismail/s…
Ghulam-Bahoo Jun 4, 2024
1f2032d
Comments added
Ghulam-Bahoo Jun 5, 2024
0f7ae2b
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
5396445
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
64f24d8
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
172946b
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
56f993c
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
ff2b6f8
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
12d522e
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
15a8986
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
d1009eb
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
2981516
Function Definition Corrected
Ghulam-Bahoo Jun 7, 2024
5813750
Function Definitaion Corrected
Ghulam-Bahoo Jun 10, 2024
f036e9f
Logic Change
Ghulam-Bahoo Jun 25, 2024
3410fe8
Logic Change
Ghulam-Bahoo Jun 25, 2024
99bfcaf
Logic Change
Ghulam-Bahoo Jun 25, 2024
20ef800
Logic Change
Ghulam-Bahoo Jun 25, 2024
fb0fa89
Logic Change
Ghulam-Bahoo Jun 25, 2024
9afc1c6
Logic Change
Ghulam-Bahoo Jun 25, 2024
53caf17
Logic Change
Ghulam-Bahoo Jun 25, 2024
7127f57
Logic Change
Ghulam-Bahoo Jun 25, 2024
8769003
Logic Change
Ghulam-Bahoo Jun 25, 2024
26a112f
Logic Change
Ghulam-Bahoo Jun 25, 2024
876c8e3
Function Defination Corrected
Ghulam-Bahoo Jul 4, 2024
ff14966
Function Defination Corrected
Ghulam-Bahoo Jul 4, 2024
2ea76f5
Function Defination Corrected
Ghulam-Bahoo Jul 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion config/kdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def kdump_memory(db, kdump_memory):


#
# 'num_dumps' command ('sudo config keump num_dumps ...')
# 'num_dumps' command ('sudo config kdump num_dumps ...')
#
@kdump.command(name="num_dumps", short_help="Configure the maximum dump files of KDUMP mechanism")
@click.argument('kdump_num_dumps', metavar='<kdump_num_dumps>', required=True, type=int)
Expand All @@ -90,3 +90,39 @@ def kdump_num_dumps(db, kdump_num_dumps):
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"num_dumps": kdump_num_dumps})


@kdump.command(name="remote", short_help="Configure remote KDUMP mechanism")
@click.argument("action", type=click.Choice(["ssh", "disable"]))
@click.option("-c", "ssh_connection_string",
metavar='<kdump_ssh_connection_string>',
help="SSH user and host. e.g user@hostname/ip")
@click.option("-p", "ssh_private_key_path",
metavar='<kdump_ssh_private_key_file_path>',
help="Path to private key. e.g /root/.ssh/kdump_id_rsa")
@pass_db
def kdump_remote(db, action, ssh_connection_string, ssh_private_key_path):
"""Configure remote KDUMP mechanism"""

# Ensure the KDUMP table and 'config' key exist
kdump_table = db.cfgdb.get_table("KDUMP")
check_kdump_table_existence(kdump_table)

if action == "ssh":
# Validate arguments for SSH configuration
if ssh_connection_string is None or ssh_private_key_path is None:
click.echo("Error: Both --ssh-connection-string and --ssh-private-key-path\
\are required for SSH configuration.")
sys.exit(1)

db.cfgdb.mod_entry("KDUMP", "config", {"remote_enabled": "true"})
if ssh_connection_string is not None:
db.cfgdb.mod_entry("KDUMP", "config", {"ssh_connection_string": ssh_connection_string})
if ssh_private_key_path is not None:
db.cfgdb.mod_entry("KDUMP", "config", {"ssh_private_key_path": ssh_private_key_path})
elif action == "disable":
# Set remote_enabled to "false"
db.cfgdb.mod_entry("KDUMP", "config", {"remote_enabled": "false"})

click.echo("KDUMP configuration changes may require a reboot to take effect.")
click.echo("Save SONiC configuration using 'config save' before issuing the reboot command.")
218 changes: 214 additions & 4 deletions scripts/sonic-kdump-config
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import sys
import syslog
import subprocess

from swsssdk import ConfigDBConnector
from swsscommon.swsscommon import ConfigDBConnector
from sonic_installer.bootloader import get_bootloader
from sonic_installer.common import IMAGE_PREFIX
Expand Down Expand Up @@ -172,9 +173,16 @@ def cmd_dump_config_json():
kdump_enabled = get_kdump_administrative_mode()
kdump_memory = get_kdump_memory()
kdump_num_dumps = get_kdump_num_dumps()
# remote SSH variables
ssh_connection_string = get_ssh_connection_string()
ssh_private_key_path = get_ssh_private_key_path()
kdump_remote_enabled = get_kdump_remote_enabled()
data = { "enable" : kdump_enabled, \
"memory" : kdump_memory, \
"max-dumps" : int(kdump_num_dumps) }
"max-dumps" : int(kdump_num_dumps), \
"ssh_connection_string" : str(ssh_connection_string), \
"ssh_private_key-path" : str(ssh_private_key_path), \
"remote_enabled" : kdump_remote_enabled }
print(json.dumps(data, indent=4))

def cmd_dump_kdump_records_json():
Expand Down Expand Up @@ -223,11 +231,18 @@ def cmd_dump_status_json():
kdump_oper_state = get_kdump_oper_mode(kdump_enabled)
kdump_memory = get_kdump_memory()
kdump_num_dumps = get_kdump_num_dumps()
# remote SSH variables
ssh_connection_string = get_ssh_connection_string()
ssh_private_key_path = get_ssh_private_key_path()
kdump_remote_enabled = get_kdump_remote_enabled()
data = { "enable" : kdump_enabled, \
"current-state" : kdump_oper_state, \
"memory" : kdump_memory, \
"allocated-memory" : get_crash_kernel_size(), \
"max-dumps" : int(kdump_num_dumps) }
"max-dumps" : int(kdump_num_dumps), \
"ssh-connection-string" : str(ssh_connection_string), \
"ssh-private-key-path" : str(ssh_private_key_path), \
"remote-enabled" : kdump_remote_enabled }
print(json.dumps(data, indent=4))

## Query current configuration to check if kdump is enabled or disabled
Expand Down Expand Up @@ -299,6 +314,62 @@ def get_kdump_num_dumps():
num_dumps = num
return num_dumps

## Query current configuration for kdump ssh_connection_string
#
# @return The ssh remote connection string for storing kernel dump files remotely
# (read from running configuration)
def get_ssh_connection_string():
ssh_connection_string = "user@ip/hostname --default, please change--"
config_db = ConfigDBConnector(use_unix_socket_path=True)
if config_db is not None:
config_db.connect()
table_data = config_db.get_table('KDUMP')
if table_data is not None:
config_data = table_data.get('config')
if config_data is not None:
conn = config_data.get('ssh_connection_string')
if conn:
ssh_connection_string = conn
return ssh_connection_string

## Query current configuration for kdump ssh_private_key_path
#
# @return The ssh remote connection private_key_file_path for connecting to remote server without authentication (command "sudo kdump-config propagate" required)
# (read from running configuration)
def get_ssh_private_key_path():
ssh_private_key_path = "/root/.ssh/kdump_id_rsa --default, please change--"
config_db = ConfigDBConnector(use_unix_socket_path=True)
if config_db is not None:
config_db.connect()
table_data = config_db.get_table('KDUMP')
if table_data is not None:
config_data = table_data.get('config')
if config_data is not None:
pr_key_path = config_data.get('ssh_private_key_path')
if pr_key_path:
ssh_private_key_path = pr_key_path
return ssh_private_key_path

## Query current configuration for kdump remote_enabled
#
# @return The if remote connection is enabled for connecting to remote server
# (read from running configuration)
def get_kdump_remote_enabled():
remote_enabled = False
config_db = ConfigDBConnector(use_unix_socket_path=True)
if config_db is not None:
config_db.connect()
table_data = config_db.get_table('KDUMP')
if table_data is not None:
config_data = table_data.get('config')
if config_data is not None:
remote_en = config_data.get('remote_enabled')
if remote_en:
remote_enabled = remote_en
return remote_enabled



## Read current value for USE_KDUMP in kdump config file
#
# @return The integer value X from USE_KDUMP=X in /etc/default/kdump-tools
Expand Down Expand Up @@ -362,6 +433,138 @@ def write_num_dumps(num_dumps):
print_err("Error while writing KDUMP_NUM_DUMPS into %s" % kdump_cfg)
sys.exit(1)

## Read current value for SSH SSH kdump-ssh-connection-string in kdump config file
#
# @return The string value X from SSH=X in /etc/default/kdump-tools
def read_ssh_connection_string_from_db():
config_db = ConfigDBConnector(use_unix_socket_path=True)
config_db.connect()

kdump_table = config_db.get_table('KDUMP')
if kdump_table:
config_data = kdump_table.get('config')
if config_data:
return config_data.get('ssh_connection_string')
return None

## Change the value for SSH kdump-ssh-connection-string in kdump config file /etc/default/kdump-tools
#
# #param ssh-connection-string value for new value
def write_ssh_connection_string_to_kdump_tools():
ssh_connection_string = read_ssh_connection_string_from_db()
if not ssh_connection_string:
print("Error: SSH connection string not found in Config DB.")
return False

try:
# Use sed to update the SSH connection string in the kdump-tools file
subprocess.run(['sudo', 'sed', '-i', 's/#SSH=.*/SSH="{}"/g'.format(ssh_connection_string), kdump_cfg], check=True)

return True
except Exception as e:
print("Error: Unable to write to {}. Exception: {}".format(kdump_cfg, str(e)))
return False


## Read current value for SSH_KEY kdump-ssh-private-key-path in kdump config file
#
# @return The string value X from SSH_KEY=X in /etc/default/kdump-tools
def read_ssh_private_key_path(kdump_cfg="/etc/default/kdump-tools"):
"""Reads the SSH private key path from the kdump configuration file.

Args:
kdump_cfg (str, optional): The path to the kdump configuration file.
Defaults to "/etc/default/kdump-tools".

Returns:
str: The extracted SSH private key path from the file or None if not found.
Raises:
Exception: If there's an error running the grep command.
"""

try:
# Construct the full command string safely
command = f"grep '#*SSH_KEY=.*' {kdump_cfg} | cut -d = -f 2"

# Use subprocess.run without shell execution
output = subprocess.run(
command.split(), capture_output=True, text=True, check=True
).stdout.strip()

if output:
return output # Existing SSH private key path found
else:
return None # No matching line found

except subprocess.CalledProcessError as e:
raise Exception(f"Error reading SSH private key path from {kdump_cfg}: {str(e)}")


def write_ssh_private_key_path(ssh_private_key_path, kdump_cfg="/etc/default/kdump-tools"):
"""Writes the SSH private key path to the kdump configuration file.

Args:
ssh_private_key_path (str): The SSH private key path to write.
kdump_cfg (str, optional): The path to the kdump configuration file.
Defaults to "/etc/default/kdump-tools".

Raises:
Exception: If there's an error writing to the file.
"""

try:
# Construct the full command string safely
command = f"sed -i 's/#*SSH_KEY=.*$/SSH_KEY={ssh_private_key_path}/' {kdump_cfg}"

# Use subprocess.run without shell execution
subprocess.run(command.split(), check=True)

except subprocess.CalledProcessError as e:
raise Exception(f"Error writing SSH private key path to {kdump_cfg}: {str(e)}")


# Example usage
ssh_private_key_path = get_ssh_private_key_path()

# Write the retrieved value to kdump_cfg only if it's not the default value
if ssh_private_key_path != "/root/.ssh/kdump_id_rsa --default, please change--":
write_ssh_private_key_path(ssh_private_key_path)

# Now you can potentially read the written value using read_ssh_private_key_path(kdump_cfg)

## Disable remote: Comment the value for SSH and SSH_KEY in kdump config file /etc/default/kdump-tools
#
def kdump_remote_disable():
"""
Disables remote kdump in the configuration file (kdump_cfg).

This function checks if remote kdump is already enabled before attempting
to disable it. If enabled, it uses sed to modify the configuration file
in-place, removing any comment character (#) before the SSH and SSH_KEY lines.
The function exits with an error message if any of the sed commands fail.

Returns:
None
"""

# Check if remote kdump is already enabled
if get_kdump_remote_enabled().lower() == "true":
# Disable SSH key authentication
rc = run_command("/bin/sed -i '/*SSH=\"/s/\#/' %s" % (kdump_cfg), use_shell=False)
if rc != 0:
print_err("Error while disabling SSH key auth in", kdump_cfg)
sys.exit(1)

# Disable SSH authentication (optional, depending on configuration)
rc = run_command("/bin/sed -i '/*SSH_KEY=\"/s/\#/' %s" % (kdump_cfg), use_shell=False)
if rc != 0:
print_err("Error while disabling SSH auth in", kdump_cfg)
sys.exit(1)

print("Successfully disabled remote kdump in", kdump_cfg)
else:
print("Remote kdump is already disabled in", kdump_cfg)

## Enable kdump
#
# @param verbose If True, the function will display a few additinal information
Expand Down Expand Up @@ -417,7 +620,7 @@ def kdump_enable(verbose, kdump_enabled, memory, num_dumps, image, cmdline_file)

## Read kdump configuration saved in the startup configuration file
#
# @param config_param If True, the function will display a few additional information
# @param config_param If True, the function will display a few additional information.
# @return Value of the configuration parameter saved in the startup configuration file
# @return None if the startup configuration file does not exist or the kdump
# configuration parameter is not present in the file.
Expand Down Expand Up @@ -448,8 +651,15 @@ def cmd_kdump_enable(verbose, image):
kdump_enabled = get_kdump_administrative_mode()
memory = get_kdump_memory()
num_dumps = get_kdump_num_dumps()

##
# ToDo - 02
##
ssh_connection_string = get_ssh_connection_string()
ssh_private_key_path = get_ssh_private_key_path()
remote_enabled = get_kdump_remote_enabled()
if verbose:
print("configDB: kdump_enabled=%d memory=[%s] num_nums=%d" % (kdump_enabled, memory, num_dumps))
print("configDB: kdump_enabled=%d memory=[%s] num_nums=%d ssh_connection_string=%d ssh_private_key_path=%d remote_enabled=%d" % (kdump_enabled, memory, num_dumps, ssh_connection_string, ssh_private_key_path, remote_enabled))

if os.path.exists(grub_cfg):
return kdump_enable(verbose, kdump_enabled, memory, num_dumps, image, grub_cfg)
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@
'semantic-version>=2.8.5',
'prettyprinter>=0.18.0',
'pyroute2>=0.5.14, <0.6.1',
'requests>=2.25.0',
'tabulate>=0.8.2,<=0.9.0',
'requests>=2.25.0, <=2.31.0',
'tabulate==0.9.0',
'toposort==1.6',
Expand Down
8 changes: 8 additions & 0 deletions show/kdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ def config():
num_files_config = get_kdump_config("num_dumps")
click.echo("Maximum number of Kdump files: {}".format(num_files_config))

# remote SSH configs
if get_kdump_config("remote_enabled") == "true":
ssh_conn_str = get_kdump_config("ssh_connection_string")
click.echo("Kdump remote server user@ip/hostname: {}".format(ssh_conn_str))

ssh_prv_key = get_kdump_config("ssh_private_key_path")
click.echo("Kdump private key file path for remote ssh connection: {}".format(ssh_prv_key))


def get_kdump_core_files():
"""Retrieves the kernel core dump files from directory '/var/crash/'.
Expand Down
1 change: 1 addition & 0 deletions sonic-utilities-forked
Submodule sonic-utilities-forked added at b28973
Loading