Skip to content

Commit 35544aa

Browse files
committed
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 <[email protected]> (cherry picked from commit 16b16d1) Conflicts: src/cephadm/cephadm.py Resolves: rhbz#2373703
1 parent 27fa5c7 commit 35544aa

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/cephadm/cephadm.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
)
144144
from cephadmlib.systemd import check_unit, check_units, terminate_service, enable_service
145145
from cephadmlib import systemd_unit
146+
from cephadmlib.signals import send_signal_to_container_entrypoint
146147
from cephadmlib import runscripts
147148
from cephadmlib.container_types import (
148149
CephContainer,
@@ -759,6 +760,24 @@ def get_legacy_daemon_fsid(ctx, cluster,
759760
fsid = get_legacy_config_fsid(cluster, legacy_dir=legacy_dir)
760761
return fsid
761762

763+
def lookup_container_id_by_daemon_name(ctx: CephadmContext, fsid: str, name: str) -> str:
764+
updater = CombinedStatusUpdater([CoreStatusUpdater()])
765+
daemon_entries = daemons_matching(
766+
ctx,
767+
daemon_name=name,
768+
)
769+
daemons = [updater.expand(ctx, entry) for entry in daemon_entries]
770+
if not daemons:
771+
raise Error('Failed to find daemon {}'.format(name))
772+
if len(daemons) > 1:
773+
raise Error('Found multiple daemons matching name {}: {}'.format(name, daemons))
774+
775+
daemon = daemons[0]
776+
try:
777+
return daemon['container_id']
778+
except KeyError:
779+
raise Error('Failed to get container id for {}'.format(daemon))
780+
762781

763782
def create_daemon_dirs(
764783
ctx: CephadmContext,
@@ -3565,6 +3584,18 @@ def command_unit(ctx):
35653584
)
35663585
return code
35673586

3587+
3588+
@infer_fsid
3589+
def command_signal(ctx):
3590+
# type: (CephadmContext) -> int
3591+
if not ctx.fsid:
3592+
raise Error('must pass --fsid to specify cluster')
3593+
3594+
container_id = lookup_container_id_by_daemon_name(ctx, ctx.fsid, ctx.name)
3595+
3596+
return send_signal_to_container_entrypoint(ctx, container_id, ctx.signal_name, ctx.signal_number)
3597+
3598+
35683599
##################################
35693600

35703601

@@ -5623,6 +5654,24 @@ def _get_parser():
56235654
help='Set LimitCORE=infinity in ceph unit files'
56245655
)
56255656

5657+
parser_signal = subparsers.add_parser(
5658+
'signal', help='Send signal to entrypoint of containerized daemon')
5659+
parser_signal.set_defaults(func=command_signal)
5660+
signal_group = parser_signal.add_mutually_exclusive_group(required=True)
5661+
signal_group.add_argument(
5662+
'--signal-number',
5663+
help='Signal number to send',)
5664+
signal_group.add_argument(
5665+
'--signal-name',
5666+
help='Signal to send')
5667+
parser_signal.add_argument(
5668+
'--fsid',
5669+
help='cluster FSID')
5670+
parser_signal.add_argument(
5671+
'--name', '-n',
5672+
required=True,
5673+
help='daemon name (type.id)')
5674+
56265675
parser_logs = subparsers.add_parser(
56275676
'logs', help='print journald logs for a daemon container')
56285677
parser_logs.set_defaults(func=command_logs)

src/cephadm/cephadmlib/signals.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# functions related to sending signals
2+
3+
import logging
4+
import signal
5+
6+
from typing import Optional
7+
8+
from .call_wrappers import call, CallVerbosity
9+
from .context import CephadmContext
10+
from .exceptions import Error
11+
12+
logger = logging.getLogger()
13+
14+
15+
def send_signal_to_container_entrypoint(
16+
ctx: CephadmContext,
17+
container_id: str,
18+
signal_name: Optional[str],
19+
signal_number: Optional[int],
20+
) -> int:
21+
if not signal_name and not signal_number:
22+
raise Error(
23+
f'Got request to send signal to entrypoint of container with id {container_id} but no signal specified'
24+
)
25+
26+
if signal_number and signal_name:
27+
raise Error(
28+
'signal_name and signal_number params to send_signal_to_container_entrypoint are mutually exclusive'
29+
)
30+
31+
if signal_number:
32+
signal_name = signal.Signals(signal_number).name
33+
elif signal_name:
34+
signal_name = signal_name.upper()
35+
signal_number = signal.Signals[signal_name].value
36+
assert signal_name is not None and signal_number is not None
37+
38+
logger.info(
39+
f'Sending signal {signal_name} ({signal_number}) to entrypoint of container with id {container_id}'
40+
)
41+
42+
_, _, code = call(
43+
ctx,
44+
[
45+
ctx.container_engine.path,
46+
'kill',
47+
container_id,
48+
'--signal',
49+
signal_name,
50+
],
51+
verbosity=CallVerbosity.VERBOSE,
52+
desc='',
53+
)
54+
return code

0 commit comments

Comments
 (0)