]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephadm: add a status updater class to listing.py
authorJohn Mulligan <jmulligan@redhat.com>
Fri, 7 Feb 2025 16:40:25 +0000 (11:40 -0500)
committerJohn Mulligan <jmulligan@redhat.com>
Tue, 11 Feb 2025 21:08:05 +0000 (16:08 -0500)
These updater classes provide generic framework for getting extra
information about a deamon during a listing.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/cephadm/cephadmlib/listing.py

index 5e8bbb8755cd081ba5644197236d0dc0fc85e89a..44004b572af4dde715f7724f2a138ae3e66750ad 100644 (file)
@@ -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)