diff --git a/lib/charms/hpc_libs/v0/slurm_ops.py b/lib/charms/hpc_libs/v0/slurm_ops.py index d49a38a..b48f0a3 100644 --- a/lib/charms/hpc_libs/v0/slurm_ops.py +++ b/lib/charms/hpc_libs/v0/slurm_ops.py @@ -62,11 +62,13 @@ def _on_install(self, _) -> None: "ConfigurationManager", "ServiceType", "SlurmManagerBase", + "SlurmOpsError", ] import json import logging import re +import socket import subprocess from collections.abc import Mapping from enum import Enum @@ -82,7 +84,7 @@ def _on_install(self, _) -> None: # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 3 +LIBPATCH = 5 # Charm library dependencies to fetch during `charmcraft pack`. PYDEPS = ["pyyaml>=6.0.1"] @@ -131,7 +133,8 @@ def install() -> None: def version() -> str: """Get the current version of Slurm installed on the system.""" info = yaml.safe_load(_snap("info", "slurm")) - ver: str = info["installed"] + if (ver := info.get("installed")) is None: + raise SlurmOpsError("unable to retrive snap info. Ensure slurm is correctly installed") return ver.split(maxsplit=1)[0] @@ -177,6 +180,7 @@ class ServiceType(Enum): """Type of Slurm service to manage.""" MUNGED = "munged" + PROMETHEUS_EXPORTER = "slurm-prometheus-exporter" SLURMD = "slurmd" SLURMCTLD = "slurmctld" SLURMDBD = "slurmdbd" @@ -208,6 +212,17 @@ def restart(self) -> None: """Restart service.""" _snap("restart", f"slurm.{self._service.value}") + def active(self) -> bool: + """Return True if the service is active.""" + info = yaml.safe_load(_snap("info", "slurm")) + if (services := info.get("services")) is None: + raise SlurmOpsError("unable to retrive snap info. Ensure slurm is correctly installed") + + # Assume `services` contains the service, since `ServiceManager` is not exposed as a + # public interface for now. + # We don't do `"active" in state` because the word "active" is also part of "inactive" :) + return "inactive" not in services[f"slurm.{self._service.value}"] + class ConfigurationManager: """Control configuration of a Slurm component.""" @@ -271,6 +286,13 @@ def generate_key(self) -> None: _mungectl("key", "generate") +class PrometheusExporterManager(ServiceManager): + """Manage `slurm-prometheus-exporter` service operations.""" + + def __init__(self) -> None: + self._service = ServiceType.PROMETHEUS_EXPORTER + + class SlurmManagerBase(ServiceManager): """Base manager for Slurm services.""" @@ -278,3 +300,9 @@ def __init__(self, service: ServiceType) -> None: self._service = service self.config = ConfigurationManager(service.config_name) self.munge = MungeManager() + self.exporter = PrometheusExporterManager() + + @property + def hostname(self) -> str: + """The hostname where this manager is running.""" + return socket.gethostname().split(".")[0] diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 783c38a..48aeff4 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -56,6 +56,7 @@ def test_install_fail(self, _, defer) -> None: defer.assert_called() @patch("slurmd_ops.SlurmdManager.install") + @patch("slurmd_ops.SlurmdManager.version", return_value="23.11.7") @patch("pathlib.Path.read_text", return_value="v1.0.0") @patch("ops.model.Unit.set_workload_version") @patch("ops.model.Resources.fetch") diff --git a/tests/unit/utils/test_slurmd.py b/tests/unit/utils/test_slurmd.py index 548086c..9c70eb2 100644 --- a/tests/unit/utils/test_slurmd.py +++ b/tests/unit/utils/test_slurmd.py @@ -26,18 +26,6 @@ class TestSlurmd(unittest.TestCase): """Unit tests for methods in slurmd utility module.""" - @patch("charms.operator_libs_linux.v1.systemd._systemctl") - def test_start(self, _) -> None: - slurmd.start() - - @patch("charms.operator_libs_linux.v1.systemd._systemctl") - def test_stop(self, _) -> None: - slurmd.stop() - - @patch("charms.operator_libs_linux.v1.systemd._systemctl") - def test_restart(self, _) -> None: - slurmd.restart() - @patch("pathlib.Path.write_text") def test_overwrite_default(self, _) -> None: slurmd.override_default("127.0.0.1")