1
+ """Support for executing Docker containers using Singularity."""
1
2
from __future__ import absolute_import
2
-
3
3
import logging
4
4
import os
5
5
import re
6
6
import shutil
7
- import subprocess
8
7
import sys
9
- from io import open
10
-
11
- from typing import (Dict , List , Text , Optional , MutableMapping , Any )
12
-
8
+ from io import open # pylint: disable=redefined-builtin
9
+ from typing import (Dict , List , Text , Optional , MutableMapping )
13
10
from .errors import WorkflowException
14
11
from .job import ContainerCommandLineJob
15
12
from .pathmapper import PathMapper , ensure_writable
16
13
from .process import (UnsupportedRequirement )
17
14
from .utils import docker_windows_path_adjust
15
+ if os .name == 'posix' and sys .version_info [0 ] < 3 :
16
+ import subprocess32 as subprocess # pylint: disable=import-error
17
+ else :
18
+ import subprocess
18
19
19
20
_logger = logging .getLogger ("cwltool" )
21
+ _USERNS = None
22
+
23
+ def _singularity_supports_userns (): # type: ()->bool
24
+ global _USERNS # pylint: disable=global-statement
25
+ if _USERNS is None :
26
+ _USERNS = "No valid /bin/sh" in subprocess .run (
27
+ [u"singularity" , u"exec" , u"--userns" , u"/etc" , u"true" ],
28
+ stderr = subprocess .PIPE ).stderr .decode ('utf-8' )
29
+ return _USERNS
20
30
21
31
22
32
class SingularityCommandLineJob (ContainerCommandLineJob ):
@@ -154,7 +164,7 @@ def add_volumes(self, pathmapper, runtime, stage_output):
154
164
elif vol .type == "WritableFile" :
155
165
if self .inplace_update :
156
166
runtime .append (u"--bind" )
157
- runtime .append ("{}:{}:rw" .format (
167
+ runtime .append (u "{}:{}:rw" .format (
158
168
docker_windows_path_adjust (vol .resolved ),
159
169
docker_windows_path_adjust (containertgt )))
160
170
else :
@@ -166,7 +176,7 @@ def add_volumes(self, pathmapper, runtime, stage_output):
166
176
else :
167
177
if self .inplace_update :
168
178
runtime .append (u"--bind" )
169
- runtime .append ("{}:{}:rw" .format (
179
+ runtime .append (u "{}:{}:rw" .format (
170
180
docker_windows_path_adjust (vol .resolved ),
171
181
docker_windows_path_adjust (containertgt )))
172
182
else :
@@ -176,7 +186,7 @@ def add_volumes(self, pathmapper, runtime, stage_output):
176
186
with open (createtmp , "wb" ) as tmp :
177
187
tmp .write (vol .resolved .encode ("utf-8" ))
178
188
runtime .append (u"--bind" )
179
- runtime .append ("{}:{}:ro" .format (
189
+ runtime .append (u "{}:{}:ro" .format (
180
190
docker_windows_path_adjust (createtmp ),
181
191
docker_windows_path_adjust (vol .target )))
182
192
@@ -192,7 +202,9 @@ def create_runtime(self,
192
202
""" Returns the Singularity runtime list of commands and options."""
193
203
194
204
runtime = [u"singularity" , u"--quiet" , u"exec" , u"--contain" , u"--pid" ,
195
- u"--ipc" ] # , u"--userns"]
205
+ u"--ipc" ]
206
+ if _singularity_supports_userns ():
207
+ runtime .append (u"--userns" )
196
208
runtime .append (u"--bind" )
197
209
runtime .append (u"{}:{}:rw" .format (
198
210
docker_windows_path_adjust (os .path .realpath (self .outdir )),
0 commit comments