]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
cephadm: add command to send signals to daemons
authorAdam King <adking@redhat.com>
Wed, 4 Jun 2025 20:12:32 +0000 (16:12 -0400)
committerAdam King <adking@redhat.com>
Wed, 17 Sep 2025 14:17:39 +0000 (10:17 -0400)
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 <adking@redhat.com>
src/cephadm/cephadm.py
src/cephadm/cephadmlib/signals.py [new file with mode: 0644]

index 95cdcc28eae6d2aa674311740b52cbfa22eb7258..38c521303ed6e5b3720c7e6979fb4d9a374bd88a 100755 (executable)
@@ -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 (file)
index 0000000..09dc2ad
--- /dev/null
@@ -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