From 843f6635b9ed349952072fe4c294d3813cbefa41 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:00:16 +0200 Subject: [PATCH 01/11] update node.pyx for 25.05 --- pyslurm/core/node.pxd | 1 - pyslurm/core/node.pyx | 37 +++++-------------------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/pyslurm/core/node.pxd b/pyslurm/core/node.pxd index 7ebbcd05..a33a94a3 100644 --- a/pyslurm/core/node.pxd +++ b/pyslurm/core/node.pxd @@ -43,7 +43,6 @@ from pyslurm.slurm cimport ( slurm_free_node_info_members, slurm_free_update_node_msg, slurm_free_partition_info_msg, - slurm_get_select_nodeinfo, slurm_sprint_cpu_bind_type, slurm_node_state_string_complete, slurm_node_state_string, diff --git a/pyslurm/core/node.pyx b/pyslurm/core/node.pyx index 01489436..8a243c9b 100644 --- a/pyslurm/core/node.pyx +++ b/pyslurm/core/node.pyx @@ -507,14 +507,7 @@ cdef class Node: @property def allocated_memory(self): - cdef uint64_t alloc_memory = 0 - if self.info.select_nodeinfo: - slurm_get_select_nodeinfo( - self.info.select_nodeinfo, - slurm.SELECT_NODEDATA_MEM_ALLOC, - slurm.NODE_STATE_ALLOCATED, - &alloc_memory) - return alloc_memory + return u64_parse(self.info.alloc_memory, on_noval=0) @property def real_memory(self): @@ -547,7 +540,7 @@ cdef class Node: @property def effective_cpus(self): - return u16_parse(self.info.cpus_efctv) + return u16_parse(self.info.cpus_efctv, on_noval=0) @property def total_cpus(self): @@ -616,35 +609,15 @@ cdef class Node: @property def allocated_tres(self): - cdef char *alloc_tres = NULL - if self.info.select_nodeinfo: - slurm_get_select_nodeinfo( - self.info.select_nodeinfo, - slurm.SELECT_NODEDATA_TRES_ALLOC_FMT_STR, - slurm.NODE_STATE_ALLOCATED, - &alloc_tres - ) - return cstr.to_dict(alloc_tres) + return cstr.to_dict(self.info.alloc_tres_fmt_str) @property def allocated_cpus(self): - cdef uint16_t alloc_cpus = 0 - if self.info.select_nodeinfo: - slurm_get_select_nodeinfo( - self.info.select_nodeinfo, - slurm.SELECT_NODEDATA_SUBCNT, - slurm.NODE_STATE_ALLOCATED, - &alloc_cpus - ) - return alloc_cpus + return u16_parse(self.info.alloc_cpus, on_noval=0) @property def idle_cpus(self): - efctv = self.effective_cpus - if not efctv: - return None - - return efctv - self.allocated_cpus + return self.effective_cpus - self.allocated_cpus @property def cpu_binding(self): From e72f7955212c1cf56be6201b6ddb29c0d5407917 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:00:51 +0200 Subject: [PATCH 02/11] remove unusued defines --- pyslurm/pydefines/slurm_defines.pxi | 5 ----- pyslurm/pydefines/slurm_enums.pxi | 17 ----------------- pyslurm/pydefines/slurm_errno_enums.pxi | 1 - pyslurm/pydefines/slurmdb_defines.pxi | 8 -------- 4 files changed, 31 deletions(-) diff --git a/pyslurm/pydefines/slurm_defines.pxi b/pyslurm/pydefines/slurm_defines.pxi index 01e29465..509eac9b 100644 --- a/pyslurm/pydefines/slurm_defines.pxi +++ b/pyslurm/pydefines/slurm_defines.pxi @@ -1,8 +1,5 @@ # EXPOSE SLURM DEFINES TO PYTHON SPACE -SYSTEM_DIMENSIONS = slurm.SYSTEM_DIMENSIONS -HIGHEST_DIMENSIONS = slurm.HIGHEST_DIMENSIONS - INFINITE8 = slurm.INFINITE8 INFINITE16 = slurm.INFINITE16 INFINITE = slurm.INFINITE @@ -290,7 +287,6 @@ DEBUG_FLAG_PRIO = slurm.DEBUG_FLAG_PRIO DEBUG_FLAG_BACKFILL = slurm.DEBUG_FLAG_BACKFILL DEBUG_FLAG_GANG = slurm.DEBUG_FLAG_GANG DEBUG_FLAG_RESERVATION = slurm.DEBUG_FLAG_RESERVATION -DEBUG_FLAG_FRONT_END = slurm.DEBUG_FLAG_FRONT_END DEBUG_FLAG_SWITCH = slurm.DEBUG_FLAG_SWITCH DEBUG_FLAG_ENERGY = slurm.DEBUG_FLAG_ENERGY DEBUG_FLAG_LICENSE = slurm.DEBUG_FLAG_LICENSE @@ -365,7 +361,6 @@ TRIGGER_RES_TYPE_NODE = slurm.TRIGGER_RES_TYPE_NODE TRIGGER_RES_TYPE_SLURMCTLD = slurm.TRIGGER_RES_TYPE_SLURMCTLD TRIGGER_RES_TYPE_SLURMDBD = slurm.TRIGGER_RES_TYPE_SLURMDBD TRIGGER_RES_TYPE_DATABASE = slurm.TRIGGER_RES_TYPE_DATABASE -TRIGGER_RES_TYPE_FRONT_END = slurm.TRIGGER_RES_TYPE_FRONT_END TRIGGER_RES_TYPE_OTHER = slurm.TRIGGER_RES_TYPE_OTHER TRIGGER_TYPE_UP = slurm.TRIGGER_TYPE_UP diff --git a/pyslurm/pydefines/slurm_enums.pxi b/pyslurm/pydefines/slurm_enums.pxi index d813ef6e..31896413 100644 --- a/pyslurm/pydefines/slurm_enums.pxi +++ b/pyslurm/pydefines/slurm_enums.pxi @@ -37,7 +37,6 @@ WAIT_ASSOC_TIME_LIMIT = slurm.WAIT_ASSOC_TIME_LIMIT WAIT_RESERVATION = slurm.WAIT_RESERVATION WAIT_NODE_NOT_AVAIL = slurm.WAIT_NODE_NOT_AVAIL WAIT_HELD_USER = slurm.WAIT_HELD_USER -WAIT_FRONT_END = slurm.WAIT_FRONT_END FAIL_DOWN_PARTITION = slurm.FAIL_DOWN_PARTITION FAIL_DOWN_NODE = slurm.FAIL_DOWN_NODE FAIL_BAD_CONSTRAINTS = slurm.FAIL_BAD_CONSTRAINTS @@ -249,22 +248,6 @@ SWITCH_PLUGIN_CRAY = slurm.SWITCH_PLUGIN_CRAY # end enum switch_plugin_type -# enum select_jobdata_type - -SELECT_JOBDATA_NETWORK = slurm.SELECT_JOBDATA_NETWORK - -# end enum select_jobdata_type - -# enum select_nodedata_type - -SELECT_NODEDATA_SUBCNT = slurm.SELECT_NODEDATA_SUBCNT -SELECT_NODEDATA_PTR = slurm.SELECT_NODEDATA_PTR -SELECT_NODEDATA_MEM_ALLOC = slurm.SELECT_NODEDATA_MEM_ALLOC -SELECT_NODEDATA_TRES_ALLOC_FMT_STR = slurm.SELECT_NODEDATA_TRES_ALLOC_FMT_STR -SELECT_NODEDATA_TRES_ALLOC_WEIGHTED = slurm.SELECT_NODEDATA_TRES_ALLOC_WEIGHTED - -# end enum select_nodedata_type - # enum select_print_mode SELECT_PRINT_HEAD = slurm.SELECT_PRINT_HEAD diff --git a/pyslurm/pydefines/slurm_errno_enums.pxi b/pyslurm/pydefines/slurm_errno_enums.pxi index b31e0802..faa9c63f 100644 --- a/pyslurm/pydefines/slurm_errno_enums.pxi +++ b/pyslurm/pydefines/slurm_errno_enums.pxi @@ -151,7 +151,6 @@ ESLURMD_PROLOG_FAILED = slurm.ESLURMD_PROLOG_FAILED ESLURMD_EPILOG_FAILED = slurm.ESLURMD_EPILOG_FAILED ESLURMD_TOOMANYSTEPS = slurm.ESLURMD_TOOMANYSTEPS ESLURMD_STEP_EXISTS = slurm.ESLURMD_STEP_EXISTS -ESLURMD_JOB_NOTRUNNING = slurm.ESLURMD_JOB_NOTRUNNING ESLURMD_STEP_SUSPENDED = slurm.ESLURMD_STEP_SUSPENDED ESLURMD_STEP_NOTSUSPENDED = slurm.ESLURMD_STEP_NOTSUSPENDED ESLURMD_INVALID_SOCKET_NAME_LEN = slurm.ESLURMD_INVALID_SOCKET_NAME_LEN diff --git a/pyslurm/pydefines/slurmdb_defines.pxi b/pyslurm/pydefines/slurmdb_defines.pxi index 41babeec..5bc36b38 100644 --- a/pyslurm/pydefines/slurmdb_defines.pxi +++ b/pyslurm/pydefines/slurmdb_defines.pxi @@ -60,14 +60,6 @@ SLURMDB_FS_USE_PARENT = slurm.SLURMDB_FS_USE_PARENT SLURMDB_CLASSIFIED_FLAG = slurm.SLURMDB_CLASSIFIED_FLAG SLURMDB_CLASS_BASE = slurm.SLURMDB_CLASS_BASE -CLUSTER_FLAG_A2 = slurm.CLUSTER_FLAG_A2 -CLUSTER_FLAG_A3 = slurm.CLUSTER_FLAG_A3 -CLUSTER_FLAG_A4 = slurm.CLUSTER_FLAG_A4 -CLUSTER_FLAG_A5 = slurm.CLUSTER_FLAG_A5 -CLUSTER_FLAG_A6 = slurm.CLUSTER_FLAG_A6 -CLUSTER_FLAG_A7 = slurm.CLUSTER_FLAG_A7 CLUSTER_FLAG_MULTSD = slurm.CLUSTER_FLAG_MULTSD -CLUSTER_FLAG_A9 = slurm.CLUSTER_FLAG_A9 -CLUSTER_FLAG_FE = slurm.CLUSTER_FLAG_FE CLUSTER_FLAG_FED = slurm.CLUSTER_FLAG_FED CLUSTER_FLAG_EXT = slurm.CLUSTER_FLAG_EXT From 30e4f780daab6147f00d1258f74ef3c0b647c495 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:01:01 +0200 Subject: [PATCH 03/11] change prolog_epilog_timeout to prolog_timeout and epilog_timeout --- pyslurm/core/slurmctld/config.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyslurm/core/slurmctld/config.pyx b/pyslurm/core/slurmctld/config.pyx index f1a2e79c..e73474e0 100644 --- a/pyslurm/core/slurmctld/config.pyx +++ b/pyslurm/core/slurmctld/config.pyx @@ -478,10 +478,6 @@ cdef class Config: def first_job_id(self): return u32_parse(self.ptr.first_job_id) - @property - def get_environment_timeout(self): - return u16_parse(self.ptr.get_env_timeout) - @property def gres_types(self): return cstr.to_list(self.ptr.gres_plugins) @@ -847,8 +843,12 @@ cdef class Config: self.ptr.prolog_cnt) @property - def prolog_epilog_timeout(self): - return u16_parse(self.ptr.prolog_epilog_timeout) + def prolog_timeout(self): + return u16_parse(self.ptr.prolog_timeout) + + @property + def epilog_timeout(self): + return u16_parse(self.ptr.epilog_timeout) @property def prolog_slurmctld(self): From c3b15e31392f1aa964899fc6bc586dabdda9da22 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:01:45 +0200 Subject: [PATCH 04/11] remove lft and rgt from association --- pyslurm/db/assoc.pyx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pyslurm/db/assoc.pyx b/pyslurm/db/assoc.pyx index 36460cbe..94442870 100644 --- a/pyslurm/db/assoc.pyx +++ b/pyslurm/db/assoc.pyx @@ -299,10 +299,6 @@ cdef class Association: def is_default(self): return u16_parse_bool(self.ptr.is_def) - @property - def lft(self): - return u32_parse(self.ptr.lft) - @property def max_jobs(self): return u32_parse(self.ptr.max_jobs, zero_is_noval=False) @@ -367,10 +363,6 @@ cdef class Association: def priority(self, val): self.ptr.priority = u32(val) - @property - def rgt(self): - return u32_parse(self.ptr.rgt) - @property def shares(self): return u32_parse(self.ptr.shares_raw, zero_is_noval=False) From efe6c953137d446c4ace6805250af2cc622c7780 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:02:08 +0200 Subject: [PATCH 05/11] update definitions for structs necessary to get batch script --- pyslurm/slurm/extra.pxi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyslurm/slurm/extra.pxi b/pyslurm/slurm/extra.pxi index c6a8a42f..e08651ed 100644 --- a/pyslurm/slurm/extra.pxi +++ b/pyslurm/slurm/extra.pxi @@ -35,7 +35,6 @@ ctypedef struct persist_conn_t: char *cluster_name time_t comm_fail_time uint16_t my_port - int fd uint16_t flags bool inited persist_conn_type_t persist_type @@ -117,11 +116,12 @@ ctypedef struct slurm_msg_t: uint32_t body_offset buf_t *buffer persist_conn_t *conn - int conn_fd conmgr_fd_t *conmgr_fd void *data uint16_t flags uint8_t hash_index + char *tls_cert + void *tls_conn uint16_t msg_type uint16_t protocol_version forward_t forward From f73f3820f0d998017c38903bd36fee80f5c6724c Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:08:24 +0200 Subject: [PATCH 06/11] regenerate slurm headers for 25.05 --- pyslurm/slurm/slurm.h.pxi | 152 +++++++++++++++----------------- pyslurm/slurm/slurm_errno.h.pxi | 11 ++- pyslurm/slurm/slurmdb.h.pxi | 89 +++++++++++-------- 3 files changed, 131 insertions(+), 121 deletions(-) diff --git a/pyslurm/slurm/slurm.h.pxi b/pyslurm/slurm/slurm.h.pxi index 76768ba8..e6c8629d 100644 --- a/pyslurm/slurm/slurm.h.pxi +++ b/pyslurm/slurm/slurm.h.pxi @@ -9,7 +9,7 @@ # * C-Macros are listed with their appropriate uint type # * Any definitions that cannot be translated are not included in this file # -# Generated on 2024-12-04T13:40:11.790952 +# Generated on 2025-09-28T15:03:24.037044 # # The Original Copyright notice from slurm.h has been included # below: @@ -53,8 +53,6 @@ cdef extern from "slurm/slurm.h": - uint8_t SYSTEM_DIMENSIONS - uint8_t HIGHEST_DIMENSIONS uint8_t HOST_NAME_MAX uint8_t INFINITE8 uint16_t INFINITE16 @@ -81,6 +79,7 @@ cdef extern from "slurm/slurm.h": uint8_t JOB_STATE_BASE uint32_t JOB_STATE_FLAGS uint16_t JOB_LAUNCH_FAILED + uint16_t JOB_GETENV_FAILED uint16_t JOB_REQUEUE uint16_t JOB_REQUEUE_HOLD uint16_t JOB_SPECIAL_EXIT @@ -161,6 +160,7 @@ cdef extern from "slurm/slurm.h": uint8_t MEM_BIND_TYPE_FLAGS_MASK uint8_t NODE_STATE_BASE uint32_t NODE_STATE_FLAGS + uint8_t NODE_STATE_EXTERNAL uint8_t NODE_STATE_RES uint8_t NODE_STATE_UNDRAIN uint8_t NODE_STATE_CLOUD @@ -184,6 +184,7 @@ cdef extern from "slurm/slurm.h": uint32_t NODE_STATE_POWER_DRAIN uint32_t NODE_STATE_DYNAMIC_NORM uint32_t NODE_STATE_BLOCKED + uint8_t NODE_CERT_TOKEN_SET uint8_t SHOW_ALL uint8_t SHOW_DETAIL uint8_t SHOW_MIXED @@ -236,6 +237,7 @@ cdef extern from "slurm/slurm.h": uint16_t PRIORITY_FLAGS_NO_NORMAL_PART uint16_t PRIORITY_FLAGS_NO_NORMAL_QOS uint16_t PRIORITY_FLAGS_NO_NORMAL_TRES + uint16_t PRIORITY_FLAGS_MAX_TRES_GRES uint8_t KILL_INV_DEP uint8_t NO_KILL_INV_DEP uint8_t HAS_STATE_DIR @@ -260,6 +262,7 @@ cdef extern from "slurm/slurm.h": uint32_t RESET_ACCRUE_TIME uint32_t CRON_JOB uint32_t JOB_MEM_SET + uint32_t EXTERNAL_JOB uint32_t USE_DEFAULT_ACCT uint32_t USE_DEFAULT_PART uint32_t USE_DEFAULT_QOS @@ -277,6 +280,7 @@ cdef extern from "slurm/slurm.h": uint64_t GRES_MULT_TASKS_PER_SHARING uint64_t GRES_ALLOW_TASK_SHARING uint64_t STEPMGR_ENABLED + uint64_t HETJOB_PURGE uint8_t X11_FORWARD_ALL uint8_t X11_FORWARD_BATCH uint8_t X11_FORWARD_FIRST @@ -352,6 +356,7 @@ cdef extern from "slurm/slurm.h": uint64_t RESERVE_FLAG_USER_DEL uint64_t RESERVE_FLAG_NO_USER_DEL uint64_t RESERVE_FLAG_SCHED_FAILED + uint64_t RESERVE_FLAG_FORCE_START uint8_t DEBUG_FLAG_SELECT_TYPE uint8_t DEBUG_FLAG_STEPS uint8_t DEBUG_FLAG_TRIGGERS @@ -367,7 +372,7 @@ cdef extern from "slurm/slurm.h": uint16_t DEBUG_FLAG_BACKFILL uint16_t DEBUG_FLAG_GANG uint16_t DEBUG_FLAG_RESERVATION - uint16_t DEBUG_FLAG_FRONT_END + uint16_t DEBUG_FLAG_AUDIT_TLS uint32_t DEBUG_FLAG_SACK uint32_t DEBUG_FLAG_SWITCH uint32_t DEBUG_FLAG_ENERGY @@ -413,6 +418,7 @@ cdef extern from "slurm/slurm.h": uint8_t PREEMPT_MODE_REQUEUE uint8_t PREEMPT_MODE_CANCEL uint8_t PREEMPT_MODE_COND_OFF + uint16_t PREEMPT_MODE_PRIORITY uint16_t PREEMPT_MODE_WITHIN uint16_t PREEMPT_MODE_GANG uint8_t RECONFIG_KEEP_PART_INFO @@ -457,7 +463,6 @@ cdef extern from "slurm/slurm.h": uint8_t LOG_FMT_SHORT uint8_t LOG_FMT_THREAD_ID uint8_t LOG_FMT_RFC3339 - uint16_t LOG_FMT_FORMAT_STDERR uint8_t STAT_COMMAND_RESET uint8_t STAT_COMMAND_GET uint8_t TRIGGER_FLAG_PERM @@ -466,7 +471,6 @@ cdef extern from "slurm/slurm.h": uint8_t TRIGGER_RES_TYPE_SLURMCTLD uint8_t TRIGGER_RES_TYPE_SLURMDBD uint8_t TRIGGER_RES_TYPE_DATABASE - uint8_t TRIGGER_RES_TYPE_FRONT_END uint8_t TRIGGER_RES_TYPE_OTHER uint8_t TRIGGER_TYPE_UP uint8_t TRIGGER_TYPE_DOWN @@ -506,6 +510,7 @@ cdef extern from "slurm/slurm.h": uint16_t KILL_NO_SIG_FAIL uint16_t KILL_JOBS_VERBOSE uint16_t KILL_CRON + uint16_t KILL_FAIL_JOB uint16_t WARN_SENT uint8_t BB_FLAG_DISABLE_PERSISTENT uint8_t BB_FLAG_ENABLE_PERSISTENT @@ -541,10 +546,6 @@ cdef extern from "slurm/slurm.h": ctypedef job_resources job_resources_t - ctypedef select_jobinfo select_jobinfo_t - - ctypedef select_nodeinfo select_nodeinfo_t - ctypedef jobacctinfo jobacctinfo_t ctypedef allocation_msg_thread allocation_msg_thread_t @@ -588,7 +589,7 @@ cdef extern from "slurm/slurm.h": WAIT_RESERVATION WAIT_NODE_NOT_AVAIL WAIT_HELD_USER - WAIT_FRONT_END + DEFUNCT_WAIT_17 FAIL_DEFER FAIL_DOWN_PARTITION FAIL_DOWN_NODE @@ -830,16 +831,6 @@ cdef extern from "slurm/slurm.h": SWITCH_PLUGIN_SLINGSHOT SWITCH_PLUGIN_NVIDIA_IMEX - cdef enum select_jobdata_type: - SELECT_JOBDATA_NETWORK - - cdef enum select_nodedata_type: - SELECT_NODEDATA_SUBCNT - SELECT_NODEDATA_PTR - SELECT_NODEDATA_MEM_ALLOC - SELECT_NODEDATA_TRES_ALLOC_FMT_STR - SELECT_NODEDATA_TRES_ALLOC_WEIGHTED - cdef enum select_print_mode: SELECT_PRINT_HEAD SELECT_PRINT_DATA @@ -956,6 +947,7 @@ cdef extern from "slurm/slurm.h": SLURMD_OFF_SPEC CPU_BIND_OFF OOM_KILL_STEP + SLURMD_SPEC_OVERRIDE ctypedef cpu_bind_type cpu_bind_type_t @@ -1000,9 +992,11 @@ cdef extern from "slurm/slurm.h": SSF_NO_SIG_FAIL SSF_EXT_LAUNCHER SSF_GRES_ALLOW_TASK_SHARING + SSF_WAIT_FOR_CHILDREN + SSF_KILL_ON_BAD_EXIT cdef enum topology_plugin_type: - TOPOLOGY_PLUGIN_DEFAULT + TOPOLOGY_PLUGIN_FLAT TOPOLOGY_PLUGIN_3DTORUS TOPOLOGY_PLUGIN_TREE TOPOLOGY_PLUGIN_BLOCK @@ -1084,6 +1078,7 @@ cdef extern from "slurm/slurm.h": uint64_t base_consumed_energy uint64_t consumed_energy uint32_t current_watts + uint64_t last_adjustment uint64_t previous_consumed_energy time_t poll_time time_t slurmd_start_time @@ -1103,6 +1098,7 @@ cdef extern from "slurm/slurm.h": char* admin_comment char* alloc_node uint16_t alloc_resp_port + char* alloc_tls_cert uint32_t alloc_sid uint32_t argc char** argv @@ -1299,6 +1295,7 @@ cdef extern from "slurm/slurm.h": uint32_t job_state time_t last_sched_eval char* licenses + char* licenses_allocated uint16_t mail_type char* mail_user uint32_t max_cpus @@ -1354,6 +1351,7 @@ cdef extern from "slurm/slurm.h": char* std_err char* std_in char* std_out + uint16_t segment_size time_t submit_time time_t suspend_time char* system_comment @@ -1477,7 +1475,6 @@ cdef extern from "slurm/slurm.h": uint16_t* cpt_compact_array uint32_t cpt_compact_cnt uint32_t* cpt_compact_reps - char* front_end slurm_node_alias_addrs_t* alias_addrs uint32_t node_cnt char* node_list @@ -1595,7 +1592,6 @@ cdef extern from "slurm/slurm.h": ctypedef top_job_msg top_job_msg_t ctypedef struct slurm_step_launch_params_t: - char* alias_list uint32_t argc char** argv uint32_t envc @@ -1621,6 +1617,7 @@ cdef extern from "slurm/slurm.h": uint32_t het_job_nnodes uint32_t het_job_ntasks uint32_t het_job_step_cnt + uint32_t* het_job_step_task_cnts uint16_t* het_job_task_cnts uint32_t** het_job_tids uint32_t* het_job_tid_offsets @@ -1721,8 +1718,10 @@ cdef extern from "slurm/slurm.h": uint32_t cpu_freq_max uint32_t cpu_freq_gov char* cpus_per_tres + char* cwd char* mem_per_tres char* name + char* job_name char* network char* nodes int32_t* node_inx @@ -1737,11 +1736,14 @@ cdef extern from "slurm/slurm.h": uint16_t start_protocol_ver uint32_t state slurm_step_id_t step_id + char* std_err + char* std_in + char* std_out char* submit_line uint32_t task_dist uint32_t time_limit - char* tres_alloc_str char* tres_bind + char* tres_fmt_alloc_str char* tres_freq char* tres_per_step char* tres_per_node @@ -1781,10 +1783,15 @@ cdef extern from "slurm/slurm.h": slurm_step_id_t step_id cdef struct node_info: + uint16_t alloc_cpus + uint64_t alloc_memory + char* alloc_tres_fmt_str char* arch char* bcast_address uint16_t boards time_t boot_time + uint16_t cert_flags + time_t cert_last_renewal char* cluster_name uint16_t cores uint16_t core_spec_cnt @@ -1824,11 +1831,11 @@ cdef extern from "slurm/slurm.h": uint32_t reason_uid time_t resume_after char* resv_name - dynamic_plugin_data_t* select_nodeinfo time_t slurmd_start_time uint16_t sockets uint16_t threads uint32_t tmp_disk + char* topology_str uint32_t weight char* tres_fmt_str char* version @@ -1842,29 +1849,6 @@ cdef extern from "slurm/slurm.h": ctypedef node_info_msg node_info_msg_t - cdef struct front_end_info: - char* allow_groups - char* allow_users - time_t boot_time - char* deny_groups - char* deny_users - char* name - uint32_t node_state - char* reason - time_t reason_time - uint32_t reason_uid - time_t slurmd_start_time - char* version - - ctypedef front_end_info front_end_info_t - - cdef struct front_end_info_msg: - time_t last_update - uint32_t record_count - front_end_info_t* front_end_array - - ctypedef front_end_info_msg front_end_info_msg_t - cdef struct topo_info: uint16_t level uint32_t link_speed @@ -1874,13 +1858,21 @@ cdef extern from "slurm/slurm.h": ctypedef topo_info topo_info_t + cdef struct topo_info_request_msg: + char* name + + ctypedef topo_info_request_msg topo_info_request_msg_t + cdef struct topo_info_response_msg: - uint32_t record_count - topo_info_t* topo_array dynamic_plugin_data_t* topo_info ctypedef topo_info_response_msg topo_info_response_msg_t + cdef struct topo_config_response_msg: + char* config + + ctypedef topo_config_response_msg topo_config_response_msg_t + cdef struct job_alloc_info_msg: uint32_t job_id char* req_cluster @@ -1952,6 +1944,7 @@ cdef extern from "slurm/slurm.h": uint16_t state_up uint32_t suspend_time uint16_t suspend_timeout + char* topology_name uint32_t total_cpus uint32_t total_nodes char* tres_fmt_str @@ -1966,7 +1959,6 @@ cdef extern from "slurm/slurm.h": cdef struct resource_allocation_response_msg: char* account uint32_t job_id - char* alias_list char* batch_host uint32_t cpu_freq_min uint32_t cpu_freq_max @@ -1979,7 +1971,6 @@ cdef extern from "slurm/slurm.h": gid_t gid char* group_name char* job_submit_user_msg - slurm_addr_t* node_addr uint32_t node_cnt char* node_list uint16_t ntasks_per_board @@ -1992,6 +1983,7 @@ cdef extern from "slurm/slurm.h": char* qos char* resv_name char* tres_per_node + char* tres_per_task uid_t uid char* user_name void* working_cluster_rec @@ -2006,6 +1998,7 @@ cdef extern from "slurm/slurm.h": ctypedef partition_info_msg partition_info_msg_t cdef struct will_run_response_msg: + char* cluster_name uint32_t job_id char* job_submit_user_msg char* node_list @@ -2013,7 +2006,6 @@ cdef extern from "slurm/slurm.h": list_t* preemptee_job_id uint32_t proc_cnt time_t start_time - double sys_usage_per ctypedef will_run_response_msg will_run_response_msg_t @@ -2074,6 +2066,7 @@ cdef extern from "slurm/slurm.h": char* partition uint32_t purge_comp_time time_t start_time + time_t time_force char* tres_str char* users @@ -2116,6 +2109,8 @@ cdef extern from "slurm/slurm.h": char* bcast_exclude char* bcast_parameters time_t boot_time + char* certgen_params + char* certgen_type char* certmgr_params char* certmgr_type void* cgroup_conf @@ -2142,11 +2137,11 @@ cdef extern from "slurm/slurm.h": uint32_t epilog_msg_time char** epilog_slurmctld uint32_t epilog_slurmctld_cnt + uint16_t epilog_timeout char* fed_params uint32_t first_job_id uint16_t fs_dampening_factor uint16_t getnameinfo_cache_timeout - uint16_t get_env_timeout char* gres_plugins uint16_t group_time uint16_t group_force @@ -2156,6 +2151,7 @@ cdef extern from "slurm/slurm.h": uint16_t health_check_interval uint16_t health_check_node_state char* health_check_program + uint32_t host_unreach_retry_count uint16_t inactive_limit char* interactive_step_opts char* job_acct_gather_freq @@ -2203,7 +2199,6 @@ cdef extern from "slurm/slurm.h": uint32_t next_job_id void* node_features_conf char* node_features_plugins - char* node_prefix uint16_t over_time_limit char* plugindir char* plugstack @@ -2232,9 +2227,9 @@ cdef extern from "slurm/slurm.h": char* proctrack_type char** prolog uint32_t prolog_cnt - uint16_t prolog_epilog_timeout char** prolog_slurmctld uint32_t prolog_slurmctld_cnt + uint16_t prolog_timeout uint16_t propagate_prio_process uint16_t prolog_flags char* propagate_rlimits @@ -2361,18 +2356,11 @@ cdef extern from "slurm/slurm.h": char* reason uint32_t reason_uid uint32_t resume_after + char* topology_str uint32_t weight ctypedef slurm_update_node_msg update_node_msg_t - cdef struct slurm_update_front_end_msg: - char* name - uint32_t node_state - char* reason - uint32_t reason_uid - - ctypedef slurm_update_front_end_msg update_front_end_msg_t - ctypedef partition_info update_part_msg_t cdef struct job_sbcast_cred_msg: @@ -2497,6 +2485,8 @@ cdef extern from "slurm/slurm.h": uint32_t last_consumed uint32_t last_deficit time_t last_update + uint8_t mode + char* nodes ctypedef slurm_license_info slurm_license_info_t @@ -2575,6 +2565,8 @@ cdef extern from "slurm/slurm.h": int slurm_job_will_run2(job_desc_msg_t* req, will_run_response_msg_t** will_run_resp) + int slurm_sort_will_run_resp(void* a, void* b) + int slurm_sbcast_lookup(slurm_selected_step_t* selected_step, job_sbcast_cred_msg_t** info) void slurm_free_sbcast_cred_msg(job_sbcast_cred_msg_t* msg) @@ -2699,6 +2691,10 @@ cdef extern from "slurm/slurm.h": void slurm_get_job_stdout(char* buf, int buf_size, job_info_t* job_ptr) + char* slurm_expand_step_stdio_fields(char* path, job_step_info_t* step) + + char* slurm_expand_job_stdio_fields(char* path, job_info_t* job) + long slurm_get_rem_time(uint32_t jobid) int slurm_job_node_ready(uint32_t job_id) @@ -2767,6 +2763,8 @@ cdef extern from "slurm/slurm.h": int slurm_get_node_alias_addrs(char* node_list, slurm_node_alias_addrs_t** alias_addrs) + int slurm_controller_hostlist_expansion(const char* hostlist, char** expanded) + void slurm_free_node_info_msg(node_info_msg_t* node_buffer_ptr) void slurm_print_node_info_msg(FILE* out, node_info_msg_t* node_info_msg_ptr, int one_liner) @@ -2783,27 +2781,17 @@ cdef extern from "slurm/slurm.h": int slurm_delete_node(update_node_msg_t* node_msg) - int slurm_load_front_end(time_t update_time, front_end_info_msg_t** resp) - - void slurm_free_front_end_info_msg(front_end_info_msg_t* front_end_buffer_ptr) - - void slurm_print_front_end_info_msg(FILE* out, front_end_info_msg_t* front_end_info_msg_ptr, int one_liner) + int slurm_load_topo(topo_info_response_msg_t** topo_info_msg_pptr, char* name) - void slurm_print_front_end_table(FILE* out, front_end_info_t* front_end_ptr, int one_liner) - - char* slurm_sprint_front_end_table(front_end_info_t* front_end_ptr, int one_liner) - - void slurm_init_update_front_end_msg(update_front_end_msg_t* update_front_end_msg) - - int slurm_update_front_end(update_front_end_msg_t* front_end_msg) - - int slurm_load_topo(topo_info_response_msg_t** topo_info_msg_pptr) + int slurm_load_topo_config(topo_config_response_msg_t** resp) void slurm_free_topo_info_msg(topo_info_response_msg_t* msg) - void slurm_print_topo_info_msg(FILE* out, topo_info_response_msg_t* topo_info_msg_ptr, char* node_list, int one_liner) + void slurm_free_topo_config_msg(topo_config_response_msg_t* msg) + + void slurm_free_topo_request_msg(topo_info_request_msg_t* msg) - int slurm_get_select_nodeinfo(dynamic_plugin_data_t* nodeinfo, select_nodedata_type data_type, node_states state, void* data) + void slurm_print_topo_info_msg(FILE* out, topo_info_response_msg_t* topo_info_msg_ptr, char* node_list, char* unit, int one_liner) void slurm_init_part_desc_msg(update_part_msg_t* update_part_msg) @@ -2813,8 +2801,6 @@ cdef extern from "slurm/slurm.h": void slurm_free_partition_info_msg(partition_info_msg_t* part_info_ptr) - void slurm_print_partition_info_msg(FILE* out, partition_info_msg_t* part_info_ptr, int one_liner) - void slurm_print_partition_info(FILE* out, partition_info_t* part_ptr, int one_liner) char* slurm_sprint_partition_info(partition_info_t* part_ptr, int one_liner) diff --git a/pyslurm/slurm/slurm_errno.h.pxi b/pyslurm/slurm/slurm_errno.h.pxi index bfe33ee0..96453d9f 100644 --- a/pyslurm/slurm/slurm_errno.h.pxi +++ b/pyslurm/slurm/slurm_errno.h.pxi @@ -9,7 +9,7 @@ # * C-Macros are listed with their appropriate uint type # * Any definitions that cannot be translated are not included in this file # -# Generated on 2024-12-04T13:40:11.641040 +# Generated on 2025-09-28T15:03:23.665186 # # The Original Copyright notice from slurm_errno.h has been included # below: @@ -258,6 +258,7 @@ cdef extern from "slurm/slurm_errno.h": ESLURM_RES_CORES_PER_GPU_NO ESLURM_MAX_POWERED_NODES ESLURM_REQUESTED_TOPO_CONFIG_UNAVAILABLE + ESLURM_PREEMPTION_REQUIRED ESPANK_ERROR ESPANK_BAD_ARG ESPANK_NOT_TASK @@ -269,6 +270,8 @@ cdef extern from "slurm/slurm_errno.h": ESPANK_NOT_EXECD ESPANK_NOT_AVAIL ESPANK_NOT_LOCAL + ESPANK_NODE_FAILURE + ESPANK_JOB_FAILURE ESLURMD_KILL_TASK_FAILED ESLURMD_KILL_JOB_ALREADY_COMPLETE ESLURMD_INVALID_ACCT_FREQ @@ -285,7 +288,7 @@ cdef extern from "slurm/slurm_errno.h": ESLURMD_EPILOG_FAILED ESLURMD_TOOMANYSTEPS ESLURMD_STEP_EXISTS - ESLURMD_JOB_NOTRUNNING + ESLURMD_STEP_NOTRUNNING ESLURMD_STEP_SUSPENDED ESLURMD_STEP_NOTSUSPENDED ESLURMD_INVALID_SOCKET_NAME_LEN @@ -293,6 +296,7 @@ cdef extern from "slurm/slurm_errno.h": ESLURMD_CPU_BIND_ERROR ESLURMD_CPU_LAYOUT_ERROR ESLURMD_TOO_MANY_RPCS + ESLURMD_STEPD_PROXY_FAILED ESLURM_PROTOCOL_INCOMPLETE_PACKET SLURM_PROTOCOL_SOCKET_IMPL_TIMEOUT SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT @@ -315,6 +319,7 @@ cdef extern from "slurm/slurm_errno.h": ESLURM_BAD_SQL ESLURM_NO_REMOVE_DEFAULT_QOS ESLURM_COORD_NO_INCREASE_JOB_LIMIT + ESLURM_NO_RPC_STATS ESLURM_FED_CLUSTER_MAX_CNT ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT ESLURM_INVALID_CLUSTER_FEATURE @@ -356,6 +361,8 @@ cdef extern from "slurm/slurm_errno.h": ESLURM_DATA_PARSING_DEPTH ESLURM_DATA_PARSER_INVALID_STATE ESLURM_CONTAINER_NOT_CONFIGURED + ESLURM_URL_UNKNOWN_SCHEME + ESLURM_URL_EMPTY ctypedef struct slurm_errtab_t: int xe_number diff --git a/pyslurm/slurm/slurmdb.h.pxi b/pyslurm/slurm/slurmdb.h.pxi index 9f2703f0..c10001e2 100644 --- a/pyslurm/slurm/slurmdb.h.pxi +++ b/pyslurm/slurm/slurmdb.h.pxi @@ -9,7 +9,7 @@ # * C-Macros are listed with their appropriate uint type # * Any definitions that cannot be translated are not included in this file # -# Generated on 2024-12-04T13:40:12.010546 +# Generated on 2025-09-28T15:03:24.516012 # # The Original Copyright notice from slurmdb.h has been included # below: @@ -49,23 +49,6 @@ cdef extern from "slurm/slurmdb.h": - uint32_t QOS_FLAG_BASE - uint32_t QOS_FLAG_NOTSET - uint32_t QOS_FLAG_ADD - uint32_t QOS_FLAG_REMOVE - uint8_t QOS_FLAG_PART_MIN_NODE - uint8_t QOS_FLAG_PART_MAX_NODE - uint8_t QOS_FLAG_PART_TIME_LIMIT - uint8_t QOS_FLAG_ENFORCE_USAGE_THRES - uint8_t QOS_FLAG_NO_RESERVE - uint8_t QOS_FLAG_REQ_RESV - uint8_t QOS_FLAG_DENY_LIMIT - uint8_t QOS_FLAG_OVER_PART_QOS - uint16_t QOS_FLAG_NO_DECAY - uint16_t QOS_FLAG_USAGE_FACTOR_SAFE - uint16_t QOS_FLAG_RELATIVE - uint16_t QOS_FLAG_RELATIVE_SET - uint16_t QOS_FLAG_PART_QOS uint8_t QOS_COND_FLAG_WITH_DELETED uint32_t SLURMDB_RES_FLAG_BASE uint32_t SLURMDB_RES_FLAG_NOTSET @@ -106,18 +89,6 @@ cdef extern from "slurm/slurmdb.h": uint32_t SLURMDB_FS_USE_PARENT uint16_t SLURMDB_CLASSIFIED_FLAG uint8_t SLURMDB_CLASS_BASE - uint8_t CLUSTER_FLAG_REGISTER - uint8_t CLUSTER_FLAG_A2 - uint8_t CLUSTER_FLAG_A3 - uint8_t CLUSTER_FLAG_A4 - uint8_t CLUSTER_FLAG_A5 - uint8_t CLUSTER_FLAG_A6 - uint8_t CLUSTER_FLAG_A7 - uint8_t CLUSTER_FLAG_MULTSD - uint16_t CLUSTER_FLAG_A9 - uint16_t CLUSTER_FLAG_FE - uint16_t CLUSTER_FLAG_FED - uint16_t CLUSTER_FLAG_EXT uint8_t ASSOC_COND_FLAG_WITH_DELETED uint8_t ASSOC_COND_FLAG_WITH_USAGE uint8_t ASSOC_COND_FLAG_ONLY_DEFS @@ -126,10 +97,14 @@ cdef extern from "slurm/slurmdb.h": uint8_t ASSOC_COND_FLAG_WOPI uint8_t ASSOC_COND_FLAG_WOPL uint8_t ASSOC_COND_FLAG_QOS_USAGE + uint16_t ASSOC_COND_FLAG_WITH_NG_USAGE uint8_t SLURMDB_EVENT_COND_OPEN uint8_t DB_CONN_FLAG_CLUSTER_DEL uint8_t DB_CONN_FLAG_ROLLBACK uint8_t DB_CONN_FLAG_FEDUPDATE + uint8_t COORD_SET_INDIRECT + uint8_t COORD_SET_DIRECT + uint8_t COORD_SET_BY_ACCT cdef extern from "slurm/slurmdb.h": @@ -200,11 +175,42 @@ cdef extern from "slurm/slurmdb.h": SLURMDB_ADD_TRES SLURMDB_UPDATE_FEDS + ctypedef enum slurmdb_qos_flags_t: + QOS_FLAG_NONE + QOS_FLAG_PART_MIN_NODE + QOS_FLAG_PART_MAX_NODE + QOS_FLAG_PART_TIME_LIMIT + QOS_FLAG_ENFORCE_USAGE_THRES + QOS_FLAG_NO_RESERVE + QOS_FLAG_REQ_RESV + QOS_FLAG_DENY_LIMIT + QOS_FLAG_OVER_PART_QOS + QOS_FLAG_NO_DECAY + QOS_FLAG_USAGE_FACTOR_SAFE + QOS_FLAG_RELATIVE + QOS_FLAG_RELATIVE_SET + QOS_FLAG_PART_QOS + QOS_FLAG_DELETED + QOS_FLAG_BASE + QOS_FLAG_NOTSET + QOS_FLAG_ADD + QOS_FLAG_REMOVE + QOS_FLAG_INVALID + cdef enum cluster_fed_states: CLUSTER_FED_STATE_NA CLUSTER_FED_STATE_ACTIVE CLUSTER_FED_STATE_INACTIVE + ctypedef enum slurmdb_cluster_flags_t: + CLUSTER_FLAG_NONE + CLUSTER_FLAG_REGISTER + CLUSTER_FLAG_DELETED + CLUSTER_FLAG_MULTSD + CLUSTER_FLAG_FED + CLUSTER_FLAG_EXT + CLUSTER_FLAG_INVALID + ctypedef enum slurmdb_assoc_flags_t: ASSOC_FLAG_NONE ASSOC_FLAG_DELETED @@ -213,6 +219,7 @@ cdef extern from "slurm/slurmdb.h": ASSOC_FLAG_USER_COORD_NO ASSOC_FLAG_BASE ASSOC_FLAG_USER_COORD + ASSOC_FLAG_BLOCK_ADD ASSOC_FLAG_INVALID ctypedef struct slurmdb_tres_rec_t: @@ -371,7 +378,6 @@ cdef extern from "slurm/slurmdb.h": uint32_t id uint16_t is_def slurmdb_assoc_usage_t* leaf_usage - uint32_t lft char* lineage uint32_t max_jobs uint32_t max_jobs_accrue @@ -391,7 +397,6 @@ cdef extern from "slurm/slurmdb.h": char* partition uint32_t priority list_t* qos_list - uint32_t rgt uint32_t shares_raw uint32_t uid slurmdb_assoc_usage_t* usage @@ -441,7 +446,7 @@ cdef extern from "slurm/slurmdb.h": uint16_t classification list_t* cluster_list list_t* federation_list - uint32_t flags + slurmdb_cluster_flags_t flags list_t* format_list list_t* rpc_version_list time_t usage_end @@ -470,7 +475,7 @@ cdef extern from "slurm/slurmdb.h": int* dim_size uint16_t id slurmdb_cluster_fed_t fed - uint32_t flags + slurmdb_cluster_flags_t flags pthread_mutex_t lock char* name char* nodes @@ -583,7 +588,6 @@ cdef extern from "slurm/slurmdb.h": uint32_t het_job_offset uint32_t jobid char* jobname - uint32_t lft char* lineage char* licenses char* mcs_label @@ -598,7 +602,9 @@ cdef extern from "slurm/slurmdb.h": uint16_t restart_cnt uint32_t resvid char* resv_name + char* resv_req char* script + uint16_t segment_size uint32_t show_full time_t start uint32_t state @@ -648,7 +654,7 @@ cdef extern from "slurm/slurmdb.h": time_t blocked_until char* description uint32_t id - uint32_t flags + slurmdb_qos_flags_t flags uint32_t grace_time uint32_t grp_jobs_accrue uint32_t grp_jobs @@ -725,6 +731,7 @@ cdef extern from "slurm/slurmdb.h": char* nodes char* node_inx time_t time_end + time_t time_force time_t time_start time_t time_start_prev char* tres_str @@ -733,6 +740,7 @@ cdef extern from "slurm/slurmdb.h": ctypedef struct slurmdb_step_rec_t: char* container + char* cwd uint32_t elapsed time_t end int32_t exitcode @@ -750,11 +758,15 @@ cdef extern from "slurm/slurmdb.h": slurmdb_stats_t stats slurm_step_id_t step_id char* stepname + char* std_err + char* std_in + char* std_out char* submit_line uint32_t suspended uint64_t sys_cpu_sec uint32_t sys_cpu_usec uint32_t task_dist + uint32_t timelimit uint64_t tot_cpu_sec uint32_t tot_cpu_usec char* tres_alloc_str @@ -910,6 +922,7 @@ cdef extern from "slurm/slurmdb.h": list_t* acct_list list_t* assoc_list char* name + char* partition list_t* tres_list uid_t uid @@ -1276,3 +1289,7 @@ cdef extern from "slurm/slurmdb.h": list_t* slurmdb_wckeys_modify(void* db_conn, slurmdb_wckey_cond_t* wckey_cond, slurmdb_wckey_rec_t* wckey) list_t* slurmdb_wckeys_remove(void* db_conn, slurmdb_wckey_cond_t* wckey_cond) + + char* slurmdb_expand_job_stdio_fields(char* path, slurmdb_job_rec_t* job) + + char* slurmdb_expand_step_stdio_fields(char* path, slurmdb_step_rec_t* step) From 11b8c20f97fe0c1b3b6565a7b1a661ec7f8b00fc Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:08:51 +0200 Subject: [PATCH 07/11] slurm_get_select_nodeinfo is removed --- pyslurm/slurm/extra.pxi | 1 - 1 file changed, 1 deletion(-) diff --git a/pyslurm/slurm/extra.pxi b/pyslurm/slurm/extra.pxi index e08651ed..49183cf6 100644 --- a/pyslurm/slurm/extra.pxi +++ b/pyslurm/slurm/extra.pxi @@ -232,7 +232,6 @@ cdef extern void slurm_free_update_step_msg(step_update_request_msg_t *msg) # Slurm Node functions # -cdef extern int slurm_get_select_nodeinfo(dynamic_plugin_data_t *nodeinfo, select_nodedata_type data_type, node_states state, void *data) cdef extern char *slurm_node_state_string_complete(uint32_t inx) cdef extern void slurm_free_update_node_msg(update_node_msg_t *msg) cdef extern void slurm_free_node_info_members(node_info_t *node) From a2570588735c3934a026d5988811316f244e3a68 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:37:04 +0200 Subject: [PATCH 08/11] remove some long deprecated classes/functions in deprecated.pyx All of these classes have better replacements --- pyslurm/deprecated.pyx | 1717 +++------------------------------------- 1 file changed, 99 insertions(+), 1618 deletions(-) diff --git a/pyslurm/deprecated.pyx b/pyslurm/deprecated.pyx index bbc1b84f..9236fac1 100644 --- a/pyslurm/deprecated.pyx +++ b/pyslurm/deprecated.pyx @@ -461,884 +461,6 @@ def get_private_data_list(data): preview = rest return result -cdef class config: - """Slurm Config Information.""" - - cdef: - slurm.slurm_conf_t *slurm_ctl_conf_ptr - slurm.slurm_conf_t *__Config_ptr - slurm.time_t Time - slurm.time_t __lastUpdate - dict __ConfigDict - - def __cinit__(self): - self.__Config_ptr = NULL - self.__lastUpdate = 0 - self.__ConfigDict = {} - self.__load() - - def __dealloc__(self): - self.__free() - - def lastUpdate(self): - """Get the time (epoch seconds) the retrieved data was updated. - - Returns: - (int): Epoch seconds - """ - return self._lastUpdate - - def ids(self): - """Return the config IDs from retrieved data. - - Returns: - (dict): Dictionary of config key IDs - """ - return self.__ConfigDict.keys() - - def find_id(self, char *keyID=''): - """Retrieve config ID data. - - Args: - keyID (str): Config key string to search - - Returns: - (dict): Dictionary of values for given config key - """ - return self.__ConfigDict.get(keyID, {}) - - cdef void __free(self): - """Free memory allocated by slurm_load_ctl_conf.""" - if self.__Config_ptr is not NULL: - slurm.slurm_free_ctl_conf(self.__Config_ptr) - self.__Config_ptr = NULL - self.__ConfigDict = {} - self.__lastUpdate = 0 - - def display_all(self): - """Print slurm control configuration information.""" - slurm.slurm_print_ctl_conf(slurm.stdout, self.__Config_ptr) - - cdef int __load(self) except? -1: - """Load the slurm control configuration information. - - Returns: - int: slurm error code - """ - cdef: - slurm.slurm_conf_t *slurm_ctl_conf_ptr = NULL - slurm.time_t Time = NULL - int apiError = 0 - int errCode = slurm.slurm_load_ctl_conf(Time, &slurm_ctl_conf_ptr) - - if errCode != 0: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - self.__Config_ptr = slurm_ctl_conf_ptr - return errCode - - def key_pairs(self): - """Return a dict of the slurm control data as key pairs. - - Returns: - (dict): Dictionary of slurm key-pair values - """ - cdef: - void *ret_list = NULL - slurm.list_t *config_list = NULL - slurm.list_itr_t *iters = NULL - - config_key_pair_t *keyPairs - - int listNum, i - dict keyDict = {} - - if self.__Config_ptr is not NULL: - - config_list = slurm.slurm_ctl_conf_2_key_pairs(self.__Config_ptr) - - listNum = slurm.slurm_list_count(config_list) - iters = slurm.slurm_list_iterator_create(config_list) - - for i in range(listNum): - - keyPairs = slurm.slurm_list_next(iters) - name = keyPairs.name - - if keyPairs.value is not NULL: - value = keyPairs.value - else: - value = None - - keyDict[name] = value - - slurm.slurm_list_iterator_destroy(iters) - - return keyDict - - def get(self): - """Return the slurm control configuration information. - - Returns: - (dict): Configuration data - """ - self.__load() - self.__get() - - return self.__ConfigDict - - cpdef dict __get(self): - """Get the slurm control configuration information.""" - cdef: - void *ret_list = NULL - slurm.list_t *config_list = NULL - slurm.list_itr_t *iters = NULL - char tmp_str[128] - - config_key_pair_t *keyPairs - int i = 0 - int listNum - dict Ctl_dict = {} - dict key_pairs = {} - - if self.__Config_ptr is not NULL: - - self.__lastUpdate = self.__Config_ptr.last_update - - Ctl_dict['accounting_storage_tres'] = stringOrNone(self.__Config_ptr.accounting_storage_tres, '') - Ctl_dict['accounting_storage_enforce'] = self.__Config_ptr.accounting_storage_enforce - Ctl_dict['accounting_storage_backup_host'] = stringOrNone(self.__Config_ptr.accounting_storage_backup_host, '') - Ctl_dict['accounting_storage_ext_host'] = stringOrNone(self.__Config_ptr.accounting_storage_ext_host, '') - Ctl_dict['accounting_storage_host'] = stringOrNone(self.__Config_ptr.accounting_storage_host, '') - Ctl_dict['accounting_storage_pass'] = stringOrNone(self.__Config_ptr.accounting_storage_pass, '') - Ctl_dict['accounting_storage_port'] = self.__Config_ptr.accounting_storage_port - Ctl_dict['accounting_storage_type'] = stringOrNone(self.__Config_ptr.accounting_storage_type, '') - Ctl_dict['accounting_storage_user'] = stringOrNone(self.__Config_ptr.accounting_storage_user, '') - Ctl_dict['acct_gather_energy_type'] = stringOrNone(self.__Config_ptr.acct_gather_energy_type, '') - Ctl_dict['acct_gather_profile_type'] = stringOrNone(self.__Config_ptr.acct_gather_profile_type, '') - Ctl_dict['acct_gather_interconnect_type'] = stringOrNone(self.__Config_ptr.acct_gather_interconnect_type, '') - Ctl_dict['acct_gather_filesystem_type'] = stringOrNone(self.__Config_ptr.acct_gather_filesystem_type, '') - Ctl_dict['acct_gather_node_freq'] = self.__Config_ptr.acct_gather_node_freq - Ctl_dict['auth_alt_types'] = stringOrNone(self.__Config_ptr.authalttypes, '') - Ctl_dict['authinfo'] = stringOrNone(self.__Config_ptr.authinfo, '') - Ctl_dict['authtype'] = stringOrNone(self.__Config_ptr.authtype, '') - Ctl_dict['batch_start_timeout'] = self.__Config_ptr.batch_start_timeout - Ctl_dict['bb_type'] = stringOrNone(self.__Config_ptr.bb_type, '') - Ctl_dict['bcast_exclude'] = stringOrNone(self.__Config_ptr.bcast_exclude, '') - Ctl_dict['bcast_parameters'] = stringOrNone(self.__Config_ptr.bcast_parameters, '') - Ctl_dict['boot_time'] = self.__Config_ptr.boot_time - Ctl_dict['cli_filter_plugins'] = stringOrNone(self.__Config_ptr.cli_filter_plugins, '') - Ctl_dict['cluster_name'] = stringOrNone(self.__Config_ptr.cluster_name, '') - Ctl_dict['comm_params'] = stringOrNone(self.__Config_ptr.comm_params, '') - Ctl_dict['complete_wait'] = self.__Config_ptr.complete_wait - Ctl_dict['conf_flags'] = self.__Config_ptr.conf_flags - Ctl_dict['cpu_freq_def'] = int32orNone(self.__Config_ptr.cpu_freq_def) - Ctl_dict['cpu_freq_govs'] = self.__Config_ptr.cpu_freq_govs - Ctl_dict['cred_type'] = stringOrNone(self.__Config_ptr.cred_type, '') - Ctl_dict['debug_flags'] = self.__Config_ptr.debug_flags - Ctl_dict['def_mem_per_cpu'] = self.__Config_ptr.def_mem_per_cpu - Ctl_dict['dependency_params'] = stringOrNone(self.__Config_ptr.dependency_params, '') - Ctl_dict['eio_timeout'] = self.__Config_ptr.eio_timeout - Ctl_dict['enforce_part_limits'] = bool(self.__Config_ptr.enforce_part_limits) - Ctl_dict['epilog'] = listOfStrings(self.__Config_ptr.epilog) - Ctl_dict['epilog_msg_time'] = self.__Config_ptr.epilog_msg_time - Ctl_dict['epilog_slurmctld'] = listOfStrings(self.__Config_ptr.epilog_slurmctld) - Ctl_dict['federation_parameters'] = stringOrNone(self.__Config_ptr.fed_params, '') - Ctl_dict['first_job_id'] = self.__Config_ptr.first_job_id - Ctl_dict['fs_dampening_factor'] = self.__Config_ptr.fs_dampening_factor - Ctl_dict['get_env_timeout'] = self.__Config_ptr.get_env_timeout - Ctl_dict['gpu_freq_def'] = stringOrNone(self.__Config_ptr.gpu_freq_def, '') - Ctl_dict['gres_plugins'] = listOrNone(self.__Config_ptr.gres_plugins, ',') - Ctl_dict['group_time'] = self.__Config_ptr.group_time - Ctl_dict['group_update_force'] = self.__Config_ptr.group_force - Ctl_dict['hash_val'] = self.__Config_ptr.hash_val - Ctl_dict['health_check_interval'] = self.__Config_ptr.health_check_interval - Ctl_dict['health_check_node_state'] = self.__Config_ptr.health_check_node_state - Ctl_dict['health_check_program'] = stringOrNone(self.__Config_ptr.health_check_program, '') - Ctl_dict['inactive_limit'] = self.__Config_ptr.inactive_limit - Ctl_dict['job_acct_gather_freq'] = stringOrNone(self.__Config_ptr.job_acct_gather_freq, '') - Ctl_dict['job_acct_gather_type'] = stringOrNone(self.__Config_ptr.job_acct_gather_type, '') - Ctl_dict['job_acct_gather_params'] = stringOrNone(self.__Config_ptr.job_acct_gather_params, '') - Ctl_dict['job_comp_host'] = stringOrNone(self.__Config_ptr.job_comp_host, '') - Ctl_dict['job_comp_loc'] = stringOrNone(self.__Config_ptr.job_comp_loc, '') - Ctl_dict['job_comp_params'] = stringOrNone(self.__Config_ptr.job_comp_params, '') - Ctl_dict['job_comp_pass'] = stringOrNone(self.__Config_ptr.job_comp_pass, '') - Ctl_dict['job_comp_port'] = self.__Config_ptr.job_comp_port - Ctl_dict['job_comp_type'] = stringOrNone(self.__Config_ptr.job_comp_type, '') - Ctl_dict['job_comp_user'] = stringOrNone(self.__Config_ptr.job_comp_user, '') - Ctl_dict['job_container_plugin'] = stringOrNone(self.__Config_ptr.job_container_plugin, '') - # TODO: wrap with job_defaults_str() - #Ctl_dict['job_defaults_list'] = stringOrNone(self.__Config_ptr.job_defaults_list, ',') - - Ctl_dict['job_file_append'] = bool(self.__Config_ptr.job_file_append) - Ctl_dict['job_requeue'] = bool(self.__Config_ptr.job_requeue) - Ctl_dict['job_submit_plugins'] = stringOrNone(self.__Config_ptr.job_submit_plugins, '') - Ctl_dict['keep_alive_time'] = int16orNone(self.__Config_ptr.keepalive_time) - Ctl_dict['kill_on_bad_exit'] = bool(self.__Config_ptr.kill_on_bad_exit) - Ctl_dict['kill_wait'] = self.__Config_ptr.kill_wait - Ctl_dict['licenses'] = __get_licenses(self.__Config_ptr.licenses) - Ctl_dict['log_fmt'] = self.__Config_ptr.log_fmt - Ctl_dict['mail_domain'] = stringOrNone(self.__Config_ptr.mail_domain, '') - Ctl_dict['mail_prog'] = stringOrNone(self.__Config_ptr.mail_prog, '') - Ctl_dict['max_array_sz'] = self.__Config_ptr.max_array_sz - Ctl_dict['max_dbd_msgs'] = self.__Config_ptr.max_dbd_msgs - Ctl_dict['max_job_cnt'] = self.__Config_ptr.max_job_cnt - Ctl_dict['max_job_id'] = self.__Config_ptr.max_job_id - Ctl_dict['max_mem_per_cpu'] = self.__Config_ptr.max_mem_per_cpu - Ctl_dict['max_step_cnt'] = self.__Config_ptr.max_step_cnt - Ctl_dict['max_tasks_per_node'] = self.__Config_ptr.max_tasks_per_node - Ctl_dict['min_job_age'] = self.__Config_ptr.min_job_age - Ctl_dict['mpi_default'] = stringOrNone(self.__Config_ptr.mpi_default, '') - Ctl_dict['mpi_params'] = stringOrNone(self.__Config_ptr.mpi_params, '') - Ctl_dict['msg_timeout'] = self.__Config_ptr.msg_timeout - Ctl_dict['next_job_id'] = self.__Config_ptr.next_job_id - Ctl_dict['node_prefix'] = stringOrNone(self.__Config_ptr.node_prefix, '') - Ctl_dict['over_time_limit'] = int16orNone(self.__Config_ptr.over_time_limit) - Ctl_dict['plugindir'] = stringOrNone(self.__Config_ptr.plugindir, '') - Ctl_dict['plugstack'] = stringOrNone(self.__Config_ptr.plugstack, '') - Ctl_dict['prep_params'] = stringOrNone(self.__Config_ptr.prep_params, '') - Ctl_dict['prep_plugins'] = stringOrNone(self.__Config_ptr.prep_plugins, '') - - config_get_preempt_mode = get_preempt_mode(self.__Config_ptr.preempt_mode) - Ctl_dict['preempt_mode'] = stringOrNone(config_get_preempt_mode, '') - - Ctl_dict['preempt_type'] = stringOrNone(self.__Config_ptr.preempt_type, '') - - if self.__Config_ptr.preempt_exempt_time == slurm.INFINITE: - Ctl_dict['preempt_exempt_time'] = "NONE" - else: - secs2time_str(self.__Config_ptr.preempt_exempt_time) - Ctl_dict['preempt_exempt_time'] = stringOrNone(tmp_str, '') - - Ctl_dict['priority_decay_hl'] = self.__Config_ptr.priority_decay_hl - Ctl_dict['priority_calc_period'] = self.__Config_ptr.priority_calc_period - Ctl_dict['priority_favor_small'] = self.__Config_ptr.priority_favor_small - Ctl_dict['priority_flags'] = self.__Config_ptr.priority_flags - Ctl_dict['priority_max_age'] = self.__Config_ptr.priority_max_age - Ctl_dict['priority_params'] = stringOrNone(self.__Config_ptr.priority_params, '') - Ctl_dict['priority_site_factor_params'] = stringOrNone(self.__Config_ptr.site_factor_params, '') - Ctl_dict['priority_site_factor_plugin'] = stringOrNone(self.__Config_ptr.site_factor_plugin, '') - Ctl_dict['priority_reset_period'] = self.__Config_ptr.priority_reset_period - Ctl_dict['priority_type'] = stringOrNone(self.__Config_ptr.priority_type, '') - Ctl_dict['priority_weight_age'] = self.__Config_ptr.priority_weight_age - Ctl_dict['priority_weight_assoc'] = self.__Config_ptr.priority_weight_assoc - Ctl_dict['priority_weight_fs'] = self.__Config_ptr.priority_weight_fs - Ctl_dict['priority_weight_js'] = self.__Config_ptr.priority_weight_js - Ctl_dict['priority_weight_part'] = self.__Config_ptr.priority_weight_part - Ctl_dict['priority_weight_qos'] = self.__Config_ptr.priority_weight_qos - Ctl_dict['proctrack_type'] = stringOrNone(self.__Config_ptr.proctrack_type, '') - Ctl_dict['private_data'] = self.__Config_ptr.private_data - Ctl_dict['private_data_list'] = get_private_data_list(self.__Config_ptr.private_data) - Ctl_dict['priority_weight_tres'] = stringOrNone(self.__Config_ptr.priority_weight_tres, '') - Ctl_dict['prolog'] = listOfStrings(self.__Config_ptr.prolog) - Ctl_dict['prolog_epilog_timeout'] = int16orNone(self.__Config_ptr.prolog_epilog_timeout) - Ctl_dict['prolog_slurmctld'] = listOfStrings(self.__Config_ptr.prolog_slurmctld) - Ctl_dict['propagate_prio_process'] = self.__Config_ptr.propagate_prio_process - Ctl_dict['prolog_flags'] = self.__Config_ptr.prolog_flags - Ctl_dict['propagate_rlimits'] = stringOrNone(self.__Config_ptr.propagate_rlimits, '') - Ctl_dict['propagate_rlimits_except'] = stringOrNone(self.__Config_ptr.propagate_rlimits_except, '') - Ctl_dict['reboot_program'] = stringOrNone(self.__Config_ptr.reboot_program, '') - Ctl_dict['reconfig_flags'] = self.__Config_ptr.reconfig_flags - Ctl_dict['resume_fail_program'] = stringOrNone(self.__Config_ptr.resume_fail_program, '') - Ctl_dict['requeue_exit'] = stringOrNone(self.__Config_ptr.requeue_exit, '') - Ctl_dict['requeue_exit_hold'] = stringOrNone(self.__Config_ptr.requeue_exit_hold, '') - Ctl_dict['resume_fail_program'] = stringOrNone(self.__Config_ptr.resume_fail_program, '') - Ctl_dict['resume_program'] = stringOrNone(self.__Config_ptr.resume_program, '') - Ctl_dict['resume_rate'] = self.__Config_ptr.resume_rate - Ctl_dict['resume_timeout'] = self.__Config_ptr.resume_timeout - Ctl_dict['resv_epilog'] = stringOrNone(self.__Config_ptr.resv_epilog, '') - Ctl_dict['resv_over_run'] = self.__Config_ptr.resv_over_run - Ctl_dict['resv_prolog'] = stringOrNone(self.__Config_ptr.resv_prolog, '') - Ctl_dict['ret2service'] = self.__Config_ptr.ret2service - Ctl_dict['sched_logfile'] = stringOrNone(self.__Config_ptr.sched_logfile, '') - Ctl_dict['sched_log_level'] = self.__Config_ptr.sched_log_level - Ctl_dict['sched_params'] = stringOrNone(self.__Config_ptr.sched_params, '') - Ctl_dict['sched_time_slice'] = self.__Config_ptr.sched_time_slice - Ctl_dict['schedtype'] = stringOrNone(self.__Config_ptr.schedtype, '') - Ctl_dict['scron_params'] = stringOrNone(self.__Config_ptr.scron_params, '') - Ctl_dict['select_type'] = stringOrNone(self.__Config_ptr.select_type, '') - Ctl_dict['select_type_param'] = self.__Config_ptr.select_type_param - Ctl_dict['slurm_conf'] = stringOrNone(self.__Config_ptr.slurm_conf, '') - Ctl_dict['slurm_user_id'] = self.__Config_ptr.slurm_user_id - Ctl_dict['slurm_user_name'] = stringOrNone(self.__Config_ptr.slurm_user_name, '') - Ctl_dict['slurmd_user_id'] = self.__Config_ptr.slurmd_user_id - Ctl_dict['slurmd_user_name'] = stringOrNone(self.__Config_ptr.slurmd_user_name, '') - Ctl_dict['slurmctld_addr'] = stringOrNone(self.__Config_ptr.slurmctld_addr, '') - Ctl_dict['slurmctld_debug'] = self.__Config_ptr.slurmctld_debug - # TODO: slurmctld_host - Ctl_dict['slurmctld_logfile'] = stringOrNone(self.__Config_ptr.slurmctld_logfile, '') - Ctl_dict['slurmctld_pidfile'] = stringOrNone(self.__Config_ptr.slurmctld_pidfile, '') - Ctl_dict['slurmctld_port'] = self.__Config_ptr.slurmctld_port - Ctl_dict['slurmctld_port_count'] = self.__Config_ptr.slurmctld_port_count - Ctl_dict['slurmctld_primary_off_prog'] = stringOrNone(self.__Config_ptr.slurmctld_primary_off_prog, '') - Ctl_dict['slurmctld_primary_on_prog'] = stringOrNone(self.__Config_ptr.slurmctld_primary_on_prog, '') - Ctl_dict['slurmctld_syslog_debug'] = self.__Config_ptr.slurmctld_syslog_debug - Ctl_dict['slurmctld_timeout'] = self.__Config_ptr.slurmctld_timeout - Ctl_dict['slurmd_debug'] = self.__Config_ptr.slurmd_debug - Ctl_dict['slurmd_logfile'] = stringOrNone(self.__Config_ptr.slurmd_logfile, '') - Ctl_dict['slurmd_parameters'] = stringOrNone(self.__Config_ptr.slurmd_params, '') - Ctl_dict['slurmd_pidfile'] = stringOrNone(self.__Config_ptr.slurmd_pidfile, '') - Ctl_dict['slurmd_port'] = self.__Config_ptr.slurmd_port - Ctl_dict['slurmd_spooldir'] = stringOrNone(self.__Config_ptr.slurmd_spooldir, '') - Ctl_dict['slurmd_syslog_debug'] = self.__Config_ptr.slurmd_syslog_debug - Ctl_dict['slurmd_timeout'] = self.__Config_ptr.slurmd_timeout - Ctl_dict['srun_epilog'] = stringOrNone(self.__Config_ptr.srun_epilog, '') - - a = [0,0] - if self.__Config_ptr.srun_port_range != NULL: - a[0] = self.__Config_ptr.srun_port_range[0] - a[1] = self.__Config_ptr.srun_port_range[1] - Ctl_dict['srun_port_range'] = tuple(a) - - Ctl_dict['srun_prolog'] = stringOrNone(self.__Config_ptr.srun_prolog, '') - Ctl_dict['state_save_location'] = stringOrNone(self.__Config_ptr.state_save_location, '') - Ctl_dict['suspend_exc_nodes'] = listOrNone(self.__Config_ptr.suspend_exc_nodes, ',') - Ctl_dict['suspend_exc_parts'] = listOrNone(self.__Config_ptr.suspend_exc_parts, ',') - Ctl_dict['suspend_program'] = stringOrNone(self.__Config_ptr.suspend_program, '') - Ctl_dict['suspend_rate'] = self.__Config_ptr.suspend_rate - Ctl_dict['suspend_time'] = self.__Config_ptr.suspend_time - Ctl_dict['suspend_timeout'] = self.__Config_ptr.suspend_timeout - Ctl_dict['switch_type'] = stringOrNone(self.__Config_ptr.switch_type, '') - Ctl_dict['switch_param'] = stringOrNone(self.__Config_ptr.switch_param, '') - Ctl_dict['task_epilog'] = stringOrNone(self.__Config_ptr.task_epilog, '') - Ctl_dict['task_plugin'] = stringOrNone(self.__Config_ptr.task_plugin, '') - Ctl_dict['task_plugin_param'] = self.__Config_ptr.task_plugin_param - Ctl_dict['task_prolog'] = stringOrNone(self.__Config_ptr.task_prolog, '') - Ctl_dict['tcp_timeout'] = self.__Config_ptr.tcp_timeout - Ctl_dict['tmp_fs'] = stringOrNone(self.__Config_ptr.tmp_fs, '') - Ctl_dict['topology_param'] = stringOrNone(self.__Config_ptr.topology_param, '') - Ctl_dict['topology_plugin'] = stringOrNone(self.__Config_ptr.topology_plugin, '') - Ctl_dict['tree_width'] = self.__Config_ptr.tree_width - Ctl_dict['unkillable_program'] = stringOrNone(self.__Config_ptr.unkillable_program, '') - Ctl_dict['unkillable_timeout'] = self.__Config_ptr.unkillable_timeout - Ctl_dict['version'] = stringOrNone(self.__Config_ptr.version, '') - Ctl_dict['vsize_factor'] = self.__Config_ptr.vsize_factor - Ctl_dict['wait_time'] = self.__Config_ptr.wait_time - Ctl_dict['x11_params'] = stringOrNone(self.__Config_ptr.x11_params, '') - - # - # Get key_pairs from Opaque data structure - # - -# config_list = self.__Config_ptr.select_conf_key_pairs -# if config_list is not NULL: -# listNum = slurm.slurm_list_count(config_list) -# iters = slurm.slurm_list_iterator_create(config_list) -# for i in range(listNum): -# keyPairs = slurm.slurm_list_next(iters) -# name = keyPairs.name -# if keyPairs.value is not NULL: -# value = keyPairs.value -# else: -# value = None -# key_pairs[name] = value -# slurm.slurm_list_iterator_destroy(iters) -# Ctl_dict['key_pairs'] = key_pairs - - self.__ConfigDict = Ctl_dict - - -# -# Partition Class -# - - -cdef class partition: - """Slurm Partition Information.""" - - cdef: - slurm.partition_info_msg_t *_Partition_ptr - slurm.time_t _lastUpdate - uint16_t _ShowFlags - dict _PartDict - - def __cinit__(self): - self._Partition_ptr = NULL - self._ShowFlags = slurm.SHOW_ALL - self._lastUpdate = NULL - - def __dealloc__(self): - pass - - def lastUpdate(self): - """Return time (epoch seconds) the partition data was updated. - - Returns: - (int): Epoch seconds - """ - return self._lastUpdate - - def ids(self): - """Return the partition IDs from retrieved data. - - Returns: - (dict): Dictionary of partition IDs - """ - cdef: - int rc - int apiError - uint32_t i - - rc = slurm.slurm_load_partitions( NULL, &self._Partition_ptr, - slurm.SHOW_ALL) - - if rc == slurm.SLURM_SUCCESS: - self._lastUpdate = self._Partition_ptr.last_update - all_partitions = [] - - for record in self._Partition_ptr.partition_array[:self._Partition_ptr.record_count]: - all_partitions.append(stringOrNone(record.name, '')) - - slurm.slurm_free_partition_info_msg(self._Partition_ptr) - self._Partition_ptr = NULL - return all_partitions - else: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - def find_id(self, partID): - """Get partition information for a given partition. - - Args: - partID (str): Partition key string to search - - Returns: - (dict): Dictionary of values for given partition - """ - return self.get().get(partID) - - def find(self, name='', val=''): - """Search for a property and associated value in the retrieved partition data. - - Args: - name (str): key string to search - val (str): value string to match - - Returns: - (list): List of IDs that match - """ - cdef: - list retList = [] - dict _partition_dict = {} - - _partition_dict = self.get() - - if val != '': - for key, value in self._partition_dict.items(): - if _partition_dict[key][name] == val: - retList.append(key) - return retList - - def print_info_msg(self, int oneLiner=0): - """Display partition information from previous load partition method. - - Args: - oneLiner (int, optional): Display on one line. - """ - cdef: - int rc - int apiError - - rc = slurm.slurm_load_partitions( NULL, &self._Partition_ptr, - slurm.SHOW_ALL) - - if rc == slurm.SLURM_SUCCESS: - slurm.slurm_print_partition_info_msg(slurm.stdout, - self._Partition_ptr, - oneLiner) - self._lastUpdate = self._Partition_ptr.last_update - slurm.slurm_free_partition_info_msg(self._Partition_ptr) - self._Partition_ptr = NULL - else: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - def delete(self, PartID): - """Delete a give slurm partition. - - Args: - PartID (str): Name of slurm partition - - Returns: - (int): 0 for success else set the slurm error code as - appropriately. - """ - cdef: - slurm.delete_part_msg_t part_msg - int apiError - int errCode - - b_partid = PartID.encode("UTF-8", "replace") - part_msg.name = b_partid - - errCode = slurm.slurm_delete_partition(&part_msg) - - if errCode != slurm.SLURM_SUCCESS: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - return errCode - - def get(self): - """Get all slurm partition information - - Returns: - (dict): Dictionary of dictionaries whose key is the partition name. - """ - cdef: - int rc - int apiError - uint16_t preempt_mode - uint32_t i - slurm.partition_info_t *record - - rc = slurm.slurm_load_partitions( NULL, &self._Partition_ptr, - slurm.SHOW_ALL) - - if rc == slurm.SLURM_SUCCESS: - self._PartDict = {} - self._lastUpdate = self._Partition_ptr.last_update - - for record in self._Partition_ptr.partition_array[:self._Partition_ptr.record_count]: - Part_dict = {} - name = stringOrNone(record.name, '') - - if record.allow_accounts or not record.deny_accounts: - if record.allow_accounts == NULL or \ - record.allow_accounts[0] == "\0".encode("UTF-8"): - Part_dict['allow_accounts'] = "ALL" - else: - Part_dict['allow_accounts'] = listOrNone( - record.allow_accounts, ',') - - Part_dict['deny_accounts'] = None - else: - Part_dict['allow_accounts'] = None - Part_dict['deny_accounts'] = listOrNone( - record.deny_accounts, ',') - - if record.allow_alloc_nodes == NULL: - Part_dict['allow_alloc_nodes'] = "ALL" - else: - Part_dict['allow_alloc_nodes'] = listOrNone( - record.allow_alloc_nodes, ',') - - if record.allow_groups == NULL or \ - record.allow_groups[0] == "\0".encode("UTF-8"): - Part_dict['allow_groups'] = "ALL" - else: - Part_dict['allow_groups'] = listOrNone( - record.allow_groups, ',') - - if record.allow_qos or not record.deny_qos: - if record.allow_qos == NULL or \ - record.allow_qos[0] == "\0".encode("UTF-8"): - Part_dict['allow_qos'] = "ALL" - else: - Part_dict['allow_qos'] = listOrNone( - record.allow_qos, ',') - Part_dict['deny_qos'] = None - else: - Part_dict['allow_qos'] = None - Part_dict['deny_qos'] = listOrNone(record.allow_qos, ',') - - if record.alternate != NULL: - Part_dict['alternate'] = stringOrNone(record.alternate, '') - else: - Part_dict['alternate'] = None - - Part_dict['billing_weights_str'] = stringOrNone( - record.billing_weights_str, '') - - #TODO: cpu_bind - Part_dict['cr_type'] = record.cr_type - - if record.def_mem_per_cpu & slurm.MEM_PER_CPU: - if record.def_mem_per_cpu == slurm.MEM_PER_CPU: - Part_dict['def_mem_per_cpu'] = "UNLIMITED" - Part_dict['def_mem_per_node'] = None - else: - Part_dict['def_mem_per_cpu'] = record.def_mem_per_cpu & (~slurm.MEM_PER_CPU) - Part_dict['def_mem_per_node'] = None - elif record.def_mem_per_cpu == 0: - Part_dict['def_mem_per_cpu'] = None - Part_dict['def_mem_per_node'] = "UNLIMITED" - else: - Part_dict['def_mem_per_cpu'] = None - Part_dict['def_mem_per_node'] = record.def_mem_per_cpu - - if record.default_time == slurm.INFINITE: - Part_dict['default_time'] = "UNLIMITED" - Part_dict['default_time_str'] = "UNLIMITED" - elif record.default_time == slurm.NO_VAL: - Part_dict['default_time'] = "NONE" - Part_dict['default_time_str'] = "NONE" - else: - Part_dict['default_time'] = record.default_time * 60 - Part_dict['default_time_str'] = secs2time_str( - record.default_time * 60) - - Part_dict['flags'] = get_partition_mode(record.flags, - record.max_share) - Part_dict['grace_time'] = record.grace_time - - # TODO: job_defaults - if record.max_cpus_per_node == slurm.INFINITE: - Part_dict['max_cpus_per_node'] = "UNLIMITED" - else: - Part_dict['max_cpus_per_node'] = record.max_cpus_per_node - - if record.max_mem_per_cpu & slurm.MEM_PER_CPU: - if record.max_mem_per_cpu == slurm.MEM_PER_CPU: - Part_dict['max_mem_per_cpu'] = "UNLIMITED" - Part_dict['max_mem_per_node'] = None - else: - Part_dict['max_mem_per_cpu'] = record.max_mem_per_cpu & (~slurm.MEM_PER_CPU) - Part_dict['max_mem_per_node'] = None - elif record.max_mem_per_cpu == 0: - Part_dict['max_mem_per_cpu'] = None - Part_dict['max_mem_per_node'] = "UNLIMITED" - else: - Part_dict['max_mem_per_cpu'] = None - Part_dict['max_mem_per_node'] = record.max_mem_per_cpu - - if record.max_nodes == slurm.INFINITE: - Part_dict['max_nodes'] = "UNLIMITED" - else: - Part_dict['max_nodes'] = record.max_nodes - - Part_dict['max_share'] = record.max_share - - if record.max_time == slurm.INFINITE: - Part_dict['max_time'] = "UNLIMITED" - Part_dict['max_time_str'] = "UNLIMITED" - else: - Part_dict['max_time'] = record.max_time * 60 - Part_dict['max_time_str'] = secs2time_str(record.max_time * 60) - - Part_dict['min_nodes'] = record.min_nodes - Part_dict['name'] = stringOrNone(record.name, '') - Part_dict['nodes'] = stringOrNone(record.nodes, '') - - if record.over_time_limit == slurm.NO_VAL16: - Part_dict['over_time_limit'] = "NONE" - elif record.over_time_limit == slurm.INFINITE16: - Part_dict['over_time_limit'] = "UNLIMITED" - else: - Part_dict['over_time_limit'] = record.over_time_limit - - # FIXME - # They removed the slurm_get_preempt_mode() function - # It must now be read from the slurm config - # https://github.com/SchedMD/slurm/commit/bd76db3cd28f418f31de877f3c39a439b09289f7 - - preempt_mode = record.preempt_mode - if preempt_mode == slurm.NO_VAL16: - Part_dict['preempt_mode'] = stringOrNone( - slurm.slurm_preempt_mode_string(preempt_mode), '' - ) - Part_dict['priority_job_factor'] = record.priority_job_factor - Part_dict['priority_tier'] = record.priority_tier - Part_dict['qos_char'] = stringOrNone(record.qos_char, '') - Part_dict['resume_timeout'] = record.resume_timeout - Part_dict['state'] = get_partition_state(record.state_up) - Part_dict['suspend_time'] = record.suspend_time - Part_dict['suspend_timout'] = record.suspend_timeout - Part_dict['total_cpus'] = record.total_cpus - Part_dict['total_nodes'] = record.total_nodes - Part_dict['tres_fmt_str'] = stringOrNone(record.tres_fmt_str, '') - - self._PartDict["%s" % name] = Part_dict - slurm.slurm_free_partition_info_msg(self._Partition_ptr) - self._Partition_ptr = NULL - return self._PartDict - else: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - - def update(self, dict Partition_dict): - """Update a slurm partition. - - Args: - Partition_dict (dict): A populated partition dictionary, an empty - one is created by create_partition_dict - - Returns: - (int): 0 for success, -1 for error, and the slurm error code is set - appropriately. - """ - cdef int errCode = slurm_update_partition(Partition_dict) - return errCode - - def create(self, dict Partition_dict): - """Create a slurm partition. - - Args: - Partition_dict (dict): A populated partition dictionary, an empty - one can be created by create_partition_dict - - Returns: - (int): 0 for success or -1 for error, and the slurm error code is - set appropriately. - """ - cdef int errCode = slurm_create_partition(Partition_dict) - return errCode - - -def create_partition_dict(): - """Returns a dictionary that can be populated by the user - and used for the update_partition and create_partition calls. - - Returns: - (dict): Empty reservation dictionary - """ - return { - 'Alternate': None, - 'Name': None, - 'MaxTime': 0, - 'DefaultTime': 0, - 'MaxNodes': 0, - 'MinNodes': 0, - 'Default': 0, - 'Hidden': 0, - 'RootOnly': 0, - 'Shared': 0, - 'Priority': 0, - 'State': 0, - 'Nodes': None, - 'AllowGroups': None, - 'AllocNodes': None - } - - -def slurm_create_partition(dict partition_dict): - """Create a slurm partition. - - Args: - partition_dict (dict): A populated partition dictionary, an empty one - can be created by create_partition_dict - - Returns: - (int): 0 for success or -1 for error, and the slurm error code is set - appropriately. - """ - cdef: - slurm.update_part_msg_t part_msg_ptr - int errCode - - slurm.slurm_init_part_desc_msg(&part_msg_ptr) - - b_name = partition_dict['Name'].encode("UTF-8", "replace") - part_msg_ptr.name = b_name - - if partition_dict.get('DefaultTime'): - part_msg_ptr.default_time = partition_dict['DefaultTime'] - - if partition_dict.get('MaxNodes'): - part_msg_ptr.max_nodes = partition_dict['MaxNodes'] - - if partition_dict.get('MinNodes'): - part_msg_ptr.min_nodes = partition_dict['MinNodes'] - - errCode = slurm.slurm_create_partition(&part_msg_ptr) - return errCode - - -def slurm_update_partition(dict partition_dict): - """Update a slurm partition. - - Args: - partition_dict (dict): A populated partition dictionary, an empty one - is created by create_partition_dict - - Returns: - (int): 0 for success, -1 for error, and the slurm error code is set - appropriately. - """ - cdef: - slurm.update_part_msg_t part_msg_ptr - unsigned int uint32_value - unsigned int time_value - int int_value = 0 - int errCode = 0 - - slurm.slurm_init_part_desc_msg(&part_msg_ptr) - - if partition_dict.get('Name'): - b_name = partition_dict['Name'].encode("UTF-8", "replace") - part_msg_ptr.name = b_name - - if partition_dict.get('Alternate'): - b_alternate = partition_dict['Alternate'].encode("UTF-8", "replace") - part_msg_ptr.alternate = b_alternate - - if partition_dict.get('MaxTime'): - part_msg_ptr.max_time = partition_dict['MaxTime'] - - if partition_dict.get('DefaultTime'): - part_msg_ptr.default_time = partition_dict['DefaultTime'] - - if partition_dict.get('MaxNodes'): - part_msg_ptr.max_nodes = partition_dict['MaxNodes'] - - if partition_dict.get('MinNodes'): - part_msg_ptr.min_nodes = partition_dict['MinNodes'] - - state = partition_dict.get('State') - if state: - if state == 'DOWN': - part_msg_ptr.state_up = PARTITION_DOWN - elif state == 'UP': - part_msg_ptr.state_up = PARTITION_UP - elif state == 'DRAIN': - part_msg_ptr.state_up = PARTITION_DRAIN - else: - errCode = -1 - - if partition_dict.get('Nodes'): - b_nodes = partition_dict['Nodes'].encode("UTF-8") - part_msg_ptr.nodes = b_nodes - - if partition_dict.get('AllowGroups'): - b_allow_groups = partition_dict['AllowGroups'].encode("UTF-8") - part_msg_ptr.allow_groups = b_allow_groups - - if partition_dict.get('AllocNodes'): - b_allow_alloc_nodes = partition_dict['AllocNodes'].encode("UTF-8") - part_msg_ptr.allow_alloc_nodes = b_allow_alloc_nodes - - errCode = slurm.slurm_update_partition(&part_msg_ptr) - return errCode - - -def slurm_delete_partition(PartID): - """Delete a slurm partition. - - Args: - PartID (str): Name of slurm partition - - Returns: - (int): 0 for success else set the slurm error code as appropriately. - """ - cdef: - slurm.delete_part_msg_t part_msg - int apiError - int errCode - - b_partid = PartID.encode("UTF-8", "replace") - part_msg.name = b_partid - errCode = slurm.slurm_delete_partition(&part_msg) - - if errCode != slurm.SLURM_SUCCESS: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - return errCode - - -# # Slurm Ping/Reconfig/Shutdown functions # @@ -2951,560 +2073,144 @@ cdef class job: return exit_status -def slurm_pid2jobid(uint32_t JobPID=0): - """Get the slurm job id from a process id. - - Args: - JobPID (int): Job process id - - Returns: - int: 0 for success or a slurm error code - """ - cdef: - uint32_t JobID = 0 - int apiError = 0 - int errCode = slurm.slurm_pid2jobid(JobPID, &JobID) - - if errCode != 0: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - return errCode, JobID - - -cdef secs2time_str(uint32_t time): - """Convert seconds to Slurm string format. - - This method converts time in seconds (86400) to Slurm's string format - (1-00:00:00). - - Args: - time (int): Time in seconds - - Returns: - str: Slurm time string. - """ - cdef: - char *time_str - double days, hours, minutes, seconds - - if time == slurm.INFINITE: - time_str = "UNLIMITED" - else: - seconds = time % 60 - minutes = (time / 60) % 60 - hours = (time / 3600) % 24 - days = time / 86400 - - if days < 0 or hours < 0 or minutes < 0 or seconds < 0: - time_str = "INVALID" - elif days: - return "%ld-%2.2ld:%2.2ld:%2.2ld" % (days, hours, - minutes, seconds) - else: - return "%2.2ld:%2.2ld:%2.2ld" % (hours, minutes, seconds) - - -cdef mins2time_str(uint32_t time): - """Convert minutes to Slurm string format. - - This method converts time in minutes (14400) to Slurm's string format - (10-00:00:00). - - Args: - time (int): Time in minutes - - Returns: - str: Slurm time string. - """ - cdef: - double days, hours, minutes, seconds - - if time == slurm.INFINITE: - return "UNLIMITED" - else: - seconds = 0 - minutes = time % 60 - hours = (time / 60) % 24 - days = time / 1440 - - if days < 0 or hours < 0 or minutes < 0 or seconds < 0: - time_str = "INVALID" - elif days: - return "%ld-%2.2ld:%2.2ld:%2.2ld" % (days, hours, - minutes, seconds) - else: - return "%2.2ld:%2.2ld:%2.2ld" % (hours, minutes, seconds) - - -# -# Slurm Error Class -# - - -class SlurmError(Exception): - - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(slurm.slurm_strerror(self.value)) - - -# -# Slurm Error Functions -# - - -def slurm_get_errno(): - """Return the slurm error as set by a slurm API call. - - Returns: - (int): Current slurm error number - """ - return errno - - -def slurm_strerror(int Errno=0): - """Return slurm error message represented by a given slurm error number. - - Args: - Errno (int): slurm error number. - - Returns: - (str): slurm error string - """ - cdef char* errMsg = slurm.slurm_strerror(Errno) - - return "%s" % errMsg - - -def slurm_perror(char* Msg=''): - """Print to standard error the supplied header. - - Header is followed by a colon, followed by a text description of the last - Slurm error code generated. - - Args: - Msg (str): slurm program error String - """ - slurm.slurm_perror(Msg) - - -# -# -# Slurm Node Read/Print/Update Class -# - - -cdef class node: - """Access/Modify/Update Slurm Node Information.""" - - cdef: - slurm.node_info_msg_t *_Node_ptr - slurm.partition_info_msg_t *_Part_ptr - uint16_t _ShowFlags - dict _NodeDict - slurm.time_t _lastUpdate - - def __cinit__(self): - self._Node_ptr = NULL - self._Part_ptr = NULL - self._ShowFlags = slurm.SHOW_ALL | slurm.SHOW_DETAIL - self._lastUpdate = 0 - - def __dealloc__(self): - pass - - def lastUpdate(self): - """Return last time (epoch seconds) the node data was updated. - - Returns: - (int): Epoch seconds - """ - return self._lastUpdate - - def ids(self): - """Return the node IDs from retrieved data. - - Returns: - (dict): Dictionary of node IDs - """ - cdef: - int rc - int apiError - uint32_t i - list all_nodes - - rc = slurm.slurm_load_node( NULL, &self._Node_ptr, self._ShowFlags) - - if rc == slurm.SLURM_SUCCESS: - all_nodes = [] - for record in self._Node_ptr.node_array[:self._Node_ptr.record_count]: - all_nodes.append(stringOrNone(record.name, '')) - slurm.slurm_free_node_info_msg(self._Node_ptr) - self._Node_ptr = NULL - return all_nodes - else: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - def find_id(self, nodeID): - """Get node information for a given node. - - Args: - nodeID (str): Node key string to search - - Returns: - (dict): Dictionary of values for given node - """ - return list(self.get_node(nodeID).values())[0] - - def get(self): - """Get all slurm node information. - - Returns: - (dict): Dictionary of dictionaries whose key is the node name. - """ - return self.get_node(None) - - def parse_gres(self, gres_str): - if gres_str: - return re.split(r',(?![^(]*\))', gres_str) - - def get_node(self, nodeID): - """Get single slurm node information. - - Args: - nodeID (str): Node key string to search. Default NULL. - - Returns: - (dict): Dictionary of node info data. - """ - cdef: - int rc - int rc_part - int apiError - int total_used - char *cloud_str - char *comp_str - char *drain_str - char *power_str - uint16_t err_cpus - uint16_t alloc_cpus - uint32_t i - uint32_t j - uint64_t alloc_mem - uint32_t node_state - slurm.node_info_t *record - dict Host_dict - char time_str[32] - char tmp_str[128] - int last_inx = 0 - slurm.slurm_conf_t *slurm_ctl_conf_ptr = NULL - - rc = slurm.slurm_load_node(NULL, &self._Node_ptr, self._ShowFlags) - - if rc != slurm.SLURM_SUCCESS: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - if slurm.slurm_load_ctl_conf(NULL, &slurm_ctl_conf_ptr) != slurm.SLURM_SUCCESS: - raise ValueError("Cannot load slurmctld conf file") - - rc_part = slurm.slurm_load_partitions(NULL, &self._Part_ptr, slurm.SHOW_ALL) - - if rc_part != slurm.SLURM_SUCCESS: - self._Part_ptr = NULL - slurm.slurm_perror("slurm_load_partitions error") - - slurm.slurm_populate_node_partitions(self._Node_ptr, self._Part_ptr) +def slurm_pid2jobid(uint32_t JobPID=0): + """Get the slurm job id from a process id. - self._lastUpdate = self._Node_ptr.last_update - self._NodeDict = {} + Args: + JobPID (int): Job process id - for j in range(self._Node_ptr.record_count): - if nodeID: - i = (j + last_inx) % self._Node_ptr.record_count - if self._Node_ptr.node_array[i].name == NULL or ( - nodeID.encode("UTF-8") != self._Node_ptr.node_array[i].name): - continue - elif self._Node_ptr.node_array[j].name == NULL: - continue - else: - i = j - - record = &self._Node_ptr.node_array[i] - - Host_dict = {} - cloud_str = "" - comp_str = "" - drain_str = "" - power_str = "" - err_cpus = 0 - alloc_cpus = 0 - - if record.name is NULL: - continue - - total_used = record.cpus - - Host_dict['arch'] = stringOrNone(record.arch, '') - Host_dict['boards'] = record.boards - Host_dict['boot_time'] = record.boot_time - Host_dict['cores'] = record.cores - Host_dict['core_spec_cnt'] = record.core_spec_cnt - Host_dict['cores_per_socket'] = record.cores - # TODO: cpu_alloc, cpu_tot - Host_dict['cpus'] = record.cpus - - # FIXME - #if record.cpu_bind: - # slurm.slurm_sprint_cpu_bind_type(tmp_str, record.cpu_bind) - # Host_dict['cpu_bind'] = stringOrNone(tmp_str, '') - - Host_dict['cpu_load'] = int32orNone(record.cpu_load) - Host_dict['cpu_spec_list'] = listOrNone(record.cpu_spec_list, '') - Host_dict['extra'] = stringOrNone(record.extra, '') - Host_dict['features'] = listOrNone(record.features, '') - Host_dict['features_active'] = listOrNone(record.features_act, '') - Host_dict['free_mem'] = int64orNone(record.free_mem) - Host_dict['gres'] = listOrNone(record.gres, ',') - Host_dict['gres_drain'] = listOrNone(record.gres_drain, '') - Host_dict['gres_used'] = self.parse_gres( - stringOrNone(record.gres_used, '') - ) - Host_dict['last_busy'] = record.last_busy - Host_dict['mcs_label'] = stringOrNone(record.mcs_label, '') - Host_dict['mem_spec_limit'] = record.mem_spec_limit - Host_dict['name'] = stringOrNone(record.name, '') - - # TODO: next_state - Host_dict['node_addr'] = stringOrNone(record.node_addr, '') - Host_dict['node_hostname'] = stringOrNone(record.node_hostname, '') - Host_dict['os'] = stringOrNone(record.os, '') - - if record.owner == slurm.NO_VAL: - Host_dict['owner'] = None - else: - Host_dict['owner'] = record.owner - - Host_dict['partitions'] = listOrNone(record.partitions, ',') - Host_dict['real_memory'] = record.real_memory - Host_dict['slurmd_start_time'] = record.slurmd_start_time - Host_dict['sockets'] = record.sockets - Host_dict['threads'] = record.threads - Host_dict['tmp_disk'] = record.tmp_disk - Host_dict['weight'] = record.weight - Host_dict['tres_fmt_str'] = stringOrNone(record.tres_fmt_str, '') - Host_dict['version'] = stringOrNone(record.version, '') - - Host_dict['reason'] = stringOrNone(record.reason, '') - if record.reason_time == 0: - Host_dict['reason_time'] = None - else: - Host_dict['reason_time'] = record.reason_time + Returns: + int: 0 for success or a slurm error code + """ + cdef: + uint32_t JobID = 0 + int apiError = 0 + int errCode = slurm.slurm_pid2jobid(JobPID, &JobID) - if record.reason_uid == slurm.NO_VAL: - Host_dict['reason_uid'] = None - else: - Host_dict['reason_uid'] = record.reason_uid + if errCode != 0: + apiError = slurm_get_errno() + raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - # Power Management - Host_dict['power_mgmt'] = {} - Host_dict['power_mgmt']["cap_watts"] = None + return errCode, JobID - # Energy statistics - Host_dict['energy'] = {} - if (not record.energy or record.energy.current_watts == slurm.NO_VAL): - Host_dict['energy']['current_watts'] = 0 - Host_dict['energy']['ave_watts'] = 0 - else: - Host_dict['energy']['current_watts'] = record.energy.current_watts - Host_dict['energy']['ave_watts'] = int(record.energy.ave_watts) - - Host_dict['energy']['previous_consumed_energy'] = int(record.energy.previous_consumed_energy) - - node_state = record.node_state - if (node_state & NODE_STATE_CLOUD): - node_state &= (~NODE_STATE_CLOUD) - cloud_str = "+CLOUD" - - if (node_state & NODE_STATE_COMPLETING): - node_state &= (~NODE_STATE_COMPLETING) - comp_str = "+COMPLETING" - - if (node_state & NODE_STATE_DRAIN): - node_state &= (~NODE_STATE_DRAIN) - drain_str = "+DRAIN" - - if (node_state & NODE_STATE_FAIL): - node_state &= (~NODE_STATE_FAIL) - drain_str = "+FAIL" - - if (node_state & NODE_STATE_POWERED_DOWN): - node_state &= (~NODE_STATE_POWERED_DOWN) - power_str = "+POWER" - - if (node_state & NODE_STATE_POWERING_DOWN): - node_state &= (~NODE_STATE_POWERING_DOWN) - power_str = "+POWERING_DOWN" - - slurm.slurm_get_select_nodeinfo(record.select_nodeinfo, - SELECT_NODEDATA_SUBCNT, - NODE_STATE_ALLOCATED, - &alloc_cpus) - - Host_dict['alloc_cpus'] = alloc_cpus - total_used -= alloc_cpus - - slurm.slurm_get_select_nodeinfo(record.select_nodeinfo, - SELECT_NODEDATA_SUBCNT, - NODE_STATE_ERROR, &err_cpus) - - Host_dict['err_cpus'] = err_cpus - total_used -= err_cpus - - if (alloc_cpus and err_cpus) or (total_used and - (total_used != record.cpus)): - node_state &= NODE_STATE_FLAGS - node_state |= NODE_STATE_MIXED - - Host_dict['state'] = ( - stringOrNone(slurm.slurm_node_state_string(node_state), '') + - stringOrNone(cloud_str, '') + - stringOrNone(comp_str, '') + - stringOrNone(drain_str, '') + - stringOrNone(power_str, '') - ) - slurm.slurm_get_select_nodeinfo(record.select_nodeinfo, - SELECT_NODEDATA_MEM_ALLOC, - NODE_STATE_ALLOCATED, &alloc_mem) +cdef secs2time_str(uint32_t time): + """Convert seconds to Slurm string format. - Host_dict['alloc_mem'] = alloc_mem + This method converts time in seconds (86400) to Slurm's string format + (1-00:00:00). - b_name = stringOrNone(record.name, '') - self._NodeDict[b_name] = Host_dict + Args: + time (int): Time in seconds - if nodeID: - last_inx = i - break + Returns: + str: Slurm time string. + """ + cdef: + char *time_str + double days, hours, minutes, seconds - slurm.slurm_free_node_info_msg(self._Node_ptr) - slurm.slurm_free_partition_info_msg(self._Part_ptr) - slurm.slurm_free_ctl_conf(slurm_ctl_conf_ptr) - self._Node_ptr = NULL - self._Part_ptr = NULL - return self._NodeDict + if time == slurm.INFINITE: + time_str = "UNLIMITED" + else: + seconds = time % 60 + minutes = (time / 60) % 60 + hours = (time / 3600) % 24 + days = time / 86400 + if days < 0 or hours < 0 or minutes < 0 or seconds < 0: + time_str = "INVALID" + elif days: + return "%ld-%2.2ld:%2.2ld:%2.2ld" % (days, hours, + minutes, seconds) + else: + return "%2.2ld:%2.2ld:%2.2ld" % (hours, minutes, seconds) - def update(self, dict node_dict): - """Update slurm node information. - Args: - node_dict (dict): A populated node dictionary, an empty one is - created by create_node_dict +cdef mins2time_str(uint32_t time): + """Convert minutes to Slurm string format. - Returns: - (int): 0 for success or -1 for error, and the slurm error code is - set appropriately. - """ - return slurm_update_node(node_dict) + This method converts time in minutes (14400) to Slurm's string format + (10-00:00:00). - def print_node_info_msg(self, int oneLiner=False): - """Output information about all slurm nodes. + Args: + time (int): Time in minutes - Args: - oneLiner (int, optional): Print on one line - """ - cdef: - int rc - int apiError + Returns: + str: Slurm time string. + """ + cdef: + double days, hours, minutes, seconds - rc = slurm.slurm_load_node( NULL, &self._Node_ptr, - self._ShowFlags) + if time == slurm.INFINITE: + return "UNLIMITED" + else: + seconds = 0 + minutes = time % 60 + hours = (time / 60) % 24 + days = time / 1440 - if rc == slurm.SLURM_SUCCESS: - slurm.slurm_print_node_info_msg(slurm.stdout, self._Node_ptr, oneLiner) - slurm.slurm_free_node_info_msg(self._Node_ptr) - self._Node_ptr = NULL + if days < 0 or hours < 0 or minutes < 0 or seconds < 0: + time_str = "INVALID" + elif days: + return "%ld-%2.2ld:%2.2ld:%2.2ld" % (days, hours, + minutes, seconds) else: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) + return "%2.2ld:%2.2ld:%2.2ld" % (hours, minutes, seconds) -def slurm_update_node(dict node_dict): - """Update slurm node information. +# +# Slurm Error Class +# - Args: - node_dict (dict): A populated node dictionary, an empty one is created - by create_node_dict - Returns: - (int): 0 for success or -1 for error, and the slurm error code is set - appropriately. - """ - cdef: - slurm.update_node_msg_t node_msg - int apiError = 0 - int errCode = 0 +class SlurmError(Exception): - if node_dict is {}: - return -1 + def __init__(self, value): + self.value = value - slurm.slurm_init_update_node_msg(&node_msg) + def __str__(self): + return repr(slurm.slurm_strerror(self.value)) - if 'node_state' in node_dict: - # see enum node_states - node_msg.node_state = node_dict['node_state'] - if 'features' in node_dict: - b_features = node_dict['features'].encode("UTF-8", "replace") - node_msg.features = b_features +# +# Slurm Error Functions +# - if 'gres' in node_dict: - b_gres = node_dict['gres'].encode("UTF-8") - node_msg.gres = b_gres - if 'node_names' in node_dict: - b_node_names = node_dict['node_names'].encode("UTF-8") - node_msg.node_names = b_node_names +def slurm_get_errno(): + """Return the slurm error as set by a slurm API call. - if 'reason' in node_dict: - b_reason = node_dict['reason'].encode("UTF-8") - node_msg.reason = b_reason - node_msg.reason_uid = os.getuid() + Returns: + (int): Current slurm error number + """ + return errno - if 'weight' in node_dict: - node_msg.weight = node_dict['weight'] - errCode = slurm.slurm_update_node(&node_msg) +def slurm_strerror(int Errno=0): + """Return slurm error message represented by a given slurm error number. - if errCode != slurm.SLURM_SUCCESS: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) + Args: + Errno (int): slurm error number. - return errCode + Returns: + (str): slurm error string + """ + cdef char* errMsg = slurm.slurm_strerror(Errno) + return "%s" % errMsg -def create_node_dict(): - """Return a an update_node dictionary - This dictionary can be populated by the user and used for the update_node - call. +def slurm_perror(char* Msg=''): + """Print to standard error the supplied header. - Returns: - (dict): Empty node dictionary + Header is followed by a colon, followed by a text description of the last + Slurm error code generated. + + Args: + Msg (str): slurm program error String """ - return { - 'node_names': None, - 'gres': None, - 'reason': None, - 'node_state': 0, - 'weight': 0, - 'features': None - } + slurm.slurm_perror(Msg) # @@ -3665,10 +2371,6 @@ cdef class jobstep: Step_dict['time_limit'] = job_step_info_ptr.job_steps[i].time_limit Step_dict['time_limit_str'] = secs2time_str(job_step_info_ptr.job_steps[i].time_limit) - Step_dict['tres_alloc_str'] = stringOrNone( - job_step_info_ptr.job_steps[i].tres_alloc_str, '' - ) - Step_dict['tres_bind'] = stringOrNone( job_step_info_ptr.job_steps[i].tres_bind, '' ) @@ -3728,7 +2430,6 @@ cdef class jobstep: Node_cnt = old_job_step_ptr.node_cnt - Layout['front_end'] = stringOrNone(old_job_step_ptr.front_end, '') Layout['node_cnt'] = Node_cnt Layout['node_list'] = stringOrNone(old_job_step_ptr.node_list, '') Layout['plane_size'] = old_job_step_ptr.plane_size @@ -4458,106 +3159,6 @@ def create_reservation_dict(): } -# -# Topology Class -# - - -cdef class topology: - """Access/update slurm topology information.""" - cdef: - slurm.topo_info_response_msg_t *_topo_info_ptr - dict _TopoDict - - def __cinit__(self): - self._topo_info_ptr = NULL - self._TopoDict = {} - - def __dealloc__(self): - self.__free() - - def lastUpdate(self): - """Get the time (epoch seconds) the retrieved data was updated. - - Returns: - (int): Epoch seconds - """ - return self._lastUpdate - - cpdef __free(self): - """Free the memory returned by load method.""" - if self._topo_info_ptr is not NULL: - slurm.slurm_free_topo_info_msg(self._topo_info_ptr) - - def load(self): - """Load slurm topology information.""" - self.__load() - - cpdef int __load(self) except? -1: - """Load slurm topology.""" - cdef int apiError = 0 - cdef int errCode = 0 - - if self._topo_info_ptr is not NULL: - # free previous pointer - slurm.slurm_free_topo_info_msg(self._topo_info_ptr) - - errCode = slurm.slurm_load_topo(&self._topo_info_ptr) - if errCode != 0: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - return errCode - - def get(self): - """Get slurm topology information. - - Returns: - (dict): Dictionary whose key is the Topology ID - """ - self.__load() - self.__get() - - return self._TopoDict - - cpdef __get(self): - cdef: - size_t i = 0 - dict Topo = {}, Topo_dict - - if self._topo_info_ptr is not NULL: - - for i in range(self._topo_info_ptr.record_count): - - Topo_dict = {} - - name = stringOrNone(self._topo_info_ptr.topo_array[i].name, '') - Topo_dict['name'] = name - Topo_dict['nodes'] = stringOrNone(self._topo_info_ptr.topo_array[i].nodes, '') - Topo_dict['level'] = self._topo_info_ptr.topo_array[i].level - Topo_dict['link_speed'] = self._topo_info_ptr.topo_array[i].link_speed - Topo_dict['switches'] = stringOrNone(self._topo_info_ptr.topo_array[i].switches, '') - - Topo[name] = Topo_dict - - self._TopoDict = Topo - - def display(self): - """Display topology information to standard output.""" - self._print_topo_info_msg() - - cpdef _print_topo_info_msg(self): - """Output information about topology based upon message as loaded - using slurm_load_topo. - """ - - if self._topo_info_ptr is not NULL: - slurm.slurm_print_topo_info_msg(slurm.stdout, - self._topo_info_ptr, - NULL, - self._ShowFlags) - - # # Statistics # @@ -4950,118 +3551,6 @@ cdef class statistics: return num2string[opcode] -# -# Front End Node Class -# - - -cdef class front_end: - """Access/update slurm front end node information.""" - - cdef: - slurm.time_t Time - slurm.time_t _lastUpdate - slurm.front_end_info_msg_t *_FrontEndNode_ptr - # slurm.front_end_info_t _record - uint16_t _ShowFlags - dict _FrontEndDict - - def __cinit__(self): - self._FrontEndNode_ptr = NULL - self._lastUpdate = 0 - self._ShowFlags = 0 - self._FrontEndDict = {} - - def __dealloc__(self): - self.__destroy() - - cpdef __destroy(self): - """Free the memory allocated by load front end node method.""" - if self._FrontEndNode_ptr is not NULL: - slurm.slurm_free_front_end_info_msg(self._FrontEndNode_ptr) - - def load(self): - """Load slurm front end node information.""" - self.__load() - - cdef int __load(self) except? -1: - """Load slurm front end node.""" - cdef: - # slurm.front_end_info_msg_t *new_FrontEndNode_ptr = NULL - time_t last_time = NULL - int apiError = 0 - int errCode = 0 - - if self._FrontEndNode_ptr is not NULL: - # free previous pointer - slurm.slurm_free_front_end_info_msg(self._FrontEndNode_ptr) - else: - last_time = NULL - errCode = slurm.slurm_load_front_end(last_time, &self._FrontEndNode_ptr) - - if errCode != 0: - apiError = slurm_get_errno() - raise ValueError(stringOrNone(slurm.slurm_strerror(apiError), ''), apiError) - - return errCode - - def lastUpdate(self): - """Return last time (sepoch seconds) the node data was updated. - - Returns: - (int): Epoch seconds - """ - return self._lastUpdate - - def ids(self): - """Return the node IDs from retrieved data. - - Returns: - (dict): Dictionary of node IDs - """ - return list(self._FrontEndDict.keys()) - - def get(self): - """Get front end node information. - - Returns: - (dict): Dictionary whose key is the Topology ID - """ - self.__load() - self.__get() - - return self._FrontEndDict - - cdef __get(self): - cdef: - dict FENode = {} - dict FE_dict = {} - - if self._FrontEndNode_ptr is not NULL: - for record in self._FrontEndNode_ptr.front_end_array[:self._FrontEndNode_ptr.record_count]: - FE_dict = {} - name = stringOrNone(record.name, '') - - FE_dict['boot_time'] = record.boot_time - FE_dict['allow_groups'] = stringOrNone(record.allow_groups, '') - FE_dict['allow_users'] = stringOrNone(record.allow_users, '') - FE_dict['deny_groups'] = stringOrNone(record.deny_groups, '') - FE_dict['deny_users'] = stringOrNone(record.deny_users, '') - - fe_node_state = get_node_state(record.node_state) - FE_dict['node_state'] = stringOrNone(fe_node_state, '') - - FE_dict['reason'] = stringOrNone(record.reason, '') - FE_dict['reason_time'] = record.reason_time - FE_dict['reason_uid'] = record.reason_uid - FE_dict['slurmd_start_time'] = record.slurmd_start_time - FE_dict['version'] = stringOrNone(record.version, '') - - FENode[name] = FE_dict - - self._FrontEndDict = FENode - - # # QOS Class # @@ -5341,7 +3830,6 @@ cdef class slurmdb_jobs: JOBS_info['gid'] = job.gid JOBS_info['jobid'] = job.jobid JOBS_info['jobname'] = stringOrNone(job.jobname, '') - JOBS_info['lft'] = job.lft JOBS_info['partition'] = stringOrNone(job.partition, '') JOBS_info['nodes'] = stringOrNone(job.nodes, '') JOBS_info['priority'] = job.priority @@ -5431,7 +3919,6 @@ cdef class slurmdb_jobs: step_info['task_dist'] = step.task_dist step_info['tot_cpu_sec'] = step.tot_cpu_sec step_info['tot_cpu_usec'] = step.tot_cpu_usec - step_info['tres_alloc_str'] = stringOrNone(step.tres_alloc_str, '') step_info['user_cpu_sec'] = step.user_cpu_sec step_info['user_cpu_usec'] = step.user_cpu_usec @@ -5946,7 +4433,6 @@ def get_trigger_res_type(uint16_t inx): * TRIGGER_RES_TYPE_SLURMCTLD 3 * TRIGGER_RES_TYPE_SLURMDBD 4 * TRIGGER_RES_TYPE_DATABASE 5 - * TRIGGER_RES_TYPE_FRONT_END 6 * TRIGGER_RES_TYPE_OTHER 7 Returns: @@ -5967,8 +4453,6 @@ cdef inline object __get_trigger_res_type(uint16_t ResType): rtype = 'slurmbdb' elif ResType == TRIGGER_RES_TYPE_DATABASE: rtype = 'database' - elif ResType == TRIGGER_RES_TYPE_FRONT_END: - rtype = 'front_end' elif ResType == TRIGGER_RES_TYPE_OTHER: rtype = 'other' @@ -6161,9 +4645,6 @@ cdef inline list debug_flags2str(uint64_t debug_flags): if (debug_flags & DEBUG_FLAG_FEDR): debugFlags.append('Federation') - if (debug_flags & DEBUG_FLAG_FRONT_END): - debugFlags.append('FrontEnd') - if (debug_flags & DEBUG_FLAG_GANG): debugFlags.append('Gang') From d7423a5edd5a661e1767e8402f0a350736e9d64b Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 17:38:10 +0200 Subject: [PATCH 09/11] bump version to 25.5.0 --- pyslurm/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyslurm/version.py b/pyslurm/version.py index 9797941c..e88cddeb 100644 --- a/pyslurm/version.py +++ b/pyslurm/version.py @@ -5,4 +5,4 @@ # The last Number "Z" is the current Pyslurm patch version, which should be # incremented each time a new release is made (except when migrating to a new # Slurm Major release, then set it back to 0) -__version__ = "24.11.0" +__version__ = "25.5.0" From 1bb3af058457ce0cc3b6f45ec2b7eed8295a2798 Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 18:00:15 +0200 Subject: [PATCH 10/11] slurmctld: update docs for the prolog/epilog timeout member change --- pyslurm/core/slurmctld/config.pxd | 9 +++++++-- pyslurm/core/slurmctld/config.pyx | 8 ++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pyslurm/core/slurmctld/config.pxd b/pyslurm/core/slurmctld/config.pxd index 7d6a03e3..f754ea33 100644 --- a/pyslurm/core/slurmctld/config.pxd +++ b/pyslurm/core/slurmctld/config.pxd @@ -285,6 +285,11 @@ cdef class Config: node when a Job completes. {slurm.conf#OPT_Epilog} + epilog_timeout (int): + The interval in seconds Slurm waits for Epilog before terminating + them. + + {slurm.conf#OPT_EpilogTimeout} epilog_msg_time (int): The number of microseconds that the slurmctld daemon requires to process an epilog completion message from the slurmd daemons. @@ -672,11 +677,11 @@ cdef class Config: it is asked to run a job step from a new job allocation. {slurm.conf#OPT_Prolog} - prolog_epilog_timeout (int): + prolog_timeout (int): The interval in seconds Slurm waits for Prolog and Epilog before terminating them. - {slurm.conf#OPT_PrologEpilogTimeout} + {slurm.conf#OPT_PrologTimeout} prolog_slurmctld (list[str]): List of pathnames of programs for the slurmctld daemon to execute before granting a new job allocation. diff --git a/pyslurm/core/slurmctld/config.pyx b/pyslurm/core/slurmctld/config.pyx index e73474e0..6f9d2ed6 100644 --- a/pyslurm/core/slurmctld/config.pyx +++ b/pyslurm/core/slurmctld/config.pyx @@ -457,6 +457,10 @@ cdef class Config: return cstr.to_list_with_count(self.ptr.epilog, self.ptr.epilog_cnt) + @property + def epilog_timeout(self): + return u16_parse(self.ptr.epilog_timeout) + @property def epilog_msg_time(self): return u32_parse(self.ptr.epilog_msg_time) @@ -846,10 +850,6 @@ cdef class Config: def prolog_timeout(self): return u16_parse(self.ptr.prolog_timeout) - @property - def epilog_timeout(self): - return u16_parse(self.ptr.epilog_timeout) - @property def prolog_slurmctld(self): return cstr.to_list_with_count(self.ptr.prolog_slurmctld, From 2a7f03615707f3f0c64cdc0786edf649131d09ba Mon Sep 17 00:00:00 2001 From: Toni Harzendorf Date: Sun, 28 Sep 2025 18:07:02 +0200 Subject: [PATCH 11/11] update all reference of 24.11 to 25.05 (except changelog for now) --- README.md | 10 +++++----- pyslurm.spec | 6 +++--- setup.cfg | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 97877258..e877e6e3 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,16 @@ pyslurm is the Python client library for the [Slurm Workload Manager](https://sl * [Python](https://www.python.org) - >= 3.6 * [Cython](https://cython.org) - >= 0.29.37 -This Version is for Slurm 24.11.x +This Version is for Slurm 25.05.x ## Versioning In pyslurm, the versioning scheme follows the official Slurm versioning. The first two numbers (`MAJOR.MINOR`) always correspond to Slurms Major-Release, -for example `24.11`. +for example `25.05`. The last number (`MICRO`) is however not tied in any way to Slurms `MICRO` version, but is instead PySlurm's internal Patch-Level. For example, any -pyslurm 24.11.X version should work with any Slurm 24.11.X release. +pyslurm 25.05.X version should work with any Slurm 25.05.X release. ## Installation @@ -29,8 +29,8 @@ the corresponding paths to the necessary files. You can specify those with environment variables (recommended), for example: ```shell -export SLURM_INCLUDE_DIR=/opt/slurm/24.11/include -export SLURM_LIB_DIR=/opt/slurm/24.11/lib +export SLURM_INCLUDE_DIR=/opt/slurm/25.05/include +export SLURM_LIB_DIR=/opt/slurm/25.05/lib ``` Then you can proceed to install pyslurm, for example by cloning the Repository: diff --git a/pyslurm.spec b/pyslurm.spec index a2c75c07..f06ebb1e 100644 --- a/pyslurm.spec +++ b/pyslurm.spec @@ -1,7 +1,7 @@ %define python3_pkgversion 3.11 Name: python-pyslurm -Version: 24.11.0 +Version: 25.5.0 %define rel 1 Release: %{rel}%{?dist} Summary: Python interface to Slurm @@ -15,8 +15,8 @@ BuildRequires: python%{python3_pkgversion}-wheel BuildRequires: python%{python3_pkgversion}-Cython BuildRequires: python%{python3_pkgversion}-packaging BuildRequires: python-rpm-macros -BuildRequires: slurm-devel >= 24.11.0 -BuildRequires: slurm >= 24.11.0 +BuildRequires: slurm-devel >= 25.05.0 +BuildRequires: slurm >= 25.05.0 Requires: python%{python3_pkgversion} %description diff --git a/setup.cfg b/setup.cfg index 43c3b737..6c8a65a5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,6 +4,6 @@ packager = Giovanni Torres doc_files = README.md examples/ build_requires = python3-devel >= 3.6 - slurm-devel >= 24.11.0 + slurm-devel >= 25.05.0 requires = slurm use_bzip2 = 1