From d3d3d79f4007d78ffc19d8ba57eb1605386b5233 Mon Sep 17 00:00:00 2001 From: Adam King Date: Wed, 4 Jun 2025 16:12:32 -0400 Subject: [PATCH] cephadm: add command to send signals to daemons This command figures out the container id for the daemon based on the given name and then uses a docker/podman to send that signal to the container Signed-off-by: Adam King --- src/cephadm/cephadm.py | 30 ++++++++++++++++++++ src/cephadm/cephadmlib/signals.py | 47 +++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/cephadm/cephadmlib/signals.py diff --git a/src/cephadm/cephadm.py b/src/cephadm/cephadm.py index 95cdcc28eae6d..38c521303ed6e 100755 --- a/src/cephadm/cephadm.py +++ b/src/cephadm/cephadm.py @@ -138,6 +138,7 @@ from cephadmlib.logging import ( ) from cephadmlib.systemd import check_unit, check_units, terminate_service, enable_service from cephadmlib import systemd_unit +from cephadmlib.signals import send_signal_to_container_entrypoint from cephadmlib import runscripts from cephadmlib.container_types import ( CephContainer, @@ -3256,6 +3257,17 @@ def command_unit(ctx: CephadmContext) -> int: ) return code + +@infer_fsid +def command_signal(ctx: CephadmContext) -> int: + if not ctx.fsid: + raise Error('must pass --fsid to specify cluster') + + container_name = DaemonIdentity.from_name(ctx.fsid, ctx.name).container_name + + return send_signal_to_container_entrypoint(ctx, container_name, ctx.signal_name or ctx.signal_number) + + ################################## @@ -4851,6 +4863,24 @@ def _get_parser(): help='cluster FSID') _name_opts(parser_unit_install) + parser_signal = subparsers.add_parser( + 'signal', help='Send signal to entrypoint of containerized daemon') + parser_signal.set_defaults(func=command_signal) + signal_group = parser_signal.add_mutually_exclusive_group(required=True) + signal_group.add_argument( + '--signal-number', + help='Signal number to send',) + signal_group.add_argument( + '--signal-name', + help='Signal to send') + parser_signal.add_argument( + '--fsid', + help='cluster FSID') + parser_signal.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + parser_logs = subparsers.add_parser( 'logs', help='print journald logs for a daemon container') parser_logs.set_defaults(func=command_logs) diff --git a/src/cephadm/cephadmlib/signals.py b/src/cephadm/cephadmlib/signals.py new file mode 100644 index 0000000000000..09dc2ad089316 --- /dev/null +++ b/src/cephadm/cephadmlib/signals.py @@ -0,0 +1,47 @@ +# functions related to sending signals + +import logging +import signal + +from typing import Optional, Union + +from .call_wrappers import call, CallVerbosity +from .context import CephadmContext +from .exceptions import Error + +logger = logging.getLogger() + + +def send_signal_to_container_entrypoint( + ctx: CephadmContext, container_name: str, sig: Union[str, int] +) -> int: + sig_str: Optional[str] = None + if isinstance(sig, int) or sig.isdigit(): + try: + sig_value = signal.Signals(int(sig)) + except ValueError: + raise Error(f'Failed to find signal name for signal ({sig})') + else: + name = sig.upper() + sig_value = signal.Signals[ + name if name.startswith('SIG') else 'SIG' + name + ] + sig_str = str(sig_value.name) + + logger.info( + f'Sending signal {sig_str} to entrypoint of container {container_name}' + ) + + _, _, code = call( + ctx, + [ + ctx.container_engine.path, + 'kill', + container_name, + '--signal', + sig_str, + ], + verbosity=CallVerbosity.VERBOSE, + desc='', + ) + return code -- 2.39.5