Skip to content

Commit

Permalink
Add --account and --job-name to slurm submission
Browse files Browse the repository at this point in the history
Refs #105
  • Loading branch information
sverhoeven committed Oct 22, 2024
1 parent 6bb29cf commit 15707da
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ A destination has its own authentication mechanism.
When a job is submitted by any user of the web service,
it will be executed by the username/proxy that is configured in the destination.

For allowed configuration options see the [API reference](https://i-vresse-bartender.readthedocs.io/en/latest/autoapi/bartender).

### Example of running jobs on the local system

```yaml
Expand Down
4 changes: 4 additions & 0 deletions src/bartender/schedulers/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class JobDescription(BaseModel):
job_dir: Path
# Command to run
command: str
# Application name
application: str = ""
# User that submitted the job
submitter: str = ""


class JobSubmissionError(Exception):
Expand Down
18 changes: 14 additions & 4 deletions src/bartender/schedulers/slurm.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ class SlurmSchedulerConfig(BaseModel):
extra_options: Escape hatch to add extra options to job script.
The string `#SBATCH {extra_options[i]}` will be appended to job
script.
submitter_as_account: Use the submitter as the account to run the job.
"""

type: Literal["slurm"] = "slurm"
ssh_config: Optional[SshConnectConfig] = None
partition: Optional[str] = None
time: Optional[str] = None
extra_options: Optional[list[str]] = None
submitter_as_account: Optional[bool] = False


class SlurmScheduler(AbstractScheduler):
Expand All @@ -80,9 +82,10 @@ def __init__(self, config: SlurmSchedulerConfig):
self.extra_options = []
else:
self.extra_options = config.extra_options
self.submitter_as_account = config.submitter_as_account

async def submit(self, description: JobDescription) -> str: # noqa: D102):
# TODO if runner is a SSHCommandRunner then description.jobdir
# if runner is a SSHCommandRunner then description.jobdir
# must be on a shared filesystem or remote filesystem
script = self._submit_script(description)
command = "sbatch"
Expand Down Expand Up @@ -167,14 +170,19 @@ async def _state_from_accounting(self, job_id: str) -> str:
)
return stdout

def _submit_script(self, description: JobDescription) -> str:
def _submit_script(self, description: JobDescription) -> str: # noqa: WPS210
partition_line = ""
if self.partition:
partition_line = f"#SBATCH --partition={self.partition}"
time_line = ""
if self.time:
time_line = f"#SBATCH --time={self.time}"

account_line = ""
if description.submitter != "" and self.submitter_as_account:
account_line = f"#SBATCH --account={description.submitter}"
job_name_line = ""
if description.application != "":
job_name_line = f"#SBATCH --job-name={description.application}"
# TODO filter out options already set
extra_option_lines = "\n".join(
[f"#SBATCH {extra}" for extra in self.extra_options],
Expand All @@ -184,9 +192,11 @@ def _submit_script(self, description: JobDescription) -> str:
{extra_option_lines}
{partition_line}
{time_line}
{account_line}
{job_name_line}
#SBATCH --output=stdout.txt
#SBATCH --error=stderr.txt
{description.command}
echo -n $? > returncode
"""
""" # noqa: WPS221
return dedent(script)
19 changes: 17 additions & 2 deletions src/bartender/web/api/applications/submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def build_description(
job_dir: Path,
payload: dict[str, str],
config: ApplicatonConfiguration,
application: str = "",
submitter: str = "",
) -> JobDescription:
"""
Builds a job description.
Expand All @@ -21,13 +23,20 @@ def build_description(
job_dir: The directory where the job will be executed.
payload: The payload containing the non-file input data for the job.
config: The configuration for the application.
application: The name of the application.
submitter: The user who submitted the job.
Returns:
Job description containing the job directory and command.
"""
template = template_environment.from_string(config.command_template)
command = template.render(**payload)
return JobDescription(job_dir=job_dir, command=command)
return JobDescription(
job_dir=job_dir,
command=command,
application=application,
submitter=submitter,
)


async def submit( # noqa: WPS211
Expand All @@ -50,7 +59,13 @@ async def submit( # noqa: WPS211
job_dao: JobDAO object.
context: Context with applications and destinations.
"""
description = build_description(job_dir, payload, context.applications[application])
description = build_description(
job_dir,
payload,
context.applications[application],
application,
submitter.username,
)

destination_name = context.destination_picker(
job_dir,
Expand Down
2 changes: 2 additions & 0 deletions tests/schedulers/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def prepare_input(job_dir: Path) -> JobDescription:
return JobDescription(
command="echo -n hello && wc input > output",
job_dir=job_dir,
submitter="test",
application="hellowc",
)


Expand Down

0 comments on commit 15707da

Please sign in to comment.