Skip to content

Commit 2769e36

Browse files
cephadm: replace detail fetching in list_daemons with updaters
Replace the deetail fetching functions with the recently added listing updater classes. The functionality is designed to be unchanged with this update. Signed-off-by: John Mulligan <[email protected]>
1 parent 2c71930 commit 2769e36

File tree

1 file changed

+21
-306
lines changed

1 file changed

+21
-306
lines changed

src/cephadm/cephadm.py

Lines changed: 21 additions & 306 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090
check_container_engine,
9191
find_container_engine,
9292
normalize_container_id,
93-
parsed_container_cpu_perc,
9493
parsed_container_image_stats,
9594
parsed_container_mem_usage,
9695
pull_command,
@@ -101,12 +100,10 @@
101100
get_legacy_daemon_fsid,
102101
is_fsid,
103102
normalize_image_digest,
104-
try_convert_datetime,
105103
read_config,
106104
_extract_host_info_from_applied_spec,
107105
)
108106
from cephadmlib.file_utils import (
109-
get_file_timestamp,
110107
makedirs,
111108
pathify,
112109
read_file,
@@ -194,10 +191,19 @@
194191
)
195192
from cephadmlib.agent import http_query
196193
from cephadmlib.listing import (
197-
LegacyDaemonEntry,
194+
DaemonStatusUpdater,
195+
NoOpDaemonStatusUpdater,
196+
CombinedStatusUpdater,
198197
daemons_matching,
199198
daemons_summary,
200199
)
200+
from cephadmlib.listing_updaters import (
201+
CPUUsageStatusUpdater,
202+
CoreStatusUpdater,
203+
DigestsStatusUpdater,
204+
MemUsageStatusUpdater,
205+
VersionStatusUpdater,
206+
)
201207

202208

203209
FuncT = TypeVar('FuncT', bound=Callable)
@@ -3397,315 +3403,24 @@ def list_daemons(
33973403
daemon_name: Optional[str] = None,
33983404
type_of_daemon: Optional[str] = None,
33993405
) -> List[Dict[str, str]]:
3400-
legacy_cache: Dict[str, Any] = {}
3401-
ls = []
3402-
3403-
data_dir = ctx.data_dir
3404-
if legacy_dir is not None:
3405-
data_dir = os.path.abspath(legacy_dir + data_dir)
3406-
3407-
if not os.path.exists(data_dir):
3408-
# data_dir (/var/lib/ceph typically) is missing. Return empty list.
3409-
logger.warning('%s is missing: no daemon listing available', data_dir)
3410-
return []
3411-
3412-
# keep track of ceph versions we see
3413-
seen_versions: Dict[str, Optional[str]] = {}
3414-
3415-
# keep track of image digests
3416-
seen_digests: Dict[str, List[str]] = {}
3417-
3418-
# keep track of memory and cpu usage we've seen
3419-
seen_memusage_cid_len, seen_memusage = parsed_container_mem_usage(ctx)
3420-
seen_cpuperc_cid_len, seen_cpuperc = parsed_container_cpu_perc(ctx)
3406+
_updater: DaemonStatusUpdater = NoOpDaemonStatusUpdater()
3407+
if detail:
3408+
detail_updaters = [
3409+
CoreStatusUpdater(),
3410+
DigestsStatusUpdater(),
3411+
VersionStatusUpdater(),
3412+
MemUsageStatusUpdater(),
3413+
CPUUsageStatusUpdater(),
3414+
]
3415+
_updater = CombinedStatusUpdater(detail_updaters)
34213416

34223417
daemon_entries = daemons_matching(
34233418
ctx,
34243419
legacy_dir,
34253420
daemon_name=daemon_name,
34263421
daemon_type=type_of_daemon,
34273422
)
3428-
for entry in daemon_entries:
3429-
if isinstance(entry, LegacyDaemonEntry):
3430-
status = cast(Dict[str, Any], entry.status)
3431-
if detail:
3432-
_update_legacy_status(
3433-
status, ctx, entry.name, legacy_cache,
3434-
)
3435-
ls.append(status)
3436-
else:
3437-
status = cast(Dict[str, Any], entry.status)
3438-
if detail:
3439-
_update_daemon_and_container_status(
3440-
status,
3441-
ctx,
3442-
entry.identity,
3443-
data_dir,
3444-
seen_versions,
3445-
seen_digests,
3446-
seen_memusage_cid_len,
3447-
seen_memusage,
3448-
seen_cpuperc_cid_len,
3449-
seen_cpuperc,
3450-
)
3451-
ls.append(status)
3452-
return ls
3453-
3454-
3455-
def _update_legacy_status(
3456-
val: Dict[str, Any],
3457-
ctx: CephadmContext,
3458-
legacy_unit_name: str,
3459-
cache: Dict[str, Any],
3460-
) -> None:
3461-
(val['enabled'], val['state'], _) = check_unit(
3462-
ctx, legacy_unit_name
3463-
)
3464-
if not cache.get('host_version'):
3465-
try:
3466-
out, err, code = call(
3467-
ctx,
3468-
['ceph', '-v'],
3469-
verbosity=CallVerbosity.QUIET,
3470-
)
3471-
if not code and out.startswith('ceph version '):
3472-
cache['host_version'] = out.split(' ')[2]
3473-
except Exception:
3474-
pass
3475-
val['host_version'] = cache.get('host_version')
3476-
3477-
3478-
def _update_daemon_and_container_status(
3479-
val: Dict[str, Any],
3480-
ctx: CephadmContext,
3481-
identity: DaemonIdentity,
3482-
data_dir: str,
3483-
seen_versions: Dict[str, Optional[str]],
3484-
seen_digests: Dict[str, List[str]],
3485-
seen_memusage_cid_len: int,
3486-
seen_memusage: Dict[str, int],
3487-
seen_cpuperc_cid_len: int,
3488-
seen_cpuperc: Dict[str, str],
3489-
) -> None:
3490-
# aliases (to clean up later)
3491-
container_path = ctx.container_engine.path
3492-
fsid = identity.fsid
3493-
daemon_type = identity.daemon_type
3494-
daemon_id = identity.daemon_id
3495-
name = j = identity.daemon_name
3496-
3497-
# get container id
3498-
(val['enabled'], val['state'], _) = check_unit(
3499-
ctx, identity.unit_name
3500-
)
3501-
container_id = None
3502-
image_name = None
3503-
image_id = None
3504-
image_digests = None
3505-
version = None
3506-
start_stamp = None
3507-
3508-
cinfo = get_container_stats(
3509-
ctx,
3510-
DaemonIdentity(fsid, daemon_type, daemon_id),
3511-
container_path=container_path,
3512-
)
3513-
if cinfo:
3514-
container_id = cinfo.container_id
3515-
image_name = cinfo.image_name
3516-
image_id = cinfo.image_id
3517-
start = cinfo.start
3518-
version = cinfo.version
3519-
image_id = normalize_container_id(image_id)
3520-
daemon_type = name.split('.', 1)[0]
3521-
start_stamp = try_convert_datetime(start)
3522-
3523-
# collect digests for this image id
3524-
image_digests = seen_digests.get(image_id)
3525-
if not image_digests:
3526-
out, err, code = call(
3527-
ctx,
3528-
[
3529-
container_path,
3530-
'image',
3531-
'inspect',
3532-
image_id,
3533-
'--format',
3534-
'{{.RepoDigests}}',
3535-
],
3536-
verbosity=CallVerbosity.QUIET,
3537-
)
3538-
if not code:
3539-
image_digests = list(
3540-
set(
3541-
map(
3542-
normalize_image_digest,
3543-
out.strip()[1:-1].split(' '),
3544-
)
3545-
)
3546-
)
3547-
seen_digests[image_id] = image_digests
3548-
3549-
# identify software version inside the container (if we can)
3550-
if not version or '.' not in version:
3551-
version = seen_versions.get(image_id, None)
3552-
if daemon_type == NFSGanesha.daemon_type:
3553-
version = NFSGanesha.get_version(
3554-
ctx, container_id
3555-
)
3556-
if daemon_type == CephIscsi.daemon_type:
3557-
version = CephIscsi.get_version(ctx, container_id)
3558-
if daemon_type == CephNvmeof.daemon_type:
3559-
version = CephNvmeof.get_version(
3560-
ctx, container_id
3561-
)
3562-
if daemon_type == SMB.daemon_type:
3563-
version = SMB.get_version(ctx, container_id)
3564-
elif not version:
3565-
if daemon_type in ceph_daemons():
3566-
out, err, code = call(
3567-
ctx,
3568-
[
3569-
container_path,
3570-
'exec',
3571-
container_id,
3572-
'ceph',
3573-
'-v',
3574-
],
3575-
verbosity=CallVerbosity.QUIET,
3576-
)
3577-
if not code and out.startswith(
3578-
'ceph version '
3579-
):
3580-
version = out.split(' ')[2]
3581-
seen_versions[image_id] = version
3582-
elif daemon_type == 'grafana':
3583-
out, err, code = call(
3584-
ctx,
3585-
[
3586-
container_path,
3587-
'exec',
3588-
container_id,
3589-
'grafana',
3590-
'server',
3591-
'-v',
3592-
],
3593-
verbosity=CallVerbosity.QUIET,
3594-
)
3595-
if not code and out.startswith('Version '):
3596-
version = out.split(' ')[1]
3597-
seen_versions[image_id] = version
3598-
elif daemon_type in [
3599-
'prometheus',
3600-
'alertmanager',
3601-
'node-exporter',
3602-
'loki',
3603-
'promtail',
3604-
]:
3605-
version = Monitoring.get_version(
3606-
ctx, container_id, daemon_type
3607-
)
3608-
seen_versions[image_id] = version
3609-
elif daemon_type == 'haproxy':
3610-
out, err, code = call(
3611-
ctx,
3612-
[
3613-
container_path,
3614-
'exec',
3615-
container_id,
3616-
'haproxy',
3617-
'-v',
3618-
],
3619-
verbosity=CallVerbosity.QUIET,
3620-
)
3621-
if (
3622-
not code
3623-
and out.startswith('HA-Proxy version ')
3624-
or out.startswith('HAProxy version ')
3625-
):
3626-
version = out.split(' ')[2]
3627-
seen_versions[image_id] = version
3628-
elif daemon_type == 'keepalived':
3629-
out, err, code = call(
3630-
ctx,
3631-
[
3632-
container_path,
3633-
'exec',
3634-
container_id,
3635-
'keepalived',
3636-
'--version',
3637-
],
3638-
verbosity=CallVerbosity.QUIET,
3639-
)
3640-
if not code and err.startswith('Keepalived '):
3641-
version = err.split(' ')[1]
3642-
if version[0] == 'v':
3643-
version = version[1:]
3644-
seen_versions[image_id] = version
3645-
elif daemon_type == CustomContainer.daemon_type:
3646-
# Because a custom container can contain
3647-
# everything, we do not know which command
3648-
# to execute to get the version.
3649-
pass
3650-
elif daemon_type == SNMPGateway.daemon_type:
3651-
version = SNMPGateway.get_version(
3652-
ctx, fsid, daemon_id
3653-
)
3654-
seen_versions[image_id] = version
3655-
elif daemon_type == MgmtGateway.daemon_type:
3656-
version = MgmtGateway.get_version(
3657-
ctx, container_id
3658-
)
3659-
seen_versions[image_id] = version
3660-
elif daemon_type == OAuth2Proxy.daemon_type:
3661-
version = OAuth2Proxy.get_version(
3662-
ctx, container_id
3663-
)
3664-
seen_versions[image_id] = version
3665-
else:
3666-
logger.warning(
3667-
'version for unknown daemon type %s'
3668-
% daemon_type
3669-
)
3670-
else:
3671-
vfile = os.path.join(data_dir, fsid, j, 'unit.image')
3672-
try:
3673-
with open(vfile, 'r') as f:
3674-
image_name = f.read().strip() or None
3675-
except IOError:
3676-
pass
3677-
3678-
# unit.meta?
3679-
mfile = os.path.join(data_dir, fsid, j, 'unit.meta')
3680-
try:
3681-
with open(mfile, 'r') as f:
3682-
meta = json.loads(f.read())
3683-
val.update(meta)
3684-
except IOError:
3685-
pass
3686-
3687-
val['container_id'] = container_id
3688-
val['container_image_name'] = image_name
3689-
val['container_image_id'] = image_id
3690-
val['container_image_digests'] = image_digests
3691-
if container_id:
3692-
val['memory_usage'] = seen_memusage.get(
3693-
container_id[0:seen_memusage_cid_len]
3694-
)
3695-
val['cpu_percentage'] = seen_cpuperc.get(
3696-
container_id[0:seen_cpuperc_cid_len]
3697-
)
3698-
val['version'] = version
3699-
val['started'] = start_stamp
3700-
val['created'] = get_file_timestamp(
3701-
os.path.join(data_dir, fsid, j, 'unit.created')
3702-
)
3703-
val['deployed'] = get_file_timestamp(
3704-
os.path.join(data_dir, fsid, j, 'unit.image')
3705-
)
3706-
val['configured'] = get_file_timestamp(
3707-
os.path.join(data_dir, fsid, j, 'unit.configured')
3708-
)
3423+
return [_updater.expand(ctx, entry) for entry in daemon_entries]
37093424

37103425

37113426
def get_daemon_description(ctx, fsid, name, detail=False, legacy_dir=None):

0 commit comments

Comments
 (0)