@@ -321,15 +321,20 @@ def add_volumes(self, pathmapper, runtime):
321321 if not vol .staged :
322322 continue
323323 if vol .target .startswith (container_outdir + "/" ):
324- host_outdir_tgt = os .path .join (host_outdir , vol .target [len (container_outdir )+ 1 :])
324+ host_outdir_tgt = os .path .join (
325+ host_outdir , vol .target [len (container_outdir )+ 1 :])
325326 else :
326327 host_outdir_tgt = None
327328 if vol .type in ("File" , "Directory" ):
328329 if not vol .resolved .startswith ("_:" ):
329- runtime .append (u"--volume=%s:%s:ro" % (docker_windows_path_adjust (vol .resolved ), docker_windows_path_adjust (vol .target )))
330+ runtime .append (u"--volume=%s:%s:ro" % (
331+ docker_windows_path_adjust (vol .resolved ),
332+ docker_windows_path_adjust (vol .target )))
330333 elif vol .type == "WritableFile" :
331334 if self .inplace_update :
332- runtime .append (u"--volume=%s:%s:rw" % (docker_windows_path_adjust (vol .resolved ), docker_windows_path_adjust (vol .target )))
335+ runtime .append (u"--volume=%s:%s:rw" % (
336+ docker_windows_path_adjust (vol .resolved ),
337+ docker_windows_path_adjust (vol .target )))
333338 else :
334339 shutil .copy (vol .resolved , host_outdir_tgt )
335340 ensure_writable (host_outdir_tgt )
@@ -338,7 +343,9 @@ def add_volumes(self, pathmapper, runtime):
338343 os .makedirs (vol .target , 0o0755 )
339344 else :
340345 if self .inplace_update :
341- runtime .append (u"--volume=%s:%s:rw" % (docker_windows_path_adjust (vol .resolved ), docker_windows_path_adjust (vol .target )))
346+ runtime .append (u"--volume=%s:%s:rw" % (
347+ docker_windows_path_adjust (vol .resolved ),
348+ docker_windows_path_adjust (vol .target )))
342349 else :
343350 shutil .copytree (vol .resolved , host_outdir_tgt )
344351 ensure_writable (host_outdir_tgt )
@@ -350,7 +357,9 @@ def add_volumes(self, pathmapper, runtime):
350357 fd , createtmp = tempfile .mkstemp (dir = self .tmpdir )
351358 with os .fdopen (fd , "wb" ) as f :
352359 f .write (vol .resolved .encode ("utf-8" ))
353- runtime .append (u"--volume=%s:%s:rw" % (docker_windows_path_adjust (createtmp ), docker_windows_path_adjust (vol .target )))
360+ runtime .append (u"--volume=%s:%s:rw" % (
361+ docker_windows_path_adjust (createtmp ),
362+ docker_windows_path_adjust (vol .target )))
354363
355364 def run (self , pull_image = True , rm_container = True ,
356365 rm_tmpdir = True , move_outputs = "move" , ** kwargs ):
@@ -360,59 +369,89 @@ def run(self, pull_image=True, rm_container=True,
360369
361370 img_id = None
362371 env = None # type: MutableMapping[Text, Text]
363- try :
364- env = cast (MutableMapping [Text , Text ], os .environ )
365- if docker_req and kwargs .get ("use_container" ):
366- img_id = docker .get_from_requirements (docker_req , True , pull_image )
367- if img_id is None :
368- if self .builder .find_default_container :
369- default_container = self .builder .find_default_container ()
370- if default_container :
371- img_id = default_container
372- env = cast (MutableMapping [Text , Text ], os .environ )
373-
374- if docker_req and img_id is None and kwargs .get ("use_container" ):
375- raise Exception ("Docker image not available" )
376- except Exception as e :
377- _logger .debug ("Docker error" , exc_info = True )
378- if docker_is_req :
379- raise UnsupportedRequirement (
380- "Docker is required to run this tool: %s" % e )
372+ user_space_docker_cmd = kwargs .get ("user_space_docker_cmd" )
373+ if docker_req and user_space_docker_cmd :
374+ # For user-space docker implementations, a local image name or ID
375+ # takes precedence over a network pull
376+ if 'dockerImageId' in docker_req :
377+ img_id = str (docker_req ["dockerImageId" ])
378+ elif 'dockerPull' in docker_req :
379+ img_id = str (docker_req ["dockerPull" ])
381380 else :
382- raise WorkflowException (
383- "Docker is not available for this tool, try --no-container"
384- " to disable Docker: %s" % e )
381+ raise Exception ("Docker image must be specified as "
382+ "'dockerImageId' or 'dockerPull' when using user "
383+ "space implementations of Docker" )
384+ else :
385+ try :
386+ env = cast (MutableMapping [Text , Text ], os .environ )
387+ if docker_req and kwargs .get ("use_container" ):
388+ img_id = str (docker .get_from_requirements (
389+ docker_req , True , pull_image ))
390+ if img_id is None :
391+ if self .builder .find_default_container :
392+ default_container = self .builder .find_default_container ()
393+ if default_container :
394+ img_id = str (default_container )
395+ env = cast (MutableMapping [Text , Text ], os .environ )
396+
397+ if docker_req and img_id is None and kwargs .get ("use_container" ):
398+ raise Exception ("Docker image not available" )
399+ except Exception as e :
400+ _logger .debug ("Docker error" , exc_info = True )
401+ if docker_is_req :
402+ raise UnsupportedRequirement (
403+ "Docker is required to run this tool: %s" % e )
404+ else :
405+ raise WorkflowException (
406+ "Docker is not available for this tool, try "
407+ "--no-container to disable Docker, or install "
408+ "a user space Docker replacement like uDocker with "
409+ "--user-space-docker-cmd.: %s" % e )
385410
386411 self ._setup (kwargs )
387412
388- runtime = [u"docker" , u"run" , u"-i" ]
413+ if user_space_docker_cmd :
414+ runtime = [user_space_docker_cmd , u"run" ]
415+ else :
416+ runtime = [u"docker" , u"run" , u"-i" ]
389417
390- runtime .append (u"--volume=%s:%s:rw" % (docker_windows_path_adjust (os .path .realpath (self .outdir )), self .builder .outdir ))
391- runtime .append (u"--volume=%s:%s:rw" % (docker_windows_path_adjust (os .path .realpath (self .tmpdir )), "/tmp" ))
418+ runtime .append (u"--volume=%s:%s:rw" % (
419+ docker_windows_path_adjust (os .path .realpath (self .outdir )),
420+ self .builder .outdir ))
421+ runtime .append (u"--volume=%s:%s:rw" % (
422+ docker_windows_path_adjust (os .path .realpath (self .tmpdir )), "/tmp" ))
392423
393424 self .add_volumes (self .pathmapper , runtime )
394425 if self .generatemapper :
395426 self .add_volumes (self .generatemapper , runtime )
396427
397- runtime .append (u"--workdir=%s" % (docker_windows_path_adjust (self .builder .outdir )))
428+ if user_space_docker_cmd :
429+ runtime = [x .replace (":ro" , "" ) for x in runtime ]
430+ runtime = [x .replace (":rw" , "" ) for x in runtime ]
398431
399- if not kwargs .get ("no_read_only" ):
400- runtime .append (u"--read-only=true" )
432+ runtime .append (u"--workdir=%s" % (
433+ docker_windows_path_adjust (self .builder .outdir )))
434+ if not user_space_docker_cmd :
401435
402- if kwargs .get ("custom_net" , None ) is not None :
403- runtime .append (u"--net={0}" .format (kwargs .get ("custom_net" )))
404- elif kwargs .get ("disable_net" , None ):
405- runtime .append (u"--net=none" )
436+ if not kwargs .get ("no_read_only" ):
437+ runtime .append (u"--read-only=true" )
406438
407- if self .stdout :
408- runtime .append ("--log-driver=none" )
439+ if kwargs .get ("custom_net" , None ) is not None :
440+ runtime .append (u"--net={0}" .format (kwargs .get ("custom_net" )))
441+ elif kwargs .get ("disable_net" , None ):
442+ runtime .append (u"--net=none" )
443+
444+ if self .stdout :
445+ runtime .append ("--log-driver=none" )
409446
410- euid , egid = docker_vm_id ()
411- if not onWindows (): # MS Windows does not have getuid() or geteuid() functions
412- euid , egid = euid or os .geteuid (), egid or os .getgid ()
447+ euid , egid = docker_vm_id ()
448+ if not onWindows ():
449+ # MS Windows does not have getuid() or geteuid() functions
450+ euid , egid = euid or os .geteuid (), egid or os .getgid ()
413451
414- if kwargs .get ("no_match_user" , None ) is False and (euid , egid ) != (None , None ):
415- runtime .append (u"--user=%d:%d" % (euid , egid ))
452+ if kwargs .get ("no_match_user" , None ) is False \
453+ and (euid , egid ) != (None , None ):
454+ runtime .append (u"--user=%d:%d" % (euid , egid ))
416455
417456 if rm_container :
418457 runtime .append (u"--rm" )
@@ -429,7 +468,8 @@ def run(self, pull_image=True, rm_container=True,
429468
430469 runtime .append (img_id )
431470
432- self ._execute (runtime , env , rm_tmpdir = rm_tmpdir , move_outputs = move_outputs )
471+ self ._execute (
472+ runtime , env , rm_tmpdir = rm_tmpdir , move_outputs = move_outputs )
433473
434474
435475def _job_popen (
0 commit comments