Skip to content

fix: apptainer command not recognized when singularity is absent #4010

Merged
johanneskoester merged 1 commit intosnakemake:mainfrom
ManarRashad:fix/issue-3860-apptainer_detection
Mar 11, 2026
Merged

fix: apptainer command not recognized when singularity is absent #4010
johanneskoester merged 1 commit intosnakemake:mainfrom
ManarRashad:fix/issue-3860-apptainer_detection

Conversation

@ManarRashad
Copy link
Copy Markdown
Contributor

@ManarRashad ManarRashad commented Mar 9, 2026

What does this fix?

Closes #3860

Problem

Snakemake only checks for a binary named singularity when using --sdm apptainer. Users who have apptainer installed (but not singularity) get the error:
"The apptainer or singularity command has to be available in order to use apptainer/singularity integration."

Solution

Updated singularity.py to check for both apptainer and singularity binaries, preferring apptainer (the modern name). All hardcoded "singularity" references replaced with the dynamically detected binary name.

Changes

  • snakemake/deployment/singularity.py — Detection checks apptainer first,
    then singularity. Updated check(), pull(), shellcmd(), and __init__() to use the detected binary name.

QC

  • The changes are already covered by an existing test case test_container
  • No documentation update needed — this is a bug fix, not a behavior change.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for apptainer container runtime alongside singularity. The system automatically detects and uses whichever runtime is available on the system.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

The Singularity deployment module now supports automatic detection and selection between apptainer and singularity binaries. The code prioritizes apptainer when available, otherwise falls back to singularity, setting a binary attribute for use throughout command execution and version checking.

Changes

Cohort / File(s) Summary
Singularity Binary Detection
src/snakemake/deployment/singularity.py
Added binary attribute to Singularity class with lazy initialization. Modified check() method to detect apptainer first, then singularity, updating version retrieval and error handling to use the detected binary. Updated shellcmd() to reference the dynamically selected binary instead of hard-coded "singularity" token.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • johanneskoester
  • cademirch
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: recognizing apptainer when singularity is absent.
Linked Issues check ✅ Passed The code changes properly detect and support apptainer as an alternative to singularity, addressing the core requirement to recognize apptainer when singularity is absent [#3860].
Out of Scope Changes check ✅ Passed All changes are scoped to singularity.py and directly address the linked issue requirement to support apptainer binary detection.
Description check ✅ Passed The PR description comprehensively addresses the problem, solution, and changes made. It includes a clear explanation of the issue, the implemented fix, the files modified, and QC checklist completion.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/snakemake/deployment/singularity.py (1)

220-223: Consider updating error message to reflect the detected binary.

The error message says "singularity version" but self.binary could be "apptainer". A minor consistency improvement:

Suggested fix
             except subprocess.CalledProcessError as e:
                 raise WorkflowError(
-                    f"Failed to get singularity version:\n{e.stderr.decode()}"
+                    f"Failed to get {self.binary} version:\n{e.stderr.decode()}"
                 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/snakemake/deployment/singularity.py` around lines 220 - 223, The
exception message always mentions "singularity" though the code uses self.binary
(which may be "apptainer"); update the WorkflowError raised in the except block
(the subprocess.CalledProcessError handler) to reference self.binary dynamically
and include the stderr details — i.e., change the message text from "Failed to
get singularity version" to something like "Failed to get {self.binary} version"
and include e.stderr.decode() as before so the error accurately names the
detected binary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/snakemake/deployment/singularity.py`:
- Around line 142-145: shellcmd() currently reads Singularity().binary without
ensuring detection; call Singularity.check() at the start of shellcmd() so the
singleton detects apptainer/singularity before using Singularity().binary
(replace the direct access with a call sequence that invokes Singularity.check()
and then reads Singularity().binary or falls back). Update any references in the
function that build cmd (the envvars/binary usage) to use the post-check value;
note Image.pull() already calls check() but shellcmd() must be self-sufficient
by invoking Singularity.check() itself.

---

Nitpick comments:
In `@src/snakemake/deployment/singularity.py`:
- Around line 220-223: The exception message always mentions "singularity"
though the code uses self.binary (which may be "apptainer"); update the
WorkflowError raised in the except block (the subprocess.CalledProcessError
handler) to reference self.binary dynamically and include the stderr details —
i.e., change the message text from "Failed to get singularity version" to
something like "Failed to get {self.binary} version" and include
e.stderr.decode() as before so the error accurately names the detected binary.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 318e0497-e609-4763-9e02-a973bf0c3c2b

📥 Commits

Reviewing files that changed from the base of the PR and between b88171c and d164cd5.

📒 Files selected for processing (1)
  • src/snakemake/deployment/singularity.py

@johanneskoester johanneskoester merged commit b8162e2 into snakemake:main Mar 11, 2026
61 checks passed
johanneskoester pushed a commit that referenced this pull request Mar 13, 2026
🤖 I have created a release *beep* *boop*
---


##
[9.17.0](v9.16.3...v9.17.0)
(2026-03-13)


### Features

* Allow storing snakemake metadata in files or databases
([#4012](#4012))
([dd75f31](dd75f31))
* Allow to specify comparison command per-unit test
([#3956](#3956))
([b88171c](b88171c))
* job table orderd topological when run is started
([#4018](#4018))
([75cf506](75cf506))
* lambda functions for priority in rules
([#3253](#3253))
([d2aa226](d2aa226))
* Make on... directive of modules accessible
([#4050](#4050))
([e9f2e1c](e9f2e1c))


### Bug Fixes

* adjust conda tests to not fail on apple silicon; fix
[#4040](#4040)
([#4049](#4049))
([f5b0142](f5b0142))
* allow "--containerize apptainer" to output apptainer format instead of
dockerfile ([#4030](#4030))
([f5cac30](f5cac30))
* apptainer command not recognized when singularity is absent
([#4010](#4010))
([b8162e2](b8162e2))
* capture stderr when tests fail
([#3995](#3995))
([97d74ba](97d74ba))
* **docs:** make Data-dependent conditional execution a complete example
([#4043](#4043))
([3a1d7f2](3a1d7f2))
* don't build the DAG when running unlock. Fixes
[#4000](#4000) and
[#198](#198)
([#4007](#4007))
([acf79fd](acf79fd))
* Ensure pixi tasks may be run as advertised
([#4046](#4046))
([88253c2](88253c2))
* fix checkpoint handling corner cases
([#3870](#3870) and
[#3559](#3559))
([#4015](#4015))
([63f4257](63f4257))
* issue 3642
([#4054](#4054))
([76e6fc2](76e6fc2))
* issue 3815
([#4026](#4026))
([b0eec96](b0eec96))
* logging None in shellcmd context causes error
([#4064](#4064))
([d0652cd](d0652cd))
* lookup function returns default value for empty DataFrame queries
([#4056](#4056))
([f71de97](f71de97))
* make `cache: omit-software` a rule specific property
([#4085](#4085))
([034a9e7](034a9e7))
* reduce number of tests leaving temporary files behind
([#4033](#4033))
([a3a1c97](a3a1c97))
* regression in dynamic resource handling
([#4038](#4038))
([f2c554a](f2c554a))
* somewhat shorter announce message
([#4080](#4080))
([57efc71](57efc71))


### Performance Improvements

* switch reretry with tenacity; decouple container classes (with Python
3.7 compat for old scripts) from rest of the codebase (enabling moving
to newer python versions)
([#4032](#4032))
([ffb19e7](ffb19e7))


### Documentation

* Add AI-assisted contributions policy to contributing guidelines
([#4051](#4051))
([dd70526](dd70526))
* **codebase:** Update & simplify plugin architecture section
([#4052](#4052))
([176cf63](176cf63))
* Correct workflow.source_path() description in documentation
([#4036](#4036))
([45883c5](45883c5))
* fixed wrong code example for collect() function
([#4037](#4037))
([5c85ed8](5c85ed8))
* Minor docs improvements
([#4089](#4089))
([29ea226](29ea226))
* switch to sphinx_design for tabs
([#3976](#3976))
([9674614](9674614))
* typo in the migration table breaking a pip install command
([#4024](#4024))
([66f9dda](66f9dda))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apptainer not recognized but singular command is

2 participants