@@ -321,15 +321,20 @@ def add_volumes(self, pathmapper, runtime):
321
321
if not vol .staged :
322
322
continue
323
323
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 :])
325
326
else :
326
327
host_outdir_tgt = None
327
328
if vol .type in ("File" , "Directory" ):
328
329
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 )))
330
333
elif vol .type == "WritableFile" :
331
334
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 )))
333
338
else :
334
339
shutil .copy (vol .resolved , host_outdir_tgt )
335
340
ensure_writable (host_outdir_tgt )
@@ -338,7 +343,9 @@ def add_volumes(self, pathmapper, runtime):
338
343
os .makedirs (vol .target , 0o0755 )
339
344
else :
340
345
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 )))
342
349
else :
343
350
shutil .copytree (vol .resolved , host_outdir_tgt )
344
351
ensure_writable (host_outdir_tgt )
@@ -350,7 +357,9 @@ def add_volumes(self, pathmapper, runtime):
350
357
fd , createtmp = tempfile .mkstemp (dir = self .tmpdir )
351
358
with os .fdopen (fd , "wb" ) as f :
352
359
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 )))
354
363
355
364
def run (self , pull_image = True , rm_container = True ,
356
365
rm_tmpdir = True , move_outputs = "move" , ** kwargs ):
@@ -360,59 +369,89 @@ def run(self, pull_image=True, rm_container=True,
360
369
361
370
img_id = None
362
371
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" ])
381
380
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 )
385
410
386
411
self ._setup (kwargs )
387
412
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" ]
389
417
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" ))
392
423
393
424
self .add_volumes (self .pathmapper , runtime )
394
425
if self .generatemapper :
395
426
self .add_volumes (self .generatemapper , runtime )
396
427
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 ]
398
431
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 :
401
435
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" )
406
438
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" )
409
446
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 ()
413
451
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 ))
416
455
417
456
if rm_container :
418
457
runtime .append (u"--rm" )
@@ -429,7 +468,8 @@ def run(self, pull_image=True, rm_container=True,
429
468
430
469
runtime .append (img_id )
431
470
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 )
433
473
434
474
435
475
def _job_popen (
0 commit comments