Skip to content

Commit 095ab18

Browse files
authored
Merge pull request #397 from singularityhub/updates/notation
Updates to several container and module bases
2 parents f34149b + 2d43610 commit 095ab18

File tree

21 files changed

+125
-73
lines changed

21 files changed

+125
-73
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ jobs:
3838
pyflakes shpc/main/modules
3939
pyflakes shpc/main/container/base.py
4040
pyflakes shpc/main/container/podman.py
41+
pyflakes shpc/main/container/docker.py
4142
pyflakes shpc/main/container/singularity.py

.github/workflows/test.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ jobs:
7373
shpc config set container_tech:${{ matrix.container_tech }}
7474
shpc config set module_sys:${{ matrix.module }}
7575
shpc config set enable_tty:false
76+
77+
printf "\n\shpc test ============================================\n"
78+
shpc test python:3.9.5-alpine
79+
7680
shpc install python:3.9.5-alpine
7781
7882
module use ./modules
@@ -96,7 +100,8 @@ jobs:
96100
cat test_output
97101
grep --quiet 'Python 3.9.5' test_output
98102
rm test_output
99-
103+
shpc uninstall --force python:3.9.5-alpine
104+
100105
- name: Run python module tests (tcsh)
101106
shell: tcsh -e {0}
102107
run: |
@@ -114,6 +119,7 @@ jobs:
114119
shpc config set container_tech:${{ matrix.container_tech }}
115120
shpc config set module_sys:${{ matrix.module }}
116121
shpc config set enable_tty:false
122+
117123
shpc install python:3.9.5-alpine
118124
119125
module use ./modules
@@ -137,3 +143,4 @@ jobs:
137143
cat test_output
138144
grep --quiet 'Python 3.9.5' test_output
139145
rm test_output
146+
shpc uninstall --force python:3.9.5-alpine

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ and **Merged pull requests**. Critical items to know are:
1414
The versions coincide with releases on pip. Only major versions will be released as tags on Github.
1515

1616
## [0.0.x](https://github.scom/singularityhub/singularity-hpc/tree/master) (0.0.x)
17+
- Add test for docker and podman (0.0.28)
18+
- namespace as format string for command named renamed to repository
19+
- shpc test/uninstall should be run for all tests
20+
- bug with uninstall
21+
- adding user and group ids to docker and podman commands
22+
- remove conflict with entire module name, should only be for aliases
23+
- fix documentation of commands in Lua module template
1724
- Cleanup of module files and docker requirement bugfix (0.0.27)
1825
- Docker support (0.0.26)
1926
- added an enable_tty setting to allow disabling add -t in recipes

docs/getting_started/user-guide.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ A summary table of variables is included below, and then further discussed in de
139139
- if defined, add to module script to load this Singularity module first
140140
- null
141141
* - module_name
142-
- Format string for module commands exec,shell,run (not aliases) can include ``{{ registry }}``, ``{{ namespace }}``, ``{{ tool }}`` and ``{{ version }}``
142+
- Format string for module commands exec,shell,run (not aliases) can include ``{{ registry }}``, ``{{ repository }}``, ``{{ tool }}`` and ``{{ version }}``
143143
- ``{{ tool }}``
144144
* - bindpaths
145145
- string with comma separated list of paths to binds. If set, expored to SINGULARITY_BINDPATH
@@ -305,12 +305,12 @@ A container identifier is parsed as follows:
305305
.. code-block:: console
306306
307307
# quay.io /biocontainers/samtools:latest
308-
# <registry>/ <namespace>/ <tool>/<version>
308+
# <registry>/ <repository>/ <tool>/<version>
309309
310310
311311
So by default, we use tool because it's likely closest to the command that is wanted.
312312
But let's say you had two versions of samtools - the namespaces would conflict! You
313-
would want to change your format string to ``{{ namespace }}-{{ tool }}`` to be
313+
would want to change your format string to ``{{ repository }}-{{ tool }}`` to be
314314
perhaps "biocontainers-samtools-exec" and "another-samtools-exec."
315315
If you change the format string to ``{{ tool }}-{{ version }}`` you would see:
316316

paper/paper.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ bibliography: paper.bib
2525

2626
Portability and reproducibility of complex software stacks is essential for researchers to perform their work. High Performance Computing (HPC) environments add another level of complexity, where possibly conflicting dependencies must co-exist. Although container technologies like Singularity [@Kurtzer2017-xj] make it possible to "bring your own environment," without any form of central strategy to manage containers, researchers that seek reproducibility via using containers are tasked with managing their own container collection, often not taking care to ensure that a particular digest or version is used. The reproducibility of the work is at risk, as they cannot easily install and use containers, nor can they share their software with others.
2727

28-
Singularity Registry HPC (shpc) is the first of its kind to provide an easy means for a researcher to add their research software for sharing and collaboration with other researchers to an existing collection of over 200 popular scientific libraries [@da2017biocontainers; @noauthor_undated-kp, @gorgolewski2017bids; @gamblin2015spack; @autamus]. The software installs these containers as environment modules [@McLay2011-wu] that are easy to use and read documentation for, and exposes aliases for commands in the container that the researcher can add to his or her pipeline without thinking about complex interactions with a container. The simple addition of an entry to the registry maintained by shpc comes down to adding a yaml file, and after doing this, another researcher can easily install the same software, down to the digest, to reproduce the original work.
28+
Singularity Registry HPC (shpc) is the first of its kind to provide an easy means for a researcher to add their research software for sharing and collaboration with other researchers to an existing collection of over 200 popular scientific libraries [@da2017biocontainers; @noauthor_undated-kp, @gorgolewski2017bids; @gamblin2015spack; @autamus]. The software installs containers as environment modules [@McLay2011-wu] that are easy to use and read documentation for, and exposes aliases for commands in the container that the researcher can add to his or her pipeline without thinking about complex interactions with a container. The simple addition of an entry to the registry maintained by shpc comes down to adding a yaml file, and after doing this, another researcher can easily install the same software, down to the digest, to reproduce the original work.
2929

3030

3131
## Statement of Need
3232

3333
Using environment modules [@McLay2011-wu] on HPC clusters is a common
3434
trend. Although writing the recipes can be complex, it's a fairly common practice for cluster administrators to provide
35-
a set of natively installed recipes for their users [@noauthor_undated-bt], or for researchers to develop and deploy their own software via containers. Even well-known package managers like Spack [@noauthor_undated-ae] and EasyBuild [@noauthor_undated-dj] expose software as modules. However, these package manager approaches don't always ensure reproducibility, or ease of development for the researcher. They typically require relying on some subset of system software, the underlying operating system, or even making changes to the system, which is not under the researcher's control. Although using containers in this context has been discussed previously [@noauthor_undated-rj; @noauthor_undated-rc], the majority of these approaches and tools do not make the process of developing and installing container modules easy. The single researcher must either convince a cluster administrator to install dependencies needed for their software, or build a container and manually move and interact with it on the cluster. All of these small challenges come together to make it harder for a researcher to develop and manage their own software, and subsequently to share their approach to reproduce the work. Using Singularity containers installed via Singularity Registry HPC offers a solution to this challenge. The only requirement is the Singularity software, and writing a simple configuration file for the registry. By clearly defining commands, and pinning exact versions of scientific software, researchers on high performance computing
35+
a set of natively installed recipes for their users [@noauthor_undated-bt], or for researchers to develop and deploy their own software via containers. Even well-known package managers like Spack [@noauthor_undated-ae] and EasyBuild [@noauthor_undated-dj] expose software as modules. However, these package manager approaches don't always ensure reproducibility, or ease of development for the researcher. They typically require relying on some subset of system software, the underlying operating system, or even making changes to the system, which is not under the researcher's control. Although using containers in this context has been discussed previously [@noauthor_undated-rj; @noauthor_undated-rc], the majority of these approaches and tools do not make the process of developing and installing container modules easy. The single researcher must either convince a cluster administrator to install dependencies needed for their software, or build a container and manually move and interact with it on the cluster. All of these small challenges come together to make it harder for a researcher to develop and manage their own software, and subsequently to share their approach to reproduce the work. Using Singularity, Podman, or other container technologies installed via Singularity Registry HPC offers a solution to this challenge. The only requirement is the container technology software, and writing a simple configuration file for the registry. By clearly defining commands, and pinning exact versions of scientific software, researchers on high performance computing
3636
clusters can have more confidence in the reproducibility of their work [@Santana-Perez2015-wo; @Boettiger2014-cz; @Wandell2015-yt].
3737

3838
## Usage

shpc/client/config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ def main(args, parser, extra, subparser):
1010

1111
from shpc.main import get_client
1212

13-
cli = get_client(quiet=args.quiet, settings_file=args.settings_file)
14-
1513
# If nothing provided, show help
1614
if not args.params:
1715
print(subparser.format_help())
@@ -20,6 +18,11 @@ def main(args, parser, extra, subparser):
2018
# The first "param" is either set of get
2119
command = args.params.pop(0)
2220

21+
validate = True if not command == "edit" else False
22+
cli = get_client(
23+
quiet=args.quiet, settings_file=args.settings_file, validate=validate
24+
)
25+
2326
# For each new setting, update and save!
2427
if command == "edit":
2528
return cli.settings.edit()

shpc/main/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ def get_client(quiet=False, **kwargs):
2121
"""
2222
# The name of the module
2323
module = kwargs.get("module")
24+
validate = kwargs.get("validate", True)
2425

2526
# Load user settings to add to client, and container technology
26-
settings = Settings(kwargs.get("settings_file"))
27+
settings = Settings(kwargs.get("settings_file"), validate)
2728
container = kwargs.get("container_tech") or settings.container_tech
2829

2930
# Use the user provided module OR the default

shpc/main/client.py

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,7 @@ def cleanup(tmpdir):
141141
# Test all tags (this could be subsetted)
142142
for tag in tags:
143143

144-
# Install the recipe
145-
sif = self.install(module_name, tag)
146-
147-
# Assert that the container exists
148-
assert os.path.exists(sif)
144+
image = self.install(module_name, tag)
149145

150146
# Do we want to test loading?
151147
if not skip_module and hasattr(self, "_test"):
@@ -157,27 +153,17 @@ def cleanup(tmpdir):
157153
# Do we want to test the test commands?
158154
if test_commands and config.test:
159155
utils.write_file(test_file, config.test)
160-
command = ["singularity", "exec", sif, "/bin/bash", test_file]
161-
result = utils.run_command(command)
162-
163-
# We can't run on incompatible hosts
164-
if (
165-
"the image's architecture" in result["message"]
166-
and result["return_code"] != 0
167-
):
168-
logger.warning(
169-
"Cannot run test for container with incompatible architecture: %s"
170-
% result["message"]
171-
)
172-
elif result["return_code"] != 0:
156+
return_code = self.container.test_script(image, test_file)
157+
if return_code != 0:
173158
cleanup(tmpdir)
174159
logger.exit("Test of %s was not successful." % module_name)
175160

176161
# Test the commands
177162
if not test_exec:
178163
continue
164+
179165
for alias in config.get_aliases():
180-
result = self._container.client.execute(sif, alias["command"])
166+
result = self.client.execute(image, alias["command"])
181167

182168
# Cleanup the test install
183169
if stage:

shpc/main/container/base.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ContainerName:
2020
def __init__(self, raw):
2121
self.raw = raw
2222
self.registry = None
23-
self.namespace = None
23+
self.repository = None
2424
self.tool = None
2525
self.version = None
2626
self.digest = None
@@ -90,13 +90,17 @@ def container_dir(self, name):
9090
return os.path.join(self.settings.module_base, name)
9191
return os.path.join(self.settings.container_base, name)
9292

93-
def guess_tag(self, module_name):
94-
"""If a user asks for a name without a tag, try to figure it out."""
93+
def guess_tag(self, module_name, allow_fail=False):
94+
"""
95+
If a user asks for a name without a tag, try to figure it out.
96+
"""
9597
if ":" in module_name:
9698
return module_name
9799
tags = os.listdir(os.path.join(self.settings.module_base, module_name))
98-
if not tags:
100+
if not tags and allow_fail:
99101
logger.exit("%s does not have any tags installed." % module_name)
102+
elif (tags or len(tags) > 1) and allow_fail:
103+
return
100104
elif len(tags) > 1:
101105
logger.exit(
102106
"Multiple tags found for %s: %s." % (module_name, ", ".join(tags))

shpc/main/container/docker.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,13 @@ def get(self, module_name):
9999
Determine if a container uri exists.
100100
"""
101101
# If no module tag provided, try to deduce from install tree
102-
module_name = self.guess_tag(module_name)
102+
full_name = self.guess_tag(module_name, allow_fail=True)
103103

104-
uri = self.add_registry(module_name)
104+
# The user already provided a tag
105+
if not full_name:
106+
full_name = module_name
107+
108+
uri = self.add_registry(full_name)
105109
# If there isn't a tag in the name, add it back
106110
if ":" not in uri:
107111
uri = ":".join(uri.rsplit("/", 1))
@@ -132,6 +136,25 @@ def check(self, module_name, config):
132136
% (module_name, config.latest.name)
133137
)
134138

139+
def test_script(self, image, test_script):
140+
"""
141+
Given a test file, run it and respond accordingly.
142+
"""
143+
command = [
144+
"docker",
145+
"run",
146+
"-i",
147+
"--entrypoint",
148+
"/bin/bash",
149+
"-t",
150+
image,
151+
test_script,
152+
]
153+
result = shpc.utils.run_command(command)
154+
155+
# Return code
156+
return result["return_code"]
157+
135158
def install(
136159
self,
137160
module_path,
@@ -190,7 +213,7 @@ def install(
190213
name=name,
191214
tool=parsed_name.tool,
192215
registry=parsed_name.registry,
193-
namespace=parsed_name.namespace,
216+
repository=parsed_name.repository,
194217
envfile=self.settings.environment_file,
195218
command=self.command,
196219
tty=self.settings.enable_tty,

0 commit comments

Comments
 (0)