Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,14 @@ The workflow tags the repository, builds packages, and publishes artifacts to Gi

The `src/slurmdb.py` utility can connect to a running **SlurmDBD** instance and
export usage metrics as JSON. Connection details are automatically scraped from
`/etc/slurm/slurmdbd.conf` (or a custom path specified via the environment
variable `SLURMDB_CONF` or the `--conf` flag). Environment variables
`slurmdbd.conf` located alongside `slurm.conf` (discovered from
`slurmctld.service` via the `ConditionPathExists` directive, defaulting to
`/etc/slurm/slurm.conf`). A custom path can be specified via the environment
variable `SLURMDB_CONF` or the `--conf` flag. Environment variables
`SLURMDB_HOST`, `SLURMDB_PORT`, `SLURMDB_USER`, `SLURMDB_PASS` and `SLURMDB_DB`
override any values found in the configuration file. The cluster prefix used to
select the job tables is determined from `/etc/slurm/slurm.conf` but can be set
using `SLURM_CLUSTER`, `--cluster` or `--slurm-conf`.
select the job tables is determined from the Slurm configuration file. The
setting can be overridden using `SLURM_CLUSTER`, `--cluster` or `--slurm-conf`.


```bash
Expand Down
33 changes: 31 additions & 2 deletions src/slurmdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ def _write_last_run(end_date):
logging.warning("Failed to write state file %s: %s", STATE_FILE, e)


def _find_slurm_conf(service_paths=None):
"""Return path to slurm.conf by inspecting slurmctld.service."""
paths = service_paths or [
"/usr/lib/systemd/system/slurmctld.service",
"/lib/systemd/system/slurmctld.service",
"/etc/systemd/system/slurmctld.service",
]
for svc in paths:
try:
with open(svc) as fh:
for line in fh:
line = line.strip()
if line.startswith("ConditionPathExists=") and line.endswith("slurm.conf"):
return line.split("=", 1)[1].strip()
except OSError:
continue
return "/etc/slurm/slurm.conf"


class SlurmDB:
"""Simple wrapper around the Slurm accounting database."""

Expand All @@ -77,7 +96,17 @@ def __init__(
cluster=None,
slurm_conf=None,
):
conf_path = config_file or os.environ.get("SLURMDB_CONF", "/etc/slurm/slurmdbd.conf")
slurm_conf_path = (
slurm_conf
or os.environ.get("SLURM_CONF")
or _find_slurm_conf()
)

conf_path = (
config_file
or os.environ.get("SLURMDB_CONF")
or os.path.join(os.path.dirname(slurm_conf_path), "slurmdbd.conf")
)
cfg = self._load_config(conf_path)

self.host = host or os.environ.get("SLURMDB_HOST") or cfg.get("host", "localhost")
Expand All @@ -88,7 +117,7 @@ def __init__(
self._conn = None
self._tres_map = None
self._config_file = conf_path
self._slurm_conf = slurm_conf or os.environ.get("SLURM_CONF", "/etc/slurm/slurm.conf")
self._slurm_conf = slurm_conf_path
self.cluster = (
cluster
or os.environ.get("SLURM_CLUSTER")
Expand Down
20 changes: 19 additions & 1 deletion test/unit/slurmdb_validation.test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import unittest
import json
import os
import tempfile
import pymysql
from slurmdb import SlurmDB
from slurmdb import SlurmDB, _find_slurm_conf
from slurm_schema import extract_schema, extract_schema_from_dump

class SlurmDBValidationTests(unittest.TestCase):
Expand All @@ -17,6 +19,22 @@ def test_valid_config_allowed(self):
db = SlurmDB(host="localhost", port=3306, user="slurm", password="", database="slurm_acct_db", cluster="cluster1")
self.assertEqual(db.cluster, "cluster1")

def test_slurm_conf_from_service_file(self):
with tempfile.TemporaryDirectory() as tmp:
svc = os.path.join(tmp, "slurmctld.service")
slurm_conf = os.path.join(tmp, "slurm.conf")
with open(svc, "w") as fh:
fh.write(f"ConditionPathExists={slurm_conf}\n")
with open(slurm_conf, "w") as fh:
fh.write("ClusterName=test\n")
slurmdbd = os.path.join(tmp, "slurmdbd.conf")
with open(slurmdbd, "w") as fh:
fh.write("StorageHost=localhost\n")
path = _find_slurm_conf([svc])
self.assertEqual(path, slurm_conf)
db = SlurmDB(slurm_conf=path)
self.assertEqual(db._config_file, slurmdbd)

def test_invalid_time_format(self):
db = SlurmDB()
with self.assertRaises(ValueError):
Expand Down
Loading