Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
6 changes: 4 additions & 2 deletions snakemake_executor_plugin_slurm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
)
from .efficiency_report import create_efficiency_report
from .submit_string import get_submit_command
from .validation import validate_slurm_extra
from .validation import validate_slurm_job_id, validate_slurm_extra


@dataclass
Expand Down Expand Up @@ -382,8 +382,10 @@ def run_job(self, job: JobExecutorInterface):
# To extract the job id we split by semicolon and take the first element
# (this also works if no cluster name was provided)
slurm_jobid = out.strip().split(";")[0]
# this slurm_jobid might be wrong: some cluster admin give convulted
# sbatch outputs. So we need to validate it properly:
if not slurm_jobid:
raise WorkflowError("Failed to retrieve SLURM job ID from sbatch output.")
slurm_jobid = validate_slurm_job_id(slurm_jobid, out)
slurm_logfile = slurm_logfile.with_name(
slurm_logfile.name.replace("%j", slurm_jobid)
)
Expand Down
34 changes: 34 additions & 0 deletions snakemake_executor_plugin_slurm/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,43 @@
"""

import re
import subprocess
from snakemake_interface_common.exceptions import WorkflowError


def validate_slurm_job_id(job_id, output):
"""
Validate that the SLURM job ID is a positive integer.
Args:
job_id (str): The SLURM job ID to validate.
Raises:
WorkflowError: If the job ID is not a positive integer or we cannot
determine a valid job ID from the given input string.
"""
if re.match(r"^\d+$", job_id):
return job_id
else:
# try matching a positive integer, raise an error if more than one match or no match found
# Match standalone integers, excluding those followed by %, letters, or digits (units/percentages/floats)
# Allows format: "1234" or "1234; clustername" (SLURM multi-cluster format)

# If the first attempt to validate the job fails, try parsing the sbatch output
# a bit more sophisticatedly:
matches = re.findall(r"\b\d+(?![%A-Za-z\d.])", output)
if len(matches) == 1:
return matches[0]
elif len(matches) > 1:
raise WorkflowError(
f"Multiple possible SLURM job IDs found in: {output}. Was looking for exactly one positive integer."
)
elif not matches:
raise WorkflowError(
f"No valid SLURM job ID found in: {output}. Was looking for exactly one positive integer."
)


def get_forbidden_slurm_options():
"""
Return a dictionary of forbidden SLURM options that the executor manages.
Expand Down
Loading