Skip to content

Commit c8f9c99

Browse files
committed
adding support for custom environment file
Signed-off-by: vsoch <[email protected]>
1 parent d70803e commit c8f9c99

File tree

11 files changed

+106
-16
lines changed

11 files changed

+106
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The versions coincide with releases on pip. Only major versions will be released
1515

1616
## [0.0.x](https://github.com/singularityhub/singularity-hpc/tree/master) (0.0.x)
1717
- adding namespaces to make module install, show, inspect easier (0.0.24)
18+
- added support for env section to render to bound environment file
1819
- container url does not render in docs (0.0.23)
1920
- addition of tcl modules, removal of un-needed database (0.0.22)
2021
- first update of all containers, and bugfix to pull (0.0.21)

docs/getting_started/user-guide.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ A summary table of variables is included below, and then further discussed in de
209209
* - namespace
210210
- Set a default module namespace that you want to install from.
211211
- null
212+
* - environment_file
213+
- The name of the environment file to generate and bind to the container.
214+
- 99-shpc.sh
212215

213216

214217

@@ -721,6 +724,7 @@ bypython (per what is available on your system). To start a shell:
721724
722725
$ shpc shell
723726
727+
724728
or with a specific interpreter:
725729

726730
.. code-block:: console
@@ -938,6 +942,51 @@ that since we have a list, you technically could provide duplicate commands.
938942
However, the list is parsed into a dictionary, so only unique values are
939943
enforced. If you accidentally have a repeated value, a warning will be printed.
940944

945+
Environment Variables
946+
---------------------
947+
948+
949+
Finally, each recipe has an optional section for environment variables. For
950+
example, the container ``vanessa/salad`` shows definition of one environment
951+
variable:
952+
953+
.. code-block:: yaml
954+
955+
docker: vanessa/salad
956+
url: https://hub.docker.com/r/vanessa/salad
957+
maintainer: '@vsoch'
958+
description: A container all about fork and spoon puns.
959+
latest:
960+
latest: sha256:e8302da47e3200915c1d3a9406d9446f04da7244e4995b7135afd2b79d4f63db
961+
tags:
962+
latest: sha256:e8302da47e3200915c1d3a9406d9446f04da7244e4995b7135afd2b79d4f63db
963+
aliases:
964+
salad: /code/salad
965+
env:
966+
maintainer: vsoch
967+
968+
And then during build, this variable is written to a ``99-shpc.sh`` file that
969+
is mounted into the countainer. For the above, the following will be written:
970+
971+
.. code-block:: console
972+
973+
export maintainer=vsoch
974+
975+
If a recipe does not have environment variables in the container.yaml, you have
976+
two options for adding a variable after install. For a more permanent solution,
977+
you can update the container.yaml file and install again. The container won't
978+
be re-pulled, but the environment file will be re-generated. If you want to
979+
manually add them to the container, each module folder will have an environment
980+
file added regardless of having this section or not, so you can export them there.
981+
When you shell, exec, or run the container (all but inspect) you should be able
982+
to see your environment variables:
983+
984+
.. code-block:: console
985+
986+
$ echo $maintainer
987+
vsoch
988+
989+
941990
Singularity Deploy
942991
------------------
943992

registry/vanessa/salad/container.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ tags:
88
latest: sha256:e8302da47e3200915c1d3a9406d9446f04da7244e4995b7135afd2b79d4f63db
99
aliases:
1010
salad: /code/salad
11+
env:
12+
maintainer: vsoch

shpc/main/container.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ def validate(self):
214214
"""
215215
jsonschema.validate(instance=self._config, schema=schemas.containerConfig)
216216

217+
def get_envars(self):
218+
"""
219+
Return loaded environment variables.
220+
"""
221+
return dict(self.env) if self.env else {}
222+
217223
def get_aliases(self):
218224
"""
219225
Return a consistently formatted list of aliases

shpc/main/lmod/template.lua

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ Container:
1616
Commands include:
1717
1818
- {{ prefix }}{{ flatname }}-run:
19-
singularity run {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>
19+
singularity run {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>
2020
- {{ prefix }}{{ flatname }}-shell:
21-
singularity shell -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>
21+
singularity shell -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>
2222
- {{ prefix }}{{ flatname }}-exec:
23-
singularity exec -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container> "$@"
23+
singularity exec -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container> "$@"
2424
- {{ prefix }}{{ flatname }}-inspect-runscript:
2525
singularity inspect -r <container>
2626
- {{ prefix }}{{ flatname }}-inspect-deffile:
2727
singularity inspect -d <container>
2828
2929
{% if aliases %}{% for alias in aliases %} - {{ alias.name }}:
30-
singularity exec {% if bindpaths %}-B {{ bindpaths }} {% endif %}{% if alias.options %}{{ alias.options }} {% endif %}<container> {{ alias.command }}
31-
{% endfor %}{% else %} - {{ prefix }}{{ flatname }}: singularity run {% if bindpaths %}-B {{ bindpaths }}{% endif %}<container>{% endif %}
30+
singularity exec {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}{% if alias.options %}{{ alias.options }} {% endif %}<container> {{ alias.command }}
31+
{% endfor %}{% else %} - {{ prefix }}{{ flatname }}: singularity run {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %}<container>{% endif %}
3232
3333
For each of the above, you can export:
3434
@@ -47,9 +47,9 @@ setenv("SINGULARITY_SHELL", "{{ singularity_shell }}")
4747

4848
-- interactive shell to any container, plus exec for aliases
4949
local containerPath = '{{ container_sif }}'
50-
local shellCmd = "singularity ${SINGULARITY_OPTS} shell ${SINGULARITY_COMMAND_OPTS} -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }}{% endif %} " .. containerPath
51-
local execCmd = "singularity ${SINGULARITY_OPTS} exec ${SINGULARITY_COMMAND_OPTS} {% if bindpaths %}-B {{ bindpaths }}{% endif %} "
52-
local runCmd = "singularity ${SINGULARITY_OPTS} run ${SINGULARITY_COMMAND_OPTS} {% if bindpaths %}-B {{ bindpaths }}{% endif %} " .. containerPath .. " ${ SINGULARITY_COMMAND_ARGS }"
50+
local shellCmd = "singularity ${SINGULARITY_OPTS} shell ${SINGULARITY_COMMAND_OPTS} -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} " .. containerPath
51+
local execCmd = "singularity ${SINGULARITY_OPTS} exec ${SINGULARITY_COMMAND_OPTS} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} "
52+
local runCmd = "singularity ${SINGULARITY_OPTS} run ${SINGULARITY_COMMAND_OPTS} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} " .. containerPath .. " ${ SINGULARITY_COMMAND_ARGS }"
5353
local inspectCmd = "singularity ${SINGULARITY_OPTS} inspect ${SINGULARITY_COMMAND_OPTS} "
5454

5555
-- set_shell_function takes bashStr and cshStr

shpc/main/modules.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from datetime import datetime
88
import shpc.utils as utils
99
import shpc.defaults as defaults
10+
import shpc.main.templates
1011
from jinja2 import Template
1112

1213
from glob import glob
@@ -389,6 +390,7 @@ def install(self, name, tag=None):
389390

390391
# prepare aliases
391392
aliases = config.get_aliases()
393+
envars = config.get_envars()
392394

393395
self._install(
394396
module_dir,
@@ -399,9 +401,20 @@ def install(self, name, tag=None):
399401
description=config.description,
400402
version=tag.name,
401403
)
404+
405+
# Write the environment file to be bound to the container
406+
self._add_environment(module_dir, envars)
402407
logger.info("Module %s/%s was created." % (config.name, tag.name))
403408
return container_path
404409

410+
def _add_environment(self, module_dir, envars):
411+
"""
412+
Given one or more environment variables in a dictionary, write to file
413+
"""
414+
out = Template(shpc.main.templates.environment_file).render(envars=envars)
415+
env_file = os.path.join(module_dir, self.settings.environment_file)
416+
utils.write_file(env_file, out)
417+
405418
def _install(
406419
self,
407420
module_dir,
@@ -461,5 +474,6 @@ def _install(
461474
creation_date=datetime.now(),
462475
name=name,
463476
flatname=name.replace("/", "-"),
477+
envfile=self.settings.environment_file,
464478
)
465479
utils.write_file(module_path, out)

shpc/main/schemas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"type": "array",
5858
"items": {"type": "string"},
5959
},
60+
"env": aliases,
6061
"aliases": {
6162
"oneOf": [
6263
aliases,

shpc/main/tcl/template.tcl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ proc ModulesHelp { } {
1414
puts stderr " - {{ container_sif }}"
1515
puts stderr "Commands include:"
1616
puts stderr " - {{ prefix }}{{ flatname }}-run:"
17-
puts stderr " singularity run {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>"
17+
puts stderr " singularity run {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>"
1818
puts stderr " - {{ prefix }}{{ flatname }}-shell:"
19-
puts stderr " singularity shell -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>"
19+
puts stderr " singularity shell -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container>"
2020
puts stderr " - {{ prefix }}{{ flatname }}-exec:"
21-
puts stderr " singularity exec -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container> \"$@\""
21+
puts stderr " singularity exec -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}<container> \"$@\""
2222
puts stderr " - {{ prefix }}{{ flatname }}-inspect-runscript:"
2323
puts stderr " singularity inspect -r <container>"
2424
puts stderr " - {{ prefix }}{{ flatname }}-inspect-deffile:"
2525
puts stderr " singularity inspect -d <container>"
2626

2727
{% if aliases %}{% for alias in aliases %} puts stderr " - {{ alias.name }}:"
28-
puts stderr " singularity exec {% if bindpaths %}-B {{ bindpaths }} {% endif %}{% if alias.options %}{{ alias.options }} {% endif %}<container> {{ alias.command }}"
29-
{% endfor %}{% else %} puts stderr " - {{ prefix }}{{ flatname }}: singularity run {% if bindpaths %}-B {{ bindpaths }}{% endif %}<container>"{% endif %}
28+
puts stderr " singularity exec {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }} {% endif %}{% if alias.options %}{{ alias.options }} {% endif %}<container> {{ alias.command }}"
29+
{% endfor %}{% else %} puts stderr " - {{ prefix }}{{ flatname }}: singularity run {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %}<container>"{% endif %}
3030

3131
puts stderr "For each of the above, you can export:"
3232

@@ -58,9 +58,9 @@ conflict {{ name }}
5858
setenv SINGULARITY_SHELL {{ singularity_shell }}
5959

6060
# interactive shell to any container, plus exec for aliases
61-
set shellCmd "singularity \${SINGULARITY_OPTS} shell \${SINGULARITY_COMMAND_OPTS} -s {{ singularity_shell }} {% if bindpaths %}-B {{ bindpaths }}{% endif %} ${containerPath}"
62-
set execCmd "singularity \${SINGULARITY_OPTS} exec \${SINGULARITY_COMMAND_OPTS} {% if bindpaths %}-B {{ bindpaths }}{% endif %} "
63-
set runCmd "singularity \${SINGULARITY_OPTS} run \${SINGULARITY_COMMAND_OPTS} {% if bindpaths %}-B {{ bindpaths }}{% endif %} ${containerPath} \${SINGULARITY_COMMAND_ARGS}"
61+
set shellCmd "singularity \${SINGULARITY_OPTS} shell \${SINGULARITY_COMMAND_OPTS} -s {{ singularity_shell }} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} ${containerPath}"
62+
set execCmd "singularity \${SINGULARITY_OPTS} exec \${SINGULARITY_COMMAND_OPTS} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} "
63+
set runCmd "singularity \${SINGULARITY_OPTS} run \${SINGULARITY_COMMAND_OPTS} {% if envfile %}-B {{ module_dir }}/{{ envfile }}:/.singularity.d/env/{{ envfile }}{% endif %} {% if bindpaths %}-B {{ bindpaths }}{% endif %} ${containerPath} \${SINGULARITY_COMMAND_ARGS}"
6464
set inspectCmd "singularity \${SINGULARITY_OPTS} inspect \${SINGULARITY_COMMAND_OPTS} "
6565

6666
# set_shell_function takes bashStr and cshStr

shpc/main/templates.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
__author__ = "Vanessa Sochat"
2+
__copyright__ = "Copyright 2021, Vanessa Sochat"
3+
__license__ = "MPL 2.0"
4+
5+
6+
environment_file = """#!/bin/sh
7+
8+
# Add custom environment variables here with export
9+
{% for key, value in envars.items() %}export {{ key }}="{{ value }}"
10+
{% endfor %}
11+
"""

shpc/settings.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ singularity_shell: /bin/bash
3131
# the module namespace you want to install from. E.g., if you have ghcr.io/autamus/clingo
3232
# and you set the namespace to ghcr.io/autamus, you can just do: shpc install clingo.
3333
namespace: null
34+
35+
# THe name of the environment file to bind to the container.
36+
# This determines order of load
37+
environment_file: "99-shpc.sh"

0 commit comments

Comments
 (0)