Skip to content

Commit 07eeced

Browse files
authored
Merge pull request ceph#61761 from phlogistonjohn/jjm-list_daemons-refactor
cephadm: refactor the core of list_daemons Reviewed-by: Adam King <[email protected]>
2 parents 95d6395 + 3c29e2f commit 07eeced

File tree

7 files changed

+902
-327
lines changed

7 files changed

+902
-327
lines changed

src/cephadm/cephadm.py

Lines changed: 37 additions & 312 deletions
Large diffs are not rendered by default.

src/cephadm/cephadmlib/container_engines.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,18 @@ def parsed_container_image_stats(
415415
ctx, image_name, container_path=container_path
416416
)
417417
return _parse_container_image_stats(image_name, out, err, code)
418+
419+
420+
def normalize_container_id(i: str) -> str:
421+
# docker adds the sha256: prefix, but AFAICS both
422+
# docker (18.09.7 in bionic at least) and podman
423+
# both always use sha256, so leave off the prefix
424+
# for consistency.
425+
# ---
426+
# (JJM) This is not a good idea and cephadm should move away from stripping
427+
# the hash-type prefix. This is there so that docker/OCI can eventually
428+
# move hash types if need be. Removing it breaks hash agility!
429+
prefix = 'sha256:'
430+
if i.startswith(prefix):
431+
i = i[len(prefix) :]
432+
return i
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# container_lookup.py - high-level functions for getting container info
2+
3+
from typing import Optional
4+
5+
import logging
6+
7+
from .container_engines import ContainerInfo, parsed_container_image_stats
8+
from .container_types import get_container_stats
9+
from .context import CephadmContext
10+
from .daemon_identity import DaemonIdentity
11+
from .listing import daemons_matching
12+
from .listing_updaters import CoreStatusUpdater
13+
14+
15+
logger = logging.getLogger()
16+
17+
18+
def get_container_info(
19+
ctx: CephadmContext, daemon_filter: str, by_name: bool
20+
) -> Optional[ContainerInfo]:
21+
"""
22+
:param ctx: Cephadm context
23+
:param daemon_filter: daemon name or type
24+
:param by_name: must be set to True if daemon name is provided
25+
:return: Container information or None
26+
"""
27+
if by_name and '.' not in daemon_filter:
28+
logger.warning(
29+
f'Trying to get container info using invalid daemon name {daemon_filter}'
30+
)
31+
return None
32+
33+
# configure filters: fsid and (daemon name or daemon type)
34+
kwargs = {
35+
'fsid': ctx.fsid,
36+
('daemon_name' if by_name else 'daemon_type'): daemon_filter,
37+
}
38+
# use keep_container_info to cache the ContainerInfo generated
39+
# during the loop and hopefully avoid having to perform the same
40+
# lookup right away.
41+
_cinfo_key = '_container_info'
42+
_updater = CoreStatusUpdater(keep_container_info=_cinfo_key)
43+
matching_daemons = [
44+
_updater.expand(ctx, entry)
45+
for entry in daemons_matching(ctx, **kwargs)
46+
]
47+
48+
if not matching_daemons:
49+
# no matches at all
50+
logger.debug(
51+
'no daemons match: daemon_filter=%r, by_name=%r',
52+
daemon_filter,
53+
by_name,
54+
)
55+
return None
56+
if by_name and len(matching_daemons) > 1:
57+
# too many matches while searching by name
58+
logger.warning(
59+
f'Found multiple daemons sharing same name: {daemon_filter}'
60+
)
61+
# Prefer to take the first daemon we find that is actually running, or
62+
# just the first in the list if none are running
63+
# (key reminder: false (0) sorts before true (1))
64+
matching_daemons = sorted(
65+
matching_daemons, key=lambda d: d.get('state') != 'running'
66+
)
67+
68+
matched_deamon = matching_daemons[0]
69+
is_running = matched_deamon.get('state') == 'running'
70+
image_name = matched_deamon.get('container_image_name', '')
71+
if is_running:
72+
cinfo = matched_deamon.get(_cinfo_key)
73+
if cinfo:
74+
# found a cached ContainerInfo while getting daemon statuses
75+
return cinfo
76+
return get_container_stats(
77+
ctx,
78+
DaemonIdentity.from_name(
79+
matched_deamon['fsid'], matched_deamon['name']
80+
),
81+
)
82+
elif image_name:
83+
# this daemon's container is not running. the regular container inspect
84+
# command will not work. Fall back to inspecting the container image
85+
assert isinstance(image_name, str)
86+
return parsed_container_image_stats(ctx, image_name)
87+
# not running, but no image name to look up!
88+
logger.debug(
89+
'bad daemon state: no image, not running: %r', matched_deamon
90+
)
91+
return None

0 commit comments

Comments
 (0)