Skip to content

Commit e8846d4

Browse files
committed
wip: improve DB API
1 parent e4684e0 commit e8846d4

File tree

10 files changed

+962
-15
lines changed

10 files changed

+962
-15
lines changed

pyslurm/db/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,18 @@
4242
Association,
4343
AssociationFilter,
4444
)
45+
from .user import (
46+
Users,
47+
User,
48+
UserFilter,
49+
)
50+
from .account import (
51+
Accounts,
52+
Account,
53+
AccountFilter,
54+
)
55+
from .wckey import (
56+
WCKeys,
57+
WCKey,
58+
WCKeyFilter,
59+
)

pyslurm/db/account.pxd

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#########################################################################
2+
# account.pxd - pyslurm slurmdbd account api
3+
#########################################################################
4+
# Copyright (C) 2025 Toni Harzendorf <[email protected]>
5+
#
6+
# This file is part of PySlurm
7+
#
8+
# PySlurm is free software; you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation; either version 2 of the License, or
11+
# (at your option) any later version.
12+
13+
# PySlurm is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License along
19+
# with PySlurm; if not, write to the Free Software Foundation, Inc.,
20+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21+
#
22+
# cython: c_string_type=unicode, c_string_encoding=default
23+
# cython: language_level=3
24+
25+
from libc.string cimport memcpy, memset
26+
from pyslurm cimport slurm
27+
from pyslurm.slurm cimport (
28+
slurmdb_account_rec_t,
29+
slurmdb_assoc_rec_t,
30+
slurmdb_assoc_cond_t,
31+
slurmdb_account_cond_t,
32+
slurmdb_accounts_get,
33+
slurmdb_destroy_account_rec,
34+
slurmdb_destroy_account_cond,
35+
try_xmalloc,
36+
)
37+
from pyslurm.db.util cimport (
38+
SlurmList,
39+
SlurmListItem,
40+
make_char_list,
41+
slurm_list_to_pylist,
42+
qos_list_to_pylist,
43+
)
44+
from pyslurm.db.tres cimport (
45+
_set_tres_limits,
46+
TrackableResources,
47+
TrackableResourceLimits,
48+
)
49+
from pyslurm.db.connection cimport Connection
50+
from pyslurm.utils cimport cstr
51+
from pyslurm.db.qos cimport QualitiesOfService, _set_qos_list
52+
from pyslurm.db.assoc cimport Associations, Association, _parse_assoc_ptr
53+
from pyslurm.xcollections cimport MultiClusterMap
54+
from pyslurm.utils.uint cimport u16_set_bool_flag
55+
56+
57+
cdef class Accounts(MultiClusterMap):
58+
pass
59+
60+
61+
cdef class AccountFilter:
62+
cdef slurmdb_account_cond_t *ptr
63+
64+
cdef public:
65+
with_assocs
66+
with_deleted
67+
with_coordinators
68+
names
69+
organizations
70+
descriptions
71+
72+
73+
cdef class Account:
74+
cdef:
75+
slurmdb_account_rec_t *ptr
76+
77+
cdef readonly:
78+
cluster
79+
80+
cdef public:
81+
associations
82+
coordinators
83+
84+
@staticmethod
85+
cdef Account from_ptr(slurmdb_account_rec_t *in_ptr)

pyslurm/db/account.pyx

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#########################################################################
2+
# account.pyx - pyslurm slurmdbd account api
3+
#########################################################################
4+
# Copyright (C) 2023 Toni Harzendorf <[email protected]>
5+
#
6+
# This file is part of PySlurm
7+
#
8+
# PySlurm is free software; you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation; either version 2 of the License, or
11+
# (at your option) any later version.
12+
13+
# PySlurm is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License along
19+
# with PySlurm; if not, write to the Free Software Foundation, Inc.,
20+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21+
#
22+
# cython: c_string_type=unicode, c_string_encoding=default
23+
# cython: language_level=3
24+
25+
from pyslurm.core.error import RPCError
26+
from pyslurm.utils.helpers import (
27+
instance_to_dict,
28+
user_to_uid,
29+
)
30+
from pyslurm.utils.uint import *
31+
from pyslurm.db.connection import _open_conn_or_error
32+
from pyslurm import settings
33+
from pyslurm import xcollections
34+
35+
36+
cdef class Accounts(MultiClusterMap):
37+
38+
def __init__(self, accounts=None):
39+
super().__init__(data=accounts,
40+
typ="Accounts",
41+
val_type=Account,
42+
id_attr=Account.name,
43+
key_type=str)
44+
45+
@staticmethod
46+
def load(AccountFilter db_filter=None, Connection db_connection=None):
47+
cdef:
48+
Accounts out = Accounts()
49+
Account account
50+
AccountFilter cond = db_filter
51+
SlurmList account_data
52+
SlurmListItem account_ptr
53+
Connection conn
54+
SlurmList assoc_data
55+
SlurmListItem assoc_ptr
56+
Association assoc
57+
QualitiesOfService qos_data
58+
TrackableResources tres_data
59+
60+
if not db_filter:
61+
cond = AccountFilter()
62+
63+
if cond.with_assocs is not False:
64+
cond.with_assocs = True
65+
66+
cond._create()
67+
68+
conn = _open_conn_or_error(db_connection)
69+
70+
account_data = SlurmList.wrap(slurmdb_accounts_get(conn.ptr, cond.ptr))
71+
72+
if account_data.is_null:
73+
raise RPCError(msg="Failed to get Account data from slurmdbd.")
74+
75+
qos_data = QualitiesOfService.load(db_connection=conn,
76+
name_is_key=False)
77+
tres_data = TrackableResources.load(db_connection=conn,
78+
name_is_key=False)
79+
80+
for account_ptr in SlurmList.iter_and_pop(account_data):
81+
account = Account.from_ptr(<slurmdb_account_rec_t*>account_ptr.data)
82+
83+
cluster = account.cluster
84+
if cluster not in out.data:
85+
out.data[cluster] = {}
86+
out.data[cluster][account.name] = account
87+
88+
assoc_data = SlurmList.wrap(account.ptr.assoc_list, owned=False)
89+
for assoc_ptr in SlurmList.iter_and_pop(assoc_data):
90+
assoc = Association.from_ptr(<slurmdb_assoc_rec_t*>assoc_ptr.data)
91+
assoc.qos_data = qos_data
92+
assoc.tres_data = tres_data
93+
_parse_assoc_ptr(assoc)
94+
account.associations.append(assoc)
95+
96+
return out
97+
98+
99+
cdef class AccountFilter:
100+
101+
def __cinit__(self):
102+
self.ptr = NULL
103+
104+
def __init__(self, **kwargs):
105+
for k, v in kwargs.items():
106+
setattr(self, k, v)
107+
108+
def __dealloc__(self):
109+
self._dealloc()
110+
111+
def _dealloc(self):
112+
slurmdb_destroy_account_cond(self.ptr)
113+
self.ptr = NULL
114+
115+
def _alloc(self):
116+
self._dealloc()
117+
self.ptr = <slurmdb_account_cond_t*>try_xmalloc(sizeof(slurmdb_account_cond_t))
118+
if not self.ptr:
119+
raise MemoryError("xmalloc failed for slurmdb_account_cond_t")
120+
121+
memset(self.ptr, 0, sizeof(slurmdb_account_cond_t))
122+
123+
self.ptr.assoc_cond = <slurmdb_assoc_cond_t*>try_xmalloc(sizeof(slurmdb_assoc_cond_t))
124+
if not self.ptr.assoc_cond:
125+
raise MemoryError("xmalloc failed for slurmdb_assoc_cond_t")
126+
127+
def _parse_flag(self, val, flag_val):
128+
if val:
129+
self.ptr.flags |= flag_val
130+
131+
def _create(self):
132+
self._alloc()
133+
cdef slurmdb_account_cond_t *ptr = self.ptr
134+
135+
make_char_list(&ptr.assoc_cond.acct_list, self.names)
136+
self._parse_flag(self.with_assocs, slurm.SLURMDB_ACCT_FLAG_WASSOC)
137+
self._parse_flag(self.with_deleted, slurm.SLURMDB_ACCT_FLAG_DELETED)
138+
self._parse_flag(self.with_coordinators, slurm.SLURMDB_ACCT_FLAG_WCOORD)
139+
140+
141+
cdef class Account:
142+
143+
def __cinit__(self):
144+
self.ptr = NULL
145+
146+
def __init__(self, name=None, **kwargs):
147+
self._alloc_impl()
148+
self.name = name
149+
self._init_defaults()
150+
for k, v in kwargs.items():
151+
setattr(self, k, v)
152+
153+
def _init_defaults(self):
154+
self.cluster = settings.LOCAL_CLUSTER
155+
self.associations = []
156+
self.coordinators = []
157+
158+
def __dealloc__(self):
159+
self._dealloc_impl()
160+
161+
def _dealloc_impl(self):
162+
slurmdb_destroy_account_rec(self.ptr)
163+
self.ptr = NULL
164+
165+
def _alloc_impl(self):
166+
if not self.ptr:
167+
self.ptr = <slurmdb_account_rec_t*>try_xmalloc(
168+
sizeof(slurmdb_account_rec_t))
169+
if not self.ptr:
170+
raise MemoryError("xmalloc failed for slurmdb_account_rec_t")
171+
172+
memset(self.ptr, 0, sizeof(slurmdb_account_rec_t))
173+
174+
def __repr__(self):
175+
return f'pyslurm.db.{self.__class__.__name__}({self.name})'
176+
177+
@staticmethod
178+
cdef Account from_ptr(slurmdb_account_rec_t *in_ptr):
179+
cdef Account wrap = Account.__new__(Account)
180+
wrap.ptr = in_ptr
181+
wrap._init_defaults()
182+
return wrap
183+
184+
def to_dict(self):
185+
"""Database Account information formatted as a dictionary.
186+
187+
Returns:
188+
(dict): Database Account information as dict.
189+
"""
190+
return instance_to_dict(self)
191+
192+
def __eq__(self, other):
193+
if isinstance(other, Account):
194+
return self.name == other.name and self.cluster == other.cluster
195+
return NotImplemented
196+
197+
@property
198+
def name(self):
199+
return cstr.to_unicode(self.ptr.name)
200+
201+
@property
202+
def description(self):
203+
return cstr.to_unicode(self.ptr.description)
204+
205+
@property
206+
def organization(self):
207+
return cstr.to_unicode(self.ptr.organization)
208+
209+
@property
210+
def is_deleted(self):
211+
if self.ptr.flags & slurm.SLURMDB_ACCT_FLAG_DELETED:
212+
return True
213+
return False
214+
215+
# TODO: extract the association of this account

pyslurm/db/assoc.pxd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,17 @@ cdef class AssociationFilter:
6565
cdef public:
6666
users
6767
ids
68+
accounts
69+
parent_accounts
70+
clusters
71+
partitions
72+
qos
6873

6974

7075
cdef class Association:
7176
cdef:
7277
slurmdb_assoc_rec_t *ptr
78+
slurmdb_assoc_rec_t *umsg
7379
QualitiesOfService qos_data
7480
TrackableResources tres_data
7581

0 commit comments

Comments
 (0)