Skip to content

Commit f781c5c

Browse files
authored
Merge pull request ceph#61601 from phlogistonjohn/jjm-cephadm-small-moves-2
cephadm: move a few other small things out of cephadm.py Reviewed-by: Adam King <[email protected]>
2 parents 274a49e + 926011a commit f781c5c

File tree

4 files changed

+204
-117
lines changed

4 files changed

+204
-117
lines changed

src/cephadm/cephadm.py

Lines changed: 24 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@
8585
concurrent_tasks,
8686
)
8787
from cephadmlib.container_engines import (
88+
ContainerInfo,
8889
Podman,
8990
check_container_engine,
9091
find_container_engine,
91-
parsed_container_mem_usage,
9292
parsed_container_cpu_perc,
93+
parsed_container_image_stats,
94+
parsed_container_mem_usage,
9395
pull_command,
9496
registry_login,
9597
)
@@ -146,8 +148,9 @@
146148
InitContainer,
147149
SidecarContainer,
148150
extract_uid_gid,
149-
is_container_running,
151+
get_container_stats,
150152
get_mgr_images,
153+
is_container_running,
151154
)
152155
from cephadmlib.decorators import (
153156
deprecated_command,
@@ -200,30 +203,6 @@
200203
##################################
201204

202205

203-
class ContainerInfo:
204-
def __init__(self, container_id: str,
205-
image_name: str,
206-
image_id: str,
207-
start: str,
208-
version: str) -> None:
209-
self.container_id = container_id
210-
self.image_name = image_name
211-
self.image_id = image_id
212-
self.start = start
213-
self.version = version
214-
215-
def __eq__(self, other: Any) -> bool:
216-
if not isinstance(other, ContainerInfo):
217-
return NotImplemented
218-
return (self.container_id == other.container_id
219-
and self.image_name == other.image_name
220-
and self.image_id == other.image_id
221-
and self.start == other.start
222-
and self.version == other.version)
223-
224-
##################################
225-
226-
227206
def get_supported_daemons():
228207
# type: () -> List[str]
229208
supported_daemons = ceph_daemons()
@@ -522,22 +501,16 @@ def daemon_name_or_type(daemon: Dict[str, str]) -> str:
522501
# container will not help us. If we have the image name from the list_daemons output
523502
# we can try that.
524503
image_name = matching_daemons[0]['container_image_name']
525-
out, _, code = get_container_stats_by_image_name(ctx, ctx.container_engine.path, image_name)
526-
if not code:
527-
# keep in mind, the daemon container is not running, so no container id here
528-
(image_id, start, version) = out.strip().split(',')
529-
return ContainerInfo(
530-
container_id='',
531-
image_name=image_name,
532-
image_id=image_id,
533-
start=start,
534-
version=version)
504+
cinfo = parsed_container_image_stats(ctx, image_name)
505+
if cinfo:
506+
return cinfo
535507
else:
536508
d_type, d_id = matching_daemons[0]['name'].split('.', 1)
537-
out, _, code = get_container_stats(ctx, ctx.container_engine.path, ctx.fsid, d_type, d_id)
538-
if not code:
539-
(container_id, image_name, image_id, start, version) = out.strip().split(',')
540-
return ContainerInfo(container_id, image_name, image_id, start, version)
509+
cinfo = get_container_stats(
510+
ctx, DaemonIdentity(ctx.fsid, d_type, d_id)
511+
)
512+
if cinfo:
513+
return cinfo
541514
return None
542515

543516

@@ -3513,10 +3486,17 @@ def list_daemons(
35133486
version = None
35143487
start_stamp = None
35153488

3516-
out, err, code = get_container_stats(ctx, container_path, fsid, daemon_type, daemon_id)
3517-
if not code:
3518-
(container_id, image_name, image_id, start,
3519-
version) = out.strip().split(',')
3489+
cinfo = get_container_stats(
3490+
ctx,
3491+
DaemonIdentity(fsid, daemon_type, daemon_id),
3492+
container_path=container_path
3493+
)
3494+
if cinfo:
3495+
container_id = cinfo.container_id
3496+
image_name = cinfo.image_name
3497+
image_id = cinfo.image_id
3498+
start = cinfo.start
3499+
version = cinfo.version
35203500
image_id = normalize_container_id(image_id)
35213501
daemon_type = name.split('.', 1)[0]
35223502
start_stamp = try_convert_datetime(start)
@@ -3660,36 +3640,6 @@ def get_daemon_description(ctx, fsid, name, detail=False, legacy_dir=None):
36603640
return d
36613641
raise Error('Daemon not found: {}. See `cephadm ls`'.format(name))
36623642

3663-
3664-
def get_container_stats(ctx: CephadmContext, container_path: str, fsid: str, daemon_type: str, daemon_id: str) -> Tuple[str, str, int]:
3665-
"""returns container id, image name, image id, created time, and ceph version if available"""
3666-
c = CephContainer.for_daemon(
3667-
ctx, DaemonIdentity(fsid, daemon_type, daemon_id), 'bash'
3668-
)
3669-
out, err, code = '', '', -1
3670-
for name in (c.cname, c.old_cname):
3671-
cmd = [
3672-
container_path, 'inspect',
3673-
'--format', '{{.Id}},{{.Config.Image}},{{.Image}},{{.Created}},{{index .Config.Labels "io.ceph.version"}}',
3674-
name
3675-
]
3676-
out, err, code = call(ctx, cmd, verbosity=CallVerbosity.QUIET)
3677-
if not code:
3678-
break
3679-
return out, err, code
3680-
3681-
3682-
def get_container_stats_by_image_name(ctx: CephadmContext, container_path: str, image_name: str) -> Tuple[str, str, int]:
3683-
"""returns image id, created time, and ceph version if available"""
3684-
out, err, code = '', '', -1
3685-
cmd = [
3686-
container_path, 'image', 'inspect',
3687-
'--format', '{{.Id}},{{.Created}},{{index .Config.Labels "io.ceph.version"}}',
3688-
image_name
3689-
]
3690-
out, err, code = call(ctx, cmd, verbosity=CallVerbosity.QUIET)
3691-
return out, err, code
3692-
36933643
##################################
36943644

36953645

src/cephadm/cephadmlib/container_engines.py

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import logging
55

6-
from typing import Tuple, List, Optional, Dict
6+
from typing import Tuple, List, Optional, Dict, Any
77

88
from .call_wrappers import call_throws, call, CallVerbosity
99
from .context import CephadmContext
@@ -302,3 +302,116 @@ def parsed_container_cpu_perc(
302302
ctx, container_path=container_path, verbosity=verbosity
303303
)
304304
return _parse_cpu_perc(code, out)
305+
306+
307+
class ContainerInfo:
308+
def __init__(
309+
self,
310+
container_id: str,
311+
image_name: str,
312+
image_id: str,
313+
start: str,
314+
version: str,
315+
) -> None:
316+
self.container_id = container_id
317+
self.image_name = image_name
318+
self.image_id = image_id
319+
self.start = start
320+
self.version = version
321+
322+
def __eq__(self, other: Any) -> bool:
323+
if not isinstance(other, ContainerInfo):
324+
return NotImplemented
325+
return (
326+
self.container_id == other.container_id
327+
and self.image_name == other.image_name
328+
and self.image_id == other.image_id
329+
and self.start == other.start
330+
and self.version == other.version
331+
)
332+
333+
334+
def _container_stats(
335+
ctx: CephadmContext,
336+
container_name: str,
337+
*,
338+
container_path: str,
339+
) -> Tuple[str, str, int]:
340+
"""returns container id, image name, image id, created time, and ceph version if available"""
341+
container_path = container_path or ctx.container_engine.path
342+
out, err, code = '', '', -1
343+
cmd = [
344+
container_path,
345+
'inspect',
346+
'--format',
347+
'{{.Id}},{{.Config.Image}},{{.Image}},{{.Created}},{{index .Config.Labels "io.ceph.version"}}',
348+
container_name,
349+
]
350+
out, err, code = call(ctx, cmd, verbosity=CallVerbosity.QUIET)
351+
return out, err, code
352+
353+
354+
def _parse_container_stats(
355+
out: str, err: str, code: int
356+
) -> Optional[ContainerInfo]:
357+
if code != 0:
358+
return None
359+
# container_id, image_name, image_id, start, version
360+
return ContainerInfo(*list(out.strip().split(',')))
361+
362+
363+
def parsed_container_stats(
364+
ctx: CephadmContext,
365+
container_name: str,
366+
*,
367+
container_path: str,
368+
) -> Optional[ContainerInfo]:
369+
out, err, code = _container_stats(
370+
ctx, container_name, container_path=container_path
371+
)
372+
return _parse_container_stats(out, err, code)
373+
374+
375+
def _container_image_stats(
376+
ctx: CephadmContext, image_name: str, *, container_path: str = ''
377+
) -> Tuple[str, str, int]:
378+
"""returns image id, created time, and ceph version if available"""
379+
container_path = container_path or ctx.container_engine.path
380+
cmd = [
381+
container_path,
382+
'image',
383+
'inspect',
384+
'--format',
385+
'{{.Id}},{{.Created}},{{index .Config.Labels "io.ceph.version"}}',
386+
image_name,
387+
]
388+
out, err, code = call(ctx, cmd, verbosity=CallVerbosity.QUIET)
389+
return out, err, code
390+
391+
392+
def _parse_container_image_stats(
393+
image_name: str,
394+
out: str,
395+
err: str,
396+
code: int,
397+
) -> Optional[ContainerInfo]:
398+
if code != 0:
399+
return None
400+
(image_id, start, version) = out.strip().split(',')
401+
# keep in mind, the daemon container is not running, so no container id here
402+
return ContainerInfo(
403+
container_id='',
404+
image_name=image_name,
405+
image_id=image_id,
406+
start=start,
407+
version=version,
408+
)
409+
410+
411+
def parsed_container_image_stats(
412+
ctx: CephadmContext, image_name: str, *, container_path: str = ''
413+
) -> Optional[ContainerInfo]:
414+
out, err, code = _container_image_stats(
415+
ctx, image_name, container_path=container_path
416+
)
417+
return _parse_container_image_stats(image_name, out, err, code)

src/cephadm/cephadmlib/container_types.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
from .call_wrappers import call, call_throws, CallVerbosity
1111
from .constants import DEFAULT_TIMEOUT
1212
from ceph.cephadm.images import DefaultImages
13-
from .container_engines import Docker, Podman
13+
from .container_engines import (
14+
ContainerInfo,
15+
Docker,
16+
Podman,
17+
parsed_container_stats,
18+
)
1419
from .context import CephadmContext
1520
from .daemon_identity import DaemonIdentity, DaemonSubIdentity
1621
from .exceptions import Error
@@ -670,3 +675,15 @@ def get_mgr_images() -> dict:
670675
f'{mgr_prefix}{image.key}': image.image_ref for image in DefaultImages
671676
}
672677
return mgr_images
678+
679+
680+
def get_container_stats(
681+
ctx: CephadmContext, identity: DaemonIdentity, *, container_path: str = ''
682+
) -> Optional[ContainerInfo]:
683+
"""returns container id, image name, image id, created time, and ceph version if available"""
684+
c = CephContainer.for_daemon(ctx, identity, 'bash')
685+
for name in (c.cname, c.old_cname):
686+
ci = parsed_container_stats(ctx, name, container_path=container_path)
687+
if ci is not None:
688+
return ci
689+
return None

0 commit comments

Comments
 (0)