diff --git a/UPGRADE_C_API.rst b/UPGRADE_C_API.rst index 6e7c84ae..3a47b2ed 100644 --- a/UPGRADE_C_API.rst +++ b/UPGRADE_C_API.rst @@ -51,13 +51,8 @@ Then, simply generate the header definitions like in this example: scripts/pyslurm_bindgen.py -D /directoy/with/slurm/headers > pyslurm/slurm/header.pxi The script outputs everything to `stdout`. Simply redirect the output to the file: :code:`pyslurm/slurm/header.pxi`. +The headers should now be fully translated. -Now, 99% of the work is done for generating the headers. For the 1% left, you now need to open the generated file, search for the two follwowing statements and comment them out: - -- `slurm_addr_t control_addr` -- `phtread_mutex_t lock` - -The compiler will otherwise complain that these are incomplete type definitions. Compiling, Updating, Testing ---------------------------- diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index a9237b4b..0dd42c2c 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -2312,19 +2312,71 @@ cdef class job: def slurm_job_batch_script(self, jobid): """ - Retrieve the batch script for a given jobid. + Return the contents of the batch-script for a Job. - :param str jobid: Job id key string to search - :returns: String output of a jobid's batch script + Note: The string returned also includes all the "\n" characters + (new-line). + + :param jobid: ID of the Job for which the script should be retrieved. + :type jobid: Union[str, int] + :raises: [ValueError]: When retrieving the Batch-Script for the Job was + not successful. + :returns: The content of the batch script. :rtype: `str` """ + # This reimplements the slurm_job_batch_script API call. Otherwise we + # would have to parse the FILE* ptr we get from it back into a + # char* which would be a bit silly. Source: + # https://github.com/SchedMD/slurm/blob/7162f15af8deaf02c3bbf940d59e818cdeb5c69d/src/api/job_info.c#L1319 + cdef: + slurm.job_id_msg_t msg + slurm.slurm_msg_t req + slurm.slurm_msg_t resp + int rc = slurm.SLURM_SUCCESS + str script = None + if isinstance(jobid, int) or isinstance(jobid, long): jobid = str(jobid).encode("UTF-8") else: jobid = jobid.encode("UTF-8") jobid_xlate = slurm.slurm_xlate_job_id(jobid) - return slurm.slurm_job_batch_script(slurm.stdout, jobid_xlate) + + slurm.slurm_msg_t_init(&req) + slurm.slurm_msg_t_init(&resp) + + memset(&msg, 0, sizeof(msg)) + msg.job_id = jobid_xlate + req.msg_type = slurm.REQUEST_BATCH_SCRIPT + req.data = &msg + + rc = slurm.slurm_send_recv_controller_msg(&req, &resp, + slurm.working_cluster_rec) + if rc < 0: + err = slurm.slurm_get_errno() + raise ValueError(slurm.stringOrNone(slurm.slurm_strerror(err), ''), + err) + + if resp.msg_type == slurm.RESPONSE_BATCH_SCRIPT: + script = slurm.stringOrNone(resp.data, None) + slurm.xfree(resp.data) + + elif resp.msg_type == slurm.RESPONSE_SLURM_RC: + rc = ( resp.data).return_code + slurm.slurm_free_return_code_msg(resp.data) + + if rc == slurm.SLURM_ERROR: + rc = slurm.slurm_get_errno() + + raise ValueError(slurm.stringOrNone(slurm.slurm_strerror(rc), ''), + rc) + + else: + rc = slurm.slurm_get_errno() + raise ValueError(slurm.stringOrNone(slurm.slurm_strerror(rc), ''), + rc) + + return script cdef int fill_job_desc_from_opts(self, dict job_opts, slurm.job_desc_msg_t *desc): """ diff --git a/pyslurm/slurm/__init__.pxd b/pyslurm/slurm/__init__.pxd index d779bb18..3c64b282 100644 --- a/pyslurm/slurm/__init__.pxd +++ b/pyslurm/slurm/__init__.pxd @@ -1,19 +1,37 @@ from libcpp cimport bool -from posix.unistd cimport uid_t, pid_t, gid_t -from libc.stdint cimport int8_t, int16_t, int32_t, int64_t -from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t from cpython.version cimport PY_MAJOR_VERSION -from libc.string cimport strlen, memcpy -cdef extern from "" nogil: - ctypedef struct sockaddr_in - ctypedef struct sockaddr_storage +from posix.unistd cimport ( + uid_t, + pid_t, + gid_t, +) + +from libc.stdint cimport ( + int8_t, + int16_t, + int32_t, + int64_t, + uint8_t, + uint16_t, + uint32_t, + uint64_t, +) + +from libc.string cimport ( + strlen, + memcpy, +) + +cdef extern from '' nogil: + ctypedef struct sockaddr_storage: + pass cdef extern from '' nogil: ctypedef struct FILE cdef FILE *stdout -cdef extern from 'time.h' nogil: +cdef extern from '' nogil: ctypedef long time_t double difftime(time_t time1, time_t time2) time_t time(time_t *t) @@ -24,8 +42,15 @@ cdef extern from '' nogil: cdef int __LINE__ char *__FUNCTION__ -cdef extern from "" nogil: - ctypedef union pthread_mutex_t +cdef extern from '' nogil: + ctypedef struct pthread_mutex_t: + pass + + ctypedef struct pthread_cond_t: + pass + + ctypedef struct pthread_t: + pass cdef extern from *: ctypedef struct slurm_job_credential diff --git a/pyslurm/slurm/extra.pxi b/pyslurm/slurm/extra.pxi index f48572d4..50fccb23 100644 --- a/pyslurm/slurm/extra.pxi +++ b/pyslurm/slurm/extra.pxi @@ -1,4 +1,132 @@ +# +# Structs that are not in the Slurm headers, which need to be redefined +# in order to implement certain features. +# +# For example: to communicate with the slurmctld directly in order +# to retrieve the actual batch-script as a string. +# + +# https://github.com/SchedMD/slurm/blob/26abe9188ea8712ba1eab4a8eb6322851f06a108/src/common/slurm_persist_conn.h#L51 +ctypedef enum persist_conn_type_t: + PERSIST_TYPE_NONE = 0 + PERSIST_TYPE_DBD + PERSIST_TYPE_FED + PERSIST_TYPE_HA_CTL + PERSIST_TYPE_HA_DBD + PERSIST_TYPE_ACCT_UPDATE + +# https://github.com/SchedMD/slurm/blob/26abe9188ea8712ba1eab4a8eb6322851f06a108/src/common/slurm_persist_conn.h#L59 +ctypedef struct persist_msg_t: + void *conn + void *data + uint32_t data_size + uint16_t msg_type + +ctypedef int (*_slurm_persist_conn_t_callback_proc) (void *arg, persist_msg_t *msg, buf_t **out_buffer, uint32_t *uid) +ctypedef void (*_slurm_persist_conn_t_callback_fini)(void *arg) + +# https://github.com/SchedMD/slurm/blob/26abe9188ea8712ba1eab4a8eb6322851f06a108/src/common/slurm_persist_conn.h#L66 +ctypedef struct slurm_persist_conn_t: + void *auth_cred + _slurm_persist_conn_t_callback_proc callback_proc + _slurm_persist_conn_t_callback_fini callback_fini + 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 + uid_t r_uid + char *rem_host + uint16_t rem_port + time_t *shutdown + pthread_t thread_id + int timeout + slurm_trigger_callbacks_t trigger_callbacks; + uint16_t version + +# https://github.com/SchedMD/slurm/blob/20e2b354168aeb0f76d67f80122d80925c2ef32b/src/common/pack.h#L68 +ctypedef struct buf_t: + uint32_t magic + char *head + uint32_t size + uint32_t processed + bool mmaped + +# https://github.com/SchedMD/slurm/blob/20e2b354168aeb0f76d67f80122d80925c2ef32b/src/common/pack.h#L68 +ctypedef struct return_code_msg_t: + uint32_t return_code + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.h#L650 +ctypedef struct job_id_msg_t: + uint32_t job_id + uint16_t show_flags + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.h#L216 +# Only partially defined - not everything needed at the moment. +ctypedef enum slurm_msg_type_t: + REQUEST_SHARE_INFO = 2022 + REQUEST_BATCH_SCRIPT = 2051 + RESPONSE_BATCH_SCRIPT = 2052 + RESPONSE_SLURM_RC = 8001 + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.h#L469 +ctypedef struct forward_t: + uint16_t cnt + uint16_t init + char *nodelist + uint32_t timeout + uint16_t tree_width + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.h#L491 +ctypedef struct forward_struct_t: + char *buf + int buf_len + uint16_t fwd_cnt + pthread_mutex_t forward_mutex + pthread_cond_t notify + List ret_list + uint32_t timeout + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.h#L514 +ctypedef struct slurm_msg_t: + slurm_addr_t address + void *auth_cred + int auth_index + uid_t auth_uid + bool auth_uid_set + uid_t restrict_uid + bool restrict_uid_set + uint32_t body_offset + buf_t *buffer + slurm_persist_conn_t *conn + int conn_fd + void *data + uint32_t data_size + uint16_t flags + uint8_t hash_index + uint16_t msg_type + uint16_t protocol_version + forward_t forward + forward_struct_t *forward_struct + slurm_addr_t orig_addr + List ret_list + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.c#L865 +cdef extern void slurm_free_return_code_msg(return_code_msg_t *msg) + +# https://github.com/SchedMD/slurm/blob/2d2e83674b59410a7ed8ab6fc8d8acfcfa8beaf9/src/common/slurm_protocol_api.c#L2401 +cdef extern int slurm_send_recv_controller_msg(slurm_msg_t *request_msg, + slurm_msg_t *response_msg, + slurmdb_cluster_rec_t *working_cluster_rec) + +# https://github.com/SchedMD/slurm/blob/fe82218def7b57f5ecda9222e80662ebbb6415f8/src/common/slurm_protocol_defs.c#L168 +cdef extern void slurm_msg_t_init(slurm_msg_t *msg) + + # Global Environment + cdef extern char **environ #