From: Aleš Mrázek Date: Fri, 17 May 2024 12:03:45 +0000 (+0200) Subject: manager: controller: getting SubprocessStatus from particular Subprocess X-Git-Tag: v6.0.8~8^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70b0e78ea7f0deb1c16b1e013bba74c801a18b66;p=thirdparty%2Fknot-resolver.git manager: controller: getting SubprocessStatus from particular Subprocess --- diff --git a/manager/knot_resolver_manager/kres_manager.py b/manager/knot_resolver_manager/kres_manager.py index 8507a9fc1..29e43f7a2 100644 --- a/manager/knot_resolver_manager/kres_manager.py +++ b/manager/knot_resolver_manager/kres_manager.py @@ -344,13 +344,13 @@ class KresManager: # pylint: disable=too-many-instance-attributes invoke_callback = True continue - if detected_subprocesses[eid] is SubprocessStatus.FAILED: - logger.error("Subprocess '%s' is failed.", eid) + if detected_subprocesses[eid] is SubprocessStatus.FATAL: + logger.error("Subprocess '%s' is in FATAL state!", eid) invoke_callback = True continue if detected_subprocesses[eid] is SubprocessStatus.UNKNOWN: - logger.warning("Subprocess '%s' is in unknown state!", eid) + logger.warning("Subprocess '%s' is in UNKNOWN state!", eid) non_registered_ids = detected_subprocesses.keys() - set(expected_ids) if len(non_registered_ids) != 0: diff --git a/manager/knot_resolver_manager/kresd_controller/interface.py b/manager/knot_resolver_manager/kresd_controller/interface.py index 3df229e69..bd1ba59fd 100644 --- a/manager/knot_resolver_manager/kresd_controller/interface.py +++ b/manager/knot_resolver_manager/kresd_controller/interface.py @@ -25,6 +25,13 @@ class SubprocessType(Enum): GC = auto() +class SubprocessStatus(Enum): + RUNNING = auto() + FATAL = auto() + EXITED = auto() + UNKNOWN = auto() + + T = TypeVar("T", bound="KresID") @@ -185,6 +192,10 @@ class Subprocess(ABC): async def _restart(self) -> None: pass + @abstractmethod + def status(self) -> SubprocessStatus: + pass + @property def type(self) -> SubprocessType: return self.id.subprocess_type @@ -228,13 +239,6 @@ class Subprocess(ABC): await writer.wait_closed() # type: ignore -class SubprocessStatus(Enum): - RUNNING = auto() - FAILED = auto() - EXITED = auto() - UNKNOWN = auto() - - class SubprocessController(ABC): """ The common Subprocess Controller interface. This is what KresManager requires and what has to be implemented by all diff --git a/manager/knot_resolver_manager/kresd_controller/supervisord/__init__.py b/manager/knot_resolver_manager/kresd_controller/supervisord/__init__.py index d0a6c6333..5fb4d81d5 100644 --- a/manager/knot_resolver_manager/kresd_controller/supervisord/__init__.py +++ b/manager/knot_resolver_manager/kresd_controller/supervisord/__init__.py @@ -139,35 +139,39 @@ def _create_fast_proxy(config: KresConfig) -> Any: return getattr(proxy, "fast") +def _convert_subprocess_status(proc: Any) -> SubprocessStatus: + conversion_tbl = { + # "STOPPED": None, # filtered out elsewhere + "STARTING": SubprocessStatus.RUNNING, + "RUNNING": SubprocessStatus.RUNNING, + "BACKOFF": SubprocessStatus.RUNNING, + "STOPPING": SubprocessStatus.RUNNING, + "EXITED": SubprocessStatus.EXITED, + "FATAL": SubprocessStatus.FATAL, + "UNKNOWN": SubprocessStatus.UNKNOWN, + } + + if proc["statename"] in conversion_tbl: + status = conversion_tbl[proc["statename"]] + else: + logger.warning(f"Unknown supervisord process state {proc['statename']}") + status = SubprocessStatus.UNKNOWN + return status + + def _list_running_subprocesses(config: KresConfig) -> Dict[SupervisordKresID, SubprocessStatus]: - supervisord = _create_supervisord_proxy(config) - processes: Any = supervisord.getAllProcessInfo() - - def convert(proc: Any) -> SubprocessStatus: - conversion_tbl = { - # "STOPPED": None, # filtered out elsewhere - "STARTING": SubprocessStatus.RUNNING, - "RUNNING": SubprocessStatus.RUNNING, - "BACKOFF": SubprocessStatus.RUNNING, - "STOPPING": SubprocessStatus.RUNNING, - "EXITED": SubprocessStatus.EXITED, - "FATAL": SubprocessStatus.FAILED, - "UNKNOWN": SubprocessStatus.UNKNOWN, - } - - if proc["statename"] in conversion_tbl: - status = conversion_tbl[proc["statename"]] - else: - logger.warning(f"Unknown supervisord process state {proc['statename']}") - status = SubprocessStatus.UNKNOWN - return status + try: + supervisord = _create_supervisord_proxy(config) + processes: Any = supervisord.getAllProcessInfo() + except Fault as e: + raise SubprocessControllerException(f"failed to get info from all running processes: {e}") from e # there will be a manager process as well, but we don't want to report anything on ourselves processes = [pr for pr in processes if pr["name"] != "manager"] # convert all the names return { - SupervisordKresID.from_string(f"{pr['group']}:{pr['name']}"): convert(pr) + SupervisordKresID.from_string(f"{pr['group']}:{pr['name']}"): _convert_subprocess_status(pr) for pr in processes if pr["statename"] != "STOPPED" } @@ -190,6 +194,14 @@ class SupervisordSubprocess(Subprocess): def name(self): return str(self.id) + def status(self) -> SubprocessStatus: + try: + supervisord = _create_supervisord_proxy(self._config) + status = supervisord.getProcessInfo(self.name) + except Fault as e: + raise SubprocessControllerException(f"failed to get status from '{self.id}' process: {e}") from e + return _convert_subprocess_status(status) + @async_in_a_thread def _start(self) -> None: # +1 for canary process (same as in config_file.py)