Skip to content
Merged
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
72 changes: 70 additions & 2 deletions .github/workflows/pyslurm.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
name: PySlurm

env:
SLURM_DOCKER_IMAGE: giovtorres/slurm-docker:25.11.2

on:
push:
branches: [main]
pull_request:
branches: [main]
release:
types: [published]
workflow_dispatch:

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]
python-version:
- "3.12"
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Pull Slurm container
run: docker pull giovtorres/slurm-docker:25.11.2
run: docker pull ${{ env.SLURM_DOCKER_IMAGE }}

- name: Start Slurm container
run: docker compose up -d
Expand All @@ -29,3 +35,65 @@ jobs:

- name: Run integration tests
run: scripts/run_tests.sh -s -i

build-sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Install build
run: pip install build

- name: Build sdist
run: python -m build --sdist

- name: Upload sdist artifact
uses: actions/upload-artifact@v7
with:
name: sdist
path: dist/*.tar.gz
retention-days: 7

build-rpm:
runs-on: ubuntu-latest
needs: build-sdist
if: github.event_name == 'pull_request' || github.event_name == 'release'
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Download sdist artifact
uses: actions/download-artifact@v8
with:
name: sdist
path: dist/

- name: Pull Slurm container
run: docker pull ${{ env.SLURM_DOCKER_IMAGE }}

- name: Start Slurm container
run: docker compose up -d

- name: Build RPM
run: scripts/build_rpm.sh

publish:
runs-on: ubuntu-latest
needs: [tests, build-sdist, build-rpm]
if: github.event_name == 'release'
environment: pypi
permissions:
id-token: write
steps:
- name: Download sdist artifact
uses: actions/download-artifact@v8
with:
name: sdist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
59 changes: 33 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,60 @@ pyslurm is the Python client library for the [Slurm Workload Manager](https://sl

## Requirements

* [Slurm](https://slurm.schedmd.com) - Slurm shared library and header files
* [Python](https://www.python.org) - >= 3.6
* [Cython](https://cython.org) - >= 0.29.37

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

## 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 `25.11`.
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 25.11.X version should work with any Slurm 25.11.X release.
PySlurm uses the format `X.Y.Z` where `X.Y` tracks the Slurm major release
and `Z` is PySlurm's own patch increment, reset to `0` on each new Slurm
major release.

| PySlurm | Slurm |
|---|---|
| 25.11.x | 25.11.x |
| 24.05.x | 24.05.x |
| 23.11.x | 23.11.x |

## Installation

By default, it is searched inside `/usr/include` for the Header files and in
`/usr/lib64` for Slurms shared-library (`libslurm.so`) during Installation.
For Slurm installations in different locations, you will need to provide
the corresponding paths to the necessary files.
PySlurm requires the Slurm development headers and shared library at build
time.

### Slurm header and library paths

If you have `slurm-devel` installed in the default paths, skip this section.

By default, PySlurm looks in:

* `/usr/include` — for Slurm header files (`slurm/slurm.h`)
* `/usr/lib64` — for the Slurm shared library (`libslurmfull.so`)

You can specify those with environment variables (recommended), for example:
If your Slurm installation is not in the default paths, set these before
installing:

```shell
export SLURM_INCLUDE_DIR=/opt/slurm/25.11/include
export SLURM_LIB_DIR=/opt/slurm/25.11/lib
export SLURM_INCLUDE_DIR=/path/to/slurm/include
export SLURM_LIB_DIR=/path/to/slurm/lib
```

Then you can proceed to install pyslurm, for example by cloning the Repository:
### From PyPI

```shell
git clone https://github.com/PySlurm/pyslurm.git && cd pyslurm
scripts/build.sh
pip install pyslurm
```

Also see `scripts/build.sh -h`. You can specify multiple cores for building
with the `-j` option (also possible to set via environment variable `PYSLURM_BUILD_JOBS`):
### From source

```shell
scripts/build.sh -j4
git clone https://github.com/PySlurm/pyslurm.git && cd pyslurm
scripts/build.sh
```

Or simply with `pip` directly:
Use `-j` to build with multiple cores (or set `PYSLURM_BUILD_JOBS`):

```shell
pip install .
scripts/build.sh -j4
```

## Contributors
Expand Down
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: giovtorres/slurm-docker:25.11.2
image: ${SLURM_DOCKER_IMAGE:-giovtorres/slurm-docker:25.11.2}
hostname: slurmctl
container_name: slurmctl
privileged: true
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ requires = [
[project]
name = "pyslurm"
dynamic = ["version"]
license = "GPL-2.0-only"
license = {text = "GPL-2.0-only"}
description = "Python Interface for Slurm"
readme = "README.md"
requires-python = ">=3.6"
Expand Down Expand Up @@ -70,6 +70,7 @@ version = { attr = "pyslurm.version.__version__" }

[tool.setuptools.packages.find]
include = ["pyslurm*"]
exclude = ["pyslurm.pydefines", "pyslurm.slurm"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know when using scripts/build.sh setuptools was always complaining about those. Adding pyslurm.slurm here should still include it in the sdist though right? (since its explicitly mentioned in MANIFEST.in). It just doesn't add those sources to the final installation dir I guess? (which is fine)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, both of these directories don’t have an __init__.py and only have Cython source files. The sdist does include these files since they are part of the source files needed to build the extension. The exclude here is so that these dirs don’t show up as importable Python packages, but they don’t have an __init__.py anyway. So, this shouldn’t change behavior, just make it explicit, if i’m not mistaken.

→ tar tzvf dist/pyslurm-25.11.0.tar.gz | grep pxi
-rw-r--r--  0 root   root       19 Feb 27  2022 pyslurm-25.11.0/pyslurm/bluegene.pxi
-rw-r--r--  0 root   root    16959 Mar 15 16:55 pyslurm-25.11.0/pyslurm/pydefines/slurm_defines.pxi
-rw-r--r--  0 root   root    22903 Mar 15 16:55 pyslurm-25.11.0/pyslurm/pydefines/slurm_enums.pxi
-rw-r--r--  0 root   root      116 Nov 14  2021 pyslurm-25.11.0/pyslurm/pydefines/slurm_errno_defines.pxi
-rw-r--r--  0 root   root    10772 Mar 15 16:55 pyslurm-25.11.0/pyslurm/pydefines/slurm_errno_enums.pxi
-rw-r--r--  0 root   root     2729 Mar 15 16:55 pyslurm-25.11.0/pyslurm/pydefines/slurmdb_defines.pxi
-rw-r--r--  0 root   root     4411 Mar 15 16:55 pyslurm-25.11.0/pyslurm/pydefines/slurmdb_enums.pxi
-rw-r--r--  0 root   root    10507 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/extra.pxi
-rw-r--r--  0 root   root     3351 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/helpers.pxi
-rw-r--r--  0 root   root    91453 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/slurm.h.pxi
-rw-r--r--  0 root   root    15320 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/slurm_errno.h.pxi
-rw-r--r--  0 root   root      842 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/slurm_version.h.pxi
-rw-r--r--  0 root   root    38974 Mar 15 16:55 pyslurm-25.11.0/pyslurm/slurm/slurmdb.h.pxi


[tool.ruff]
line-length = 80
Expand Down
25 changes: 11 additions & 14 deletions pyslurm.spec
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
%define python3_pkgversion 3.11

Name: python-pyslurm
Version: 25.11.0
%define rel 1
Release: %{rel}%{?dist}
Summary: Python interface to Slurm
License: GPLv2+
License: GPL-2.0-only
URL: https://github.com/PySlurm/pyslurm
Source: pyslurm-%{version}.tar.gz

BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: python%{python3_pkgversion}-setuptools
BuildRequires: python%{python3_pkgversion}-wheel
BuildRequires: python%{python3_pkgversion}-Cython
BuildRequires: python%{python3_pkgversion}-packaging
BuildRequires: python-rpm-macros
BuildRequires: python3-devel
BuildRequires: pyproject-rpm-macros
BuildRequires: slurm-devel >= 25.11.0
BuildRequires: slurm >= 25.11.0
Requires: python%{python3_pkgversion}

%description
pyslurm is a Python interface to Slurm

%package -n python%{python3_pkgversion}-pyslurm
%package -n python3-pyslurm
Summary: %{summary}
Requires: python3

%description -n python%{python3_pkgversion}-pyslurm
%description -n python3-pyslurm
pyslurm is a Python interface to Slurm

%prep
Expand All @@ -41,6 +34,10 @@ pyslurm is a Python interface to Slurm
%pyproject_install
%pyproject_save_files pyslurm

%files -f %{pyproject_files}
%files -n python3-pyslurm -f %{pyproject_files}
%license COPYING.txt
%doc README.md

%changelog
* Sun Mar 22 2026 Giovanni Torres <giovtorres@users.noreply.github.com> - 25.11.0-1
- Initial package
89 changes: 89 additions & 0 deletions scripts/build_rpm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
set -e

CONTAINER_NAME="${CONTAINER_NAME:-slurmctl}"
RPMBUILD_DIR="/root/rpmbuild"

usage() {
echo "Usage: $0 [-c container_name]"
echo " -c Container name (default: slurmctl)"
exit 1
}

while getopts ":c:h" o; do
case "${o}" in
c) CONTAINER_NAME="${OPTARG}" ;;
h) usage ;;
*) usage ;;
esac
done

if ! docker inspect -f '{{.State.Running}}' "$CONTAINER_NAME" &>/dev/null; then
echo "Error: Container '$CONTAINER_NAME' is not running."
echo "Start it with: docker compose up -d"
exit 1
fi

# Wait for slurmctld to be ready
echo "Waiting for Slurm controller..."
for i in $(seq 1 30); do
if docker exec "$CONTAINER_NAME" scontrol ping 2>/dev/null | grep -q "UP"; then
echo "Slurm controller is ready."
break
fi
if [ "$i" -eq 30 ]; then
echo "Error: Slurm controller did not become ready in time."
exit 1
fi
sleep 2
done

echo "Installing RPM build dependencies in container '$CONTAINER_NAME'..."
docker exec "$CONTAINER_NAME" bash -c "
set -e
dnf install -y -q rpm-build python3-devel pyproject-rpm-macros \
python3-Cython python3-setuptools python3-wheel
"

# Build sdist if not already present (may have been built by a prior CI step)
if ls dist/*.tar.gz &>/dev/null; then
echo "Using existing sdist in dist/"
else
echo "Building sdist..."
docker exec "$CONTAINER_NAME" bash -c "
set -e
pip install -q build
cd /pyslurm
python -m build --sdist
"
fi

echo "Building RPM..."
docker exec "$CONTAINER_NAME" bash -c "
set -e
mkdir -p ${RPMBUILD_DIR}/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
cp /pyslurm/dist/*.tar.gz ${RPMBUILD_DIR}/SOURCES/
cp /pyslurm/pyslurm.spec ${RPMBUILD_DIR}/SPECS/
rpmbuild -ba ${RPMBUILD_DIR}/SPECS/pyslurm.spec
"

echo "Installing RPM in container '$CONTAINER_NAME'..."
docker exec "$CONTAINER_NAME" bash -c "
set -e
if rpm -q python3-pyslurm &>/dev/null; then
dnf reinstall -y -q ${RPMBUILD_DIR}/RPMS/*/python3-pyslurm-*.rpm
else
dnf install -y -q ${RPMBUILD_DIR}/RPMS/*/python3-pyslurm-*.rpm
fi
"

docker exec -i -w /tmp "$CONTAINER_NAME" python3 - << 'PYEOF'
import pyslurm
print("pyslurm version:", pyslurm.__version__)
from pyslurm import slurmctld
import pprint
conf = slurmctld.Config.load()
pprint.pprint(conf.to_dict())
PYEOF

echo "RPM build and install successful."