feat: add Slurm command client and renderer - #892
Conversation
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Greptile SummaryThe PR adds a structured Slurm command boundary and deterministic batch-script renderer for the first scheduler execution slice.
|
| Filename | Overview |
|---|---|
| packages/data-designer-slurm/src/data_designer/slurm/launcher/client.py | Adds typed, argument-vector operations for Slurm submission, observation, inventory, and cancellation with normalized command failures. |
| packages/data-designer-slurm/src/data_designer/slurm/launcher/parsing.py | Adds strict parsing and normalization for scheduler identifiers, states, exit codes, submissions, and GPU GRES output. |
| packages/data-designer-slurm/src/data_designer/slurm/launcher/renderer.py | Adds deterministic batch rendering with validated directives, shell-safe values, integrity checks, and attempt-specific paths. |
| packages/data-designer-slurm/src/data_designer/slurm/launcher/runner.py | Adds bounded subprocess execution with a minimal locale-stable environment; the two previously reported default-PATH failures are fixed at current HEAD. |
| packages/data-designer-slurm/tests/slurm_test_fakes/slurm.py | Extends deterministic scheduler fakes to mirror the new production command formats. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Plan[Resolved Slurm run plan] --> Renderer[Batch script renderer]
Renderer --> Script[Deterministic sbatch script]
Client[Slurm command client] --> Runner[Bounded subprocess runner]
Runner --> Slurm[Slurm CLI tools]
Slurm --> Parsers[Strict output parsers]
Parsers --> Records[Typed scheduler records]
Client --> Script
Reviews (3): Last reviewed commit: "fix: fall back from empty command path" | Re-trigger Greptile
| raise ValueError("environment names must be non-empty and must not contain '=' or NUL") | ||
| if type(value) is not str or "\0" in value: | ||
| raise ValueError("environment values must not contain NUL") | ||
| self._environment = MappingProxyType({**explicit_environment, "LC_ALL": "C"}) |
There was a problem hiding this comment.
Default environment loses Slurm PATH
If a cluster installs Slurm outside the platform fallback path, the default runner replaces the configured environment with only LC_ALL=C while using bare executable names, causing every default client operation to fail with SlurmCommandError even though the tools are available through the caller's PATH.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/data-designer-slurm/src/data_designer/slurm/launcher/runner.py
Line: 43
Comment:
**Default environment loses Slurm PATH**
If a cluster installs Slurm outside the platform fallback path, the default runner replaces the configured environment with only `LC_ALL=C` while using bare executable names, causing every default client operation to fail with `SlurmCommandError` even though the tools are available through the caller's `PATH`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Fixed in bb5bc8e. The default runner now forwards only the caller's PATH plus LC_ALL=C; an explicitly supplied environment remains an exact replacement. This preserves cluster command discovery without unrestricted ambient-environment forwarding. The environment regression coverage and the full Slurm suite pass (490 tests after the follow-up fix).
Preserve the caller's PATH as the only ambient lookup input for default Slurm commands while continuing to isolate all other environment variables. Normalize oversized numeric scheduler fields into the launcher parse-error boundary. Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
| if type(timeout_seconds) not in {int, float} or not math.isfinite(timeout_seconds) or timeout_seconds <= 0: | ||
| raise ValueError("timeout_seconds must be a finite positive number") | ||
| explicit_environment = ( | ||
| dict(environment) if environment is not None else {"PATH": os.environ.get("PATH", os.defpath)} |
There was a problem hiding this comment.
Empty PATH bypasses fallback resolution
If the parent environment contains PATH="", os.environ.get preserves the empty value instead of using os.defpath. The default client's bare Slurm executable names then cannot resolve, causing every operation to fail with SlurmCommandError even when the tools are installed in a platform fallback directory.
| dict(environment) if environment is not None else {"PATH": os.environ.get("PATH", os.defpath)} | |
| dict(environment) if environment is not None else {"PATH": os.environ.get("PATH") or os.defpath} |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/data-designer-slurm/src/data_designer/slurm/launcher/runner.py
Line: 39
Comment:
**Empty PATH bypasses fallback resolution**
If the parent environment contains `PATH=""`, `os.environ.get` preserves the empty value instead of using `os.defpath`. The default client's bare Slurm executable names then cannot resolve, causing every operation to fail with `SlurmCommandError` even when the tools are installed in a platform fallback directory.
```suggestion
dict(environment) if environment is not None else {"PATH": os.environ.get("PATH") or os.defpath}
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Fixed in ca308e2 by falling back to os.defpath when the ambient PATH is absent or empty. Added a regression test for an empty PATH; the full Slurm suite passes (490 tests), and Slurm lint and formatting checks pass.
Use the platform default search path when the ambient PATH is absent or empty so bare Slurm executables remain resolvable. Part of #868 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
📋 Summary
Adds the first independently reviewable #868 slice: a structured Slurm command boundary and deterministic thin batch renderer. This gives M0 a plan-to-script proof and supplies the scheduler primitives needed by #867 without pulling allocation runtime or persistence policy into this PR.
🔗 Related Issue
Part of #868
🔄 Changes
sbatch,squeue,sacct,scancel, and boundedsinfooperations with exact argv construction, minimal environments, timeouts, normalized errors, and returned-selector correlation.🔍 Attention Areas
client.py— managed-selector correlation and the--export=NILsubmission boundary.renderer.py— directive/resource semantics and checksum-before-source ordering.🧪 Testing
make testpasses — 4,564 passed, 1 skippedmake check-allpassesmake test-slurm-wheel-installpasses✅ Checklist