Skip to content

Commit 7e3d13f

Browse files
Merge pull request #104 from NessieCanCode/check-slurmctld.service-for-config-path
Discover slurm config path from service file
2 parents 5fa07f8 + 7bad0b7 commit 7e3d13f

3 files changed

Lines changed: 56 additions & 7 deletions

File tree

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,14 @@ The workflow tags the repository, builds packages, and publishes artifacts to Gi
8383

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

9395

9496
```bash

src/slurmdb.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ def _write_last_run(end_date):
6363
logging.warning("Failed to write state file %s: %s", STATE_FILE, e)
6464

6565

66+
def _find_slurm_conf(service_paths=None):
67+
"""Return path to slurm.conf by inspecting slurmctld.service."""
68+
paths = service_paths or [
69+
"/usr/lib/systemd/system/slurmctld.service",
70+
"/lib/systemd/system/slurmctld.service",
71+
"/etc/systemd/system/slurmctld.service",
72+
]
73+
for svc in paths:
74+
try:
75+
with open(svc) as fh:
76+
for line in fh:
77+
line = line.strip()
78+
if line.startswith("ConditionPathExists=") and line.endswith("slurm.conf"):
79+
return line.split("=", 1)[1].strip()
80+
except OSError:
81+
continue
82+
return "/etc/slurm/slurm.conf"
83+
84+
6685
class SlurmDB:
6786
"""Simple wrapper around the Slurm accounting database."""
6887

@@ -77,7 +96,17 @@ def __init__(
7796
cluster=None,
7897
slurm_conf=None,
7998
):
80-
conf_path = config_file or os.environ.get("SLURMDB_CONF", "/etc/slurm/slurmdbd.conf")
99+
slurm_conf_path = (
100+
slurm_conf
101+
or os.environ.get("SLURM_CONF")
102+
or _find_slurm_conf()
103+
)
104+
105+
conf_path = (
106+
config_file
107+
or os.environ.get("SLURMDB_CONF")
108+
or os.path.join(os.path.dirname(slurm_conf_path), "slurmdbd.conf")
109+
)
81110
cfg = self._load_config(conf_path)
82111

83112
self.host = host or os.environ.get("SLURMDB_HOST") or cfg.get("host", "localhost")
@@ -88,7 +117,7 @@ def __init__(
88117
self._conn = None
89118
self._tres_map = None
90119
self._config_file = conf_path
91-
self._slurm_conf = slurm_conf or os.environ.get("SLURM_CONF", "/etc/slurm/slurm.conf")
120+
self._slurm_conf = slurm_conf_path
92121
self.cluster = (
93122
cluster
94123
or os.environ.get("SLURM_CLUSTER")

test/unit/slurmdb_validation.test.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import unittest
22
import json
3+
import os
4+
import tempfile
35
import pymysql
4-
from slurmdb import SlurmDB
6+
from slurmdb import SlurmDB, _find_slurm_conf
57
from slurm_schema import extract_schema, extract_schema_from_dump
68

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

22+
def test_slurm_conf_from_service_file(self):
23+
with tempfile.TemporaryDirectory() as tmp:
24+
svc = os.path.join(tmp, "slurmctld.service")
25+
slurm_conf = os.path.join(tmp, "slurm.conf")
26+
with open(svc, "w") as fh:
27+
fh.write(f"ConditionPathExists={slurm_conf}\n")
28+
with open(slurm_conf, "w") as fh:
29+
fh.write("ClusterName=test\n")
30+
slurmdbd = os.path.join(tmp, "slurmdbd.conf")
31+
with open(slurmdbd, "w") as fh:
32+
fh.write("StorageHost=localhost\n")
33+
path = _find_slurm_conf([svc])
34+
self.assertEqual(path, slurm_conf)
35+
db = SlurmDB(slurm_conf=path)
36+
self.assertEqual(db._config_file, slurmdbd)
37+
2038
def test_invalid_time_format(self):
2139
db = SlurmDB()
2240
with self.assertRaises(ValueError):

0 commit comments

Comments
 (0)