From: John Mulligan Date: Fri, 7 Feb 2025 16:40:25 +0000 (-0500) Subject: cephadm: add a status updater class to listing.py X-Git-Tag: v20.3.0~256^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2f2be76c56552ff8da2318c744533b7863917231;p=ceph.git cephadm: add a status updater class to listing.py These updater classes provide generic framework for getting extra information about a deamon during a listing. Signed-off-by: John Mulligan --- diff --git a/src/cephadm/cephadmlib/listing.py b/src/cephadm/cephadmlib/listing.py index 5e8bbb8755c..44004b572af 100644 --- a/src/cephadm/cephadmlib/listing.py +++ b/src/cephadm/cephadmlib/listing.py @@ -1,9 +1,56 @@ # listing.py - listings and status of current daemons +# +# listing.py is the result of a refactor of the previous mega-function list_daemons. +# It attempts to break the operation of listing daemons and getting information about +# those daemons into the following parts: +# +# Functions daemons and daemons_matching iterate the configuration tree +# used by ceph and yields entry objects that represent either a standard +# daemon or a legacy daemon. +# +# Function daemons_summary is a convenient function that return a list +# containing the status field of entries from daemons_matching. It is designed +# to be a drop in replacement for `list_daemons` called with the `detail=False` +# argument. +# +# To provide an equivalent to the detail gathering portion of list_daemons the +# DaemonStatusUpdater base class and subclasses are designed to be a +# well-defined but flexible mechanism to gather additional data for each entry +# type and update the contents of the associated status dict. The +# DaemonStatusUpdater class is designed to support caching. The caching can be +# set up when an updater is initialized or on the fly, being used or refreshed +# when an update method is called. The update and legacy_update functions are +# to be provided by sub-classes that to mutate an existing status dictionary. +# +# The DaemonStatusUpdater expand method is designed to be used in an iterator +# or list comprehension in order to process the entries yielded by the listing +# methods mentioned above. This is intended to allow callers to list daemons +# with the level of detail needed rather than being forced to rely on a too-simple +# iterator and gather extra details in an ad-hoc way or get too much info than +# needed and incur extra costs getting that unwanted data. +# +# The CombinedStatusUpdater class exists so that multiple updaters can be +# easily combined. The init method of the class takes a list of other +# DaemonStatusUpdater classes and calls them (in order) to update the status +# dict. +# +# Use the CombinedStatusUpdater and a list of desired updaters to list/iterate +# with the level of detail your function needs. For example: +# >>> updater = CombinedStatusUpdater([ +# ... CoreStatusUpdater(), +# ... PowerLevelUpdater(), +# ... MyCoolCustomUpdater(), +# ... ]) +# >>> result = [updater.expand(ctx, entry) for entry in daemons(ctx)] +# +# These six lines let you flexibly perform the equivalent of list_daemons +# with a more precice level of detail needed by the caller. + import os import logging -from typing import TypedDict, Union, Optional, Iterator, List +from typing import TypedDict, Union, Optional, Iterator, List, Any, Dict, cast from .context import CephadmContext from .daemon_identity import DaemonIdentity @@ -192,3 +239,95 @@ def daemons_summary( daemon_type=daemon_type, ) ] + + +class DaemonStatusUpdater: + """Base class for types that can update and/or expand the daemon information + provided by the core listing functions in this module. + """ + + def update( + self, + val: Dict[str, Any], + ctx: CephadmContext, + identity: DaemonIdentity, + data_dir: str, + ) -> None: + """Update the val dict with new status information for the daemon with + the given identity and configuration dir. + """ + pass + + def legacy_update( + self, + val: Dict[str, Any], + ctx: CephadmContext, + fsid: str, + daemon_type: str, + name: str, + data_dir: str, + ) -> None: + """Update the val dict with new status information for a legacy daemon + described by the given parameters and configuration dir. + """ + pass + + def expand( + self, + ctx: CephadmContext, + entry: Union[LegacyDaemonEntry, DaemonEntry], + ) -> Dict[str, Any]: + """Return a status dictionary based on the entry object and its status + attribute expanded with additional information. + """ + if isinstance(entry, LegacyDaemonEntry): + status = cast(Dict[str, Any], entry.status) + self.legacy_update( + status, + ctx, + entry.fsid, + entry.daemon_type, + entry.name, + entry.data_dir, + ) + return status + status = cast(Dict[str, Any], entry.status) + self.update(status, ctx, entry.identity, entry.data_dir) + return status + + +class NoOpDaemonStatusUpdater(DaemonStatusUpdater): + """A daemon status updater that adds no new information to the status + dictionary. + """ + + pass + + +class CombinedStatusUpdater(DaemonStatusUpdater): + """A status updater that combines multiple status updaters together.""" + + def __init__(self, updaters: List[DaemonStatusUpdater]): + self.updaters = updaters + + def update( + self, + val: Dict[str, Any], + ctx: CephadmContext, + identity: DaemonIdentity, + data_dir: str, + ) -> None: + for updater in self.updaters: + updater.update(val, ctx, identity, data_dir) + + def legacy_update( + self, + val: Dict[str, Any], + ctx: CephadmContext, + fsid: str, + daemon_type: str, + name: str, + data_dir: str, + ) -> None: + for updater in self.updaters: + updater.legacy_update(val, ctx, fsid, daemon_type, name, data_dir)