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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/pyslurm.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: PySlurm

env:
SLURM_DOCKER_IMAGE: giovtorres/slurm-docker:25.11.4-rl10
SLURM_DOCKER_IMAGE: giovtorres/slurm-docker:26.05.3-rl10

on:
push:
Expand All @@ -18,11 +18,11 @@ jobs:
strategy:
matrix:
include:
- slurm-image: giovtorres/slurm-docker:25.11.4-rl10
- slurm-image: giovtorres/slurm-docker:26.05.3-rl10
python-version: "3.12"
- slurm-image: giovtorres/slurm-docker:25.11.4-rl9
- slurm-image: giovtorres/slurm-docker:26.05.3-rl9
python-version: "3.9"
- slurm-image: giovtorres/slurm-docker:25.11.4-rl8
- slurm-image: giovtorres/slurm-docker:26.05.3-rl8
python-version: "3.6"
fail-fast: false
env:
Expand Down
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,52 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased on the [26.05.x](https://github.com/PySlurm/pyslurm/tree/26.05.x) branch

### Added

- Support for Slurm 26.05.x
- New Enums, both available directly as `pyslurm.<name>`:
- `JobExclusive`
- `JobOversubscribe`
- New members added for the `pyslurm.Job` class:
- `container_type`
- `exclusive`
- `oversubscribe`
- `memory_update_delay`
- `memory_update_margin`
- New member added for the `pyslurm.JobStep` class:
- `container_type`
- New member added for the `pyslurm.JobSubmitDescription` class:
- `container_type` (also recognized as `--container-type` in batch scripts)
- New member added for the `pyslurm.Node` class:
- `suspend_time`
- New members added for the `pyslurm.slurmctld.Config` class:
- `health_check_timeout`
- `license_parameters`
- `metrics_auth`
- `metrics_auth_users`
- `metrics_parameters`
- `slurmctld_http_auth_parameters`
- `slurmd_http_auth_parameters`

### Fixed

- Fixed heap corruption in `pyslurm.Reservation.create()`. Slurm 26.05 changed
`slurm_create_reservation` to return an `xmalloc`-allocated name, which must
be released with `xfree` rather than `free`.
- Added the `node_ranks` member to the internal `job_resources` struct
definition. Its absence shifted every following member, corrupting
`pyslurm.Job.cpus`.

### Changed

- Slurm 26.05 changed a number of RPCs to take a `slurm_step_id_t` instead of a
plain `uint32_t` job id. This is handled internally and the PySlurm API is
unchanged.
- `ESLURM_ERROR_ON_DESC_TO_RECORD_COPY` was removed in Slurm 26.05 and is
replaced by `ESLURM_MAX_JOB_COUNT`.

## Unreleased on the [25.11.x](https://github.com/PySlurm/pyslurm/tree/25.11.x) branch

### Added
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pyslurm is the Python client library for the [Slurm Workload Manager](https://sl

## Requirements

* [Slurm](https://slurm.schedmd.com) 25.11.x — shared library and header files
* [Slurm](https://slurm.schedmd.com) 26.05.x — shared library and header files
* [Python](https://www.python.org) >= 3.6

## Versioning
Expand All @@ -15,6 +15,7 @@ major release.

| PySlurm | Slurm |
|---|---|
| 26.05.x | 26.05.x |
| 25.11.x | 25.11.x |
| 24.05.x | 24.05.x |
| 23.11.x | 23.11.x |
Expand Down
184 changes: 150 additions & 34 deletions UPGRADE_C_API.rst
Original file line number Diff line number Diff line change
@@ -1,67 +1,183 @@
Upgrading PySlurm to a new Slurm Release
========================================

Contents
--------

* `Overview`_
* `Directory Structure`_
* `Requirements`_
* `Generating Code`_
* `Compiling, Updating, Testing`_
* `1. Create the branch`_
* `2. Validate the generator`_
* `3. Regenerate the bindings`_
* `4. Audit extra.pxi`_
* `5. Build and fix call sites`_
* `6. Test`_
* `7. Update version metadata`_

Overview
--------

This small guide shows how to update PySlurm to a new Major Slurm Release - specifically it shows
how to translate the C-API Headers into an appropriate file with cython definitions.

Directory Structure
-------------------
PySlurm tracks Slurm major releases one-for-one: branch ``26.05.x`` targets
Slurm 26.05, ``25.11.x`` targets 25.11, and so on. Upgrading means pointing the
Cython definitions at the new C headers and repairing whatever the new release
broke.

All the Cython definitions for Slurm can be found in the directory :code:`pyslurm/slurm/`
Essentially, the two most important files are :code:`header.pxi` and :code:`extra.pxi`.
The first one contains all auto-generated definitions, the latter one contains definitions not found in the headers directly, but exported in `libslurm.so`.
The definitions live in :code:`pyslurm/slurm/`:

The Idea here is to simply have one branch for each Major release, e.g. `20.11`, `21.08`, `22.05` and so on.
* :code:`slurm.h.pxi`, :code:`slurmdb.h.pxi`, :code:`slurm_errno.h.pxi` are
**generated** from the Slurm headers by :code:`scripts/pyslurm_bindgen.py`.
Never edit them by hand.
* :code:`extra.pxi` is **hand-maintained**. It declares internal structs and
functions that are exported by ``libslurmfull.so`` but absent from the public
headers. This file is where upgrades go wrong quietly - see step 4.

Requirements
------------

- `autopxd2 <https://pypi.org/project/autopxd2/>`_
- C-Preprocessor (*cpp*, *clang*)
- Slurm headers (*slurm.h*, *slurmdb.h*, *slurm_errno.h*)
- Cython compiler (latest stable)
* `autopxd2 <https://pypi.org/project/autopxd2/>`_ **2.5.0**. Pin it. The 3.x
series changed the API that :code:`pyslurm_bindgen.py` calls into.
* A C preprocessor (*cpp* or *clang*)
* Slurm headers for the target release (*slurm.h*, *slurmdb.h*, *slurm_errno.h*)
* Cython (latest stable)

Work inside a container or VM that has the target Slurm release installed, so
that the headers, ``libslurmfull.so``, and a running ``slurmctld`` all match.

1. Create the branch
--------------------

Name it after the Slurm major release:

.. code-block:: bash

Generating Code
---------------
git checkout -b 26.05.x

The script in :code:`scripts/pyslurm_bindgen.py` basically generates all of the needed definitions from the Header files.
Inside the script, `autopxd2` is used which helps to create Cython specific definitions for all structs and functions.
In addition, also all constants from the headers (`#define`) are made available with their appropriate data types.
2. Validate the generator
-------------------------

First of all, checkout a new branch in the Repository, and give it the name
of the major release to target, for example:
Before generating anything you intend to keep, run the generator against the
**previous** release's headers and diff the result against what is already
committed:

.. code-block:: bash

git checkout -b 22.05
scripts/pyslurm_bindgen.py -D /path/to/25.11/include/slurm -o /tmp/check
diff pyslurm/slurm/slurm.h.pxi /tmp/check/slurm.h.pxi

Ignore the ``Generated on`` timestamp; everything else should be identical. If
it is not, your autopxd2 version or toolchain differs from the one that produced
the committed files, and every diff you see in step 3 will be noise. Fix that
first.

Then, simply generate the header definitions like in this example:
3. Regenerate the bindings
--------------------------

.. code-block:: bash

scripts/pyslurm_bindgen.py -D /directory/with/slurm/headers > pyslurm/slurm/header.pxi
scripts/pyslurm_bindgen.py -D /path/to/26.05/include/slurm

The script writes one :code:`<header>.pxi` per header into
:code:`pyslurm/slurm/` (override with :code:`-o`, or use :code:`-s` to print to
stdout instead). It also translates ``#define`` macros into typed constants.

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 diff against the previous release's generated output. That diff *is* the
API change list: renamed functions, changed signatures, added and removed struct
members, new and deleted enum values. Read all of it. Anything that only changes
a struct member will compile cleanly and fail at runtime.

If the generator crashes, the new headers contain a construct autopxd2 cannot
parse. Prefer patching :code:`scripts/pyslurm_bindgen.py` over editing generated
output - see ``_patch_autopxd_enum_casts()`` there for an example, added when
26.05 started using ``SLURM_BIT()`` (which expands to a cast) for enum values.

Compiling, Updating, Testing
----------------------------
Fix the fallout in :code:`pyslurm/pydefines/*.pxi`, which reference constants by
name and break loudly when one disappears.

Now with the generated headers, you can try and build pyslurm (e.g. by having a slurm installation in a virtual machine):
4. Audit extra.pxi
------------------

**Do not skip this step.** The structs in :code:`extra.pxi` are declared as
plain ``ctypedef struct``, not inside a ``cdef extern`` block, so Cython emits
its own C definition rather than deferring to a header. If a member is added
upstream and not mirrored here, every following member reads from the wrong
offset. Nothing warns you: the build succeeds and unit tests pass.

Fetch the matching Slurm sources and compare each declaration field by field:

.. code-block:: bash

python3 setup.py build
curl -O https://download.schedmd.com/slurm/slurm-26.05.2.tar.bz2
tar xf slurm-26.05.2.tar.bz2

The structs and their homes:

=========================== ==========================================
Declaration Slurm source
=========================== ==========================================
``job_resources`` ``src/common/job_resources.h``
``slurm_msg_t`` ``src/common/slurm_protocol_defs.h``
``forward_t`` ``src/common/slurm_protocol_defs.h``
``forward_struct_t`` ``src/common/slurm_protocol_defs.h``
``job_id_msg_t`` ``src/common/slurm_protocol_defs.h``
``return_code_msg_t`` ``src/common/slurm_protocol_defs.h``
``persist_conn_t`` ``src/common/persist_conn.h``
``persist_msg_t`` ``src/common/persist_conn.h``
``buf_t`` ``src/common/pack.h``
``slurm_msg_type_t`` ``src/common/msg_type.h``
``tres_types_t`` ``src/common/slurmdb_defs.h``
=========================== ==========================================

Check for three things:

* **Added or removed members.** Order matters. A ``void *`` standing in for a
concrete pointer type is fine; a missing member is not.
* **Structs embedded by value.** ``forward_t`` sits inside ``slurm_msg_t``, so a
change to it silently resizes ``slurm_msg_t``.
* **Hardcoded enum values.** :code:`extra.pxi` pins a few ``slurm_msg_type_t``
members to literal numbers. Slurm reuses retired RPC slots between releases,
so recompute them from the new ``msg_type.h``.

Also check memory ownership. Slurm occasionally switches an API from returning
``strdup``-allocated memory to ``xmalloc``-allocated memory (26.05 did this to
``slurm_create_reservation``). Calling libc ``free()`` on an ``xmalloc`` pointer
corrupts the heap. Grepping the release's ``src/api/*.c`` for changes in the
``caller must free`` / ``caller must xfree`` comments catches these cheaply.

5. Build and fix call sites
---------------------------

.. code-block:: bash

scripts/build.sh -j8 -d

Iterate until it compiles. Most breakage is mechanical: renamed functions,
changed argument types, deleted constants. A clean build means the code
*compiles* against the new API - it says nothing about steps 3 and 4 being
complete.

6. Test
-------

.. code-block:: bash

scripts/run_tests.sh # unit + integration

Integration tests need a running Slurm of the target version; they are what
catch the struct layout and memory ownership problems that the build cannot.
Run them before opening the PR.

7. Update version metadata
--------------------------

Set :code:`pyslurm/version.py` to ``<major>.<minor>.0``. ``setup.py`` derives
the required Slurm version from it and refuses to build against a mismatched
``slurm_version.h``.

Then update the remaining references:

This will likely give you a bunch of errors, since usually a few things have changed in between major releases.
Usually it is rather straightforward to adapt the code. Often only a few constants have been deleted/renamed. If no more errors are showing and it compiles, everything is done.
* :code:`pyslurm.spec` - ``Version``, ``BuildRequires: slurm-devel``, ``%changelog``
* :code:`README.md` - requirements line and compatibility table
* :code:`CLAUDE.md` - required Slurm version
* :code:`CHANGELOG.md` - new section for the branch
* :code:`docker-compose.yml` - default image tag
* :code:`.github/workflows/pyslurm.yml` - image tags in the test matrix
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
slurm:
image: ${SLURM_DOCKER_IMAGE:-giovtorres/slurm-docker:25.11.2}
image: ${SLURM_DOCKER_IMAGE:-giovtorres/slurm-docker:26.05.3}
hostname: slurmctl
container_name: slurmctl
privileged: true
Expand Down
9 changes: 6 additions & 3 deletions pyslurm.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: python-pyslurm
Version: 25.11.2
Version: 26.5.0
%define rel 1
Release: %{rel}%{?dist}
Summary: Python interface to Slurm
Expand All @@ -9,7 +9,7 @@ Source: pyslurm-%{version}.tar.gz

BuildRequires: python3-devel
BuildRequires: pyproject-rpm-macros
BuildRequires: slurm-devel >= 25.11.0
BuildRequires: slurm-devel >= 26.05.0

%description
pyslurm is a Python interface to Slurm
Expand Down Expand Up @@ -39,7 +39,10 @@ pyslurm is a Python interface to Slurm
%doc README.md

%changelog
* Sat Apr 12 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.2-1
* Thu Aug 20 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 26.5.0-1
- Support for Slurm 26.05.x

* Sat Apr 12 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.2-1
- Fix Python 3.6 package metadata (UNKNOWN-0.0.0) by reading version from setup.py

* Sun Mar 22 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.0-1
Expand Down
12 changes: 12 additions & 0 deletions pyslurm/core/job/job.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, int64_t
from libc.stdlib cimport free
from pyslurm.core.job.submission cimport JobSubmitDescription
from pyslurm.core.job.step cimport JobSteps, JobStep
from pyslurm.utils.helpers cimport init_job_step_id
from pyslurm.xcollections cimport MultiClusterMap
from pyslurm cimport slurm
from pyslurm.slurm cimport (
Expand Down Expand Up @@ -62,6 +63,7 @@ from pyslurm.slurm cimport (
slurm_update_job,
slurm_notify_job,
slurm_requeue,
slurm_step_id_t,
xfree,
try_xmalloc,
)
Expand Down Expand Up @@ -287,6 +289,10 @@ cdef class Job:
Name of the reservation this Job uses.
resource_sharing (str):
Mode controlling how a job shares resources with others.
exclusive (pyslurm.JobExclusive):
Exclusive resource allocation mode of the Job.
oversubscribe (pyslurm.JobOversubscribe):
Whether the Job is willing to oversubscribe resources.
requires_contiguous_nodes (bool):
Whether the Job has allocated a set of contiguous nodes.
licenses (list):
Expand All @@ -307,6 +313,12 @@ cdef class Job:
The container this Job uses.
container_id (str):
The OCI ID of the Container this Job uses.
container_type (str):
Container plugin type the Job uses.
memory_update_delay (int):
Delay in minutes before memory is auto-reduced.
memory_update_margin (int):
Margin in percent applied when memory is auto-reduced.
comment (str):
An arbitrary comment set for the Job.
standard_input (str):
Expand Down
Loading