Skip to content

Commit 211e677

Browse files
cephadm: support --infer-name option for lazy devs
Add an --infer-name/-i option to the cephadm enter command. This new option is a spin on --name/-n but allows the value to be partial. The first part of the value must be a service type (like `mgr`, `mds`, `nfs`, etc). That can then be followed optionally by a dot (.) and a part (or whole) of an id. For example: Enter the one and only mgr container running on this host: ``` cephadm enter -i mgr ``` Enter a (primary) smb container running on this host belonging to the virtual cluster "cluster1", without specifying random chars or rank values: ``` cephadm enter -i smb.cluster1 ``` If the partial name does not match any services on the host or it matches more than 1 service on the host it will return an error. In the case of >1 service you can then supply more characters in the partial id to narrow down the match. For example: ``` cephadm enter -i osd Inferring fsid bf7116b2-2b9d-11f0-bb35-525400220000 ERROR: too many daemons match 'osd' (osd.2, osd.5) /tmp/cephadm enter -i osd.2 Inferring fsid bf7116b2-2b9d-11f0-bb35-525400220000 Inferring daemon osd.2 [ceph: root@ceph0 /]# ``` Signed-off-by: John Mulligan <[email protected]>
1 parent e8b8c95 commit 211e677

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/cephadm/cephadm.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@
188188
)
189189
from cephadmlib.agent import http_query
190190
from cephadmlib.listing import (
191+
CombinedStatusUpdater,
191192
DaemonStatusUpdater,
192193
NoOpDaemonStatusUpdater,
193-
CombinedStatusUpdater,
194194
daemons_matching,
195195
daemons_summary,
196196
)
@@ -201,7 +201,7 @@
201201
MemUsageStatusUpdater,
202202
VersionStatusUpdater,
203203
)
204-
from cephadmlib.container_lookup import infer_local_ceph_image
204+
from cephadmlib.container_lookup import infer_local_ceph_image, identify
205205

206206

207207
FuncT = TypeVar('FuncT', bound=Callable)
@@ -3151,12 +3151,9 @@ def command_shell(ctx):
31513151

31523152

31533153
@infer_fsid
3154-
def command_enter(ctx):
3155-
# type: (CephadmContext) -> int
3156-
if not ctx.fsid:
3157-
raise Error('must pass --fsid to specify cluster')
3158-
(daemon_type, daemon_id) = ctx.name.split('.', 1)
3159-
container_args = ['-i'] # type: List[str]
3154+
def command_enter(ctx: CephadmContext) -> int:
3155+
ident = identify(ctx)
3156+
container_args = ['-i']
31603157
if ctx.command:
31613158
command = ctx.command
31623159
else:
@@ -3168,10 +3165,10 @@ def command_enter(ctx):
31683165
]
31693166
c = CephContainer(
31703167
ctx,
3168+
identity=ident,
31713169
image=ctx.image,
31723170
entrypoint='doesnotmatter',
31733171
container_args=container_args,
3174-
cname='ceph-%s-%s.%s' % (ctx.fsid, daemon_type, daemon_id),
31753172
)
31763173
command = c.exec_cmd(command)
31773174
return call_timeout(ctx, command, ctx.timeout)
@@ -4767,10 +4764,13 @@ def _get_parser():
47674764
parser_enter.add_argument(
47684765
'--fsid',
47694766
help='cluster FSID')
4770-
parser_enter.add_argument(
4767+
parser_enter_ng = parser_enter.add_mutually_exclusive_group(required=True)
4768+
parser_enter_ng.add_argument(
47714769
'--name', '-n',
4772-
required=True,
47734770
help='daemon name (type.id)')
4771+
parser_enter_ng.add_argument(
4772+
'--infer-name', '-i',
4773+
help='daemon name search (type[.partial_id])')
47744774
parser_enter.add_argument(
47754775
'command', nargs=argparse.REMAINDER,
47764776
help='command')

src/cephadm/cephadmlib/container_lookup.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from operator import itemgetter
44
from typing import Optional, Tuple
55

6+
import fnmatch
67
import logging
78

89
from .container_engines import (
@@ -15,7 +16,8 @@
1516
from .context import CephadmContext
1617
from .daemon_identity import DaemonIdentity
1718
from .daemons.ceph import ceph_daemons
18-
from .listing import daemons_matching
19+
from .exceptions import Error
20+
from .listing import LegacyDaemonEntry, daemons_matching
1921
from .listing_updaters import CoreStatusUpdater
2022

2123

@@ -176,3 +178,56 @@ def _keyfunc(image: ImageInfo) -> Tuple[bool, bool, str]:
176178
reason,
177179
)
178180
return best_image.name
181+
182+
183+
def infer_daemon_identity(
184+
ctx: CephadmContext, partial_name: str
185+
) -> DaemonIdentity:
186+
"""Given a partial daemon/service name, infer the identity of the
187+
daemon.
188+
"""
189+
190+
if not partial_name:
191+
raise Error('a daemon type is required to infer a service name')
192+
if '.' in partial_name:
193+
_type, _name = partial_name.split('.', 1)
194+
else:
195+
_type, _name = partial_name, ''
196+
# allow searching for a name with just the beginning without having
197+
# to expliclity supply a trailing asterisk
198+
_name += '*'
199+
matches = []
200+
for d in daemons_matching(ctx, fsid=ctx.fsid, daemon_type=_type):
201+
if isinstance(d, LegacyDaemonEntry):
202+
logger.info('Ignoring legacy daemon %s', d.name)
203+
continue # ignore legacy daemons
204+
if fnmatch.fnmatch(d.identity.daemon_id, _name):
205+
matches.append(d)
206+
207+
if not matches:
208+
raise Error(f'no daemons match {partial_name!r}')
209+
if len(matches) > 1:
210+
excess = ', '.join(d.identity.daemon_name for d in matches)
211+
raise Error(f'too many daemons match {partial_name!r} ({excess})')
212+
ident = matches[0].identity
213+
logger.info('Inferring daemon %s', ident.daemon_name)
214+
return ident
215+
216+
217+
def identify(ctx: CephadmContext) -> DaemonIdentity:
218+
"""Given a context try and determine a specific daemon identity to use
219+
based on the --name CLI option (exact) or --infer-name (partial match)
220+
option.
221+
"""
222+
if not ctx.fsid:
223+
raise Error('must pass --fsid to specify cluster')
224+
name = getattr(ctx, 'name', '')
225+
if name:
226+
return DaemonIdentity.from_name(ctx.fsid, name)
227+
iname = getattr(ctx, 'infer_name', '')
228+
if iname:
229+
return infer_daemon_identity(ctx, iname)
230+
raise Error(
231+
'must specify a daemon name'
232+
' (use --name/-n or --infer-name/-i for example)'
233+
)

0 commit comments

Comments
 (0)