)
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,
)
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)
+
+
##################################
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)
--- /dev/null
+# 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