-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinSingularity.groovy
65 lines (55 loc) · 2.72 KB
/
inSingularity.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import org.electronicvisions.jenlib.ShellManipulator
/**
* Run a section of code within a specified singularity container.
* This makes {@code jesh} steps being executed inside a bash within the given singularity container.
*
* If supported by your singularity installation, nested {@code inSingularity} contexts are allowed.
*
* The order of which singularity image is invoked is the following:
* <ul>
* <li>If nothing is specified -> use /container/stable/latest</li>
* <li>If "In-Container: /path/to/image" is present in commit message, use "/path/to/image" instead of default path.</li>
* <li>If containerOptions contains "image", *always* use that image (highest priority, trumps "In-Container:"-tag).</li>
* </ul>
*
* @param containerOptions Keys:
* <ul>
* <li>image: [optional, defaults to "/containers/stable/latest"] Singularity container image to be used.
* If the commit being built contains "In-Container: /path/to/image", the default will be change to "/path/to/image".</li>
* <li>app: [optional, defaults to no app] Singularity container app to be used.</li>
* <li>singularityArgs: [optional, defaults to ""] Additional singularity arguments.</li>
* </ul>
* @param content Code to be executed in the context of a container instance.
*/
def call(Map<String, String> containerOptions = [:], Closure content) {
/**
* Argument to be be passed to singularity for specifying the app.
*/
String appArgument = ""
if (containerOptions.get("app") != null) {
appArgument = "--app=${containerOptions.get("app")}"
}
// Lazy evaluate getDefaultContainerPath: Computing it is not necessary if an image argument is given
String containerImage = containerOptions.get("image")
if (containerImage == null) {
containerImage = getDefaultContainerPath()
}
List<String> prefixCommands = new ArrayList()
// Parent app shall not be propagated in nested singularity calls
prefixCommands.add('unset SINGULARITY_APPNAME')
// SINGULARITY_ENV environment modifiers shall be kept inside the container to allow for nested calls
prefixCommands.add('for param in "${!SINGULARITYENV_@}"; do export "SINGULARITYENV_$param"="${!param}"; done')
prefixCommands.add("singularity exec " +
"${appArgument} " +
"${containerOptions.get("singularityArgs", "")} " +
"${containerImage}")
ShellManipulator manipulator = ShellManipulator.fromEnvironment(this)
manipulator.add(prefixCommands.join(" && "), "")
try {
content()
} catch (Throwable anything) {
throw anything
} finally {
manipulator.restore()
}
}