Skip to content

Commit a73d5bf

Browse files
author
Peter Amstutz
committed
Fix docker volume staging for writable files / file literals.
1 parent b7f87da commit a73d5bf

File tree

1 file changed

+32
-28
lines changed

1 file changed

+32
-28
lines changed

cwltool/job.py

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -98,24 +98,26 @@ def deref_links(outputs): # type: (Any) -> None
9898
for v in outputs:
9999
deref_links(v)
100100

101-
def relink_initialworkdir(pathmapper, inplace_update=False):
101+
def relink_initialworkdir(pathmapper, host_outdir, container_outdir, inplace_update=False):
102102
# type: (PathMapper, bool) -> None
103103
for src, vol in pathmapper.items():
104104
if not vol.staged:
105105
continue
106+
106107
if vol.type in ("File", "Directory") or (inplace_update and
107108
vol.type in ("WritableFile", "WritableDirectory")):
108-
if os.path.islink(vol.target) or os.path.isfile(vol.target):
109-
os.remove(vol.target)
110-
elif os.path.isdir(vol.target):
111-
shutil.rmtree(vol.target)
109+
host_outdir_tgt = os.path.join(host_outdir, vol.target[len(container_outdir)+1:])
110+
if os.path.islink(host_outdir_tgt) or os.path.isfile(host_outdir_tgt):
111+
os.remove(host_outdir_tgt)
112+
elif os.path.isdir(host_outdir_tgt):
113+
shutil.rmtree(host_outdir_tgt)
112114
if onWindows():
113115
if vol.type in ("File", "WritableFile"):
114-
shutil.copy(vol.resolved,vol.target)
116+
shutil.copy(vol.resolved,host_outdir_tgt)
115117
elif vol.type in ("Directory", "WritableDirectory"):
116-
copytree_with_merge(vol.resolved, vol.target)
118+
copytree_with_merge(vol.resolved, host_outdir_tgt)
117119
else:
118-
os.symlink(vol.resolved, vol.target)
120+
os.symlink(vol.resolved, host_outdir_tgt)
119121

120122
class JobBase(object):
121123
def __init__(self): # type: () -> None
@@ -160,7 +162,7 @@ def _setup(self, kwargs): # type: (Dict) -> None
160162
make_path_mapper_kwargs = make_path_mapper_kwargs.copy()
161163
del make_path_mapper_kwargs["basedir"]
162164
self.generatemapper = self.make_pathmapper(cast(List[Any], self.generatefiles["listing"]),
163-
self.outdir, basedir=self.outdir, separateDirs=False, **make_path_mapper_kwargs)
165+
self.builder.outdir, basedir=self.outdir, separateDirs=False, **make_path_mapper_kwargs)
164166
_logger.debug(u"[job %s] initial work dir %s", self.name,
165167
json.dumps({p: self.generatemapper.mapper(p) for p in self.generatemapper.files()}, indent=4))
166168

@@ -234,7 +236,7 @@ def _execute(self, runtime, env, rm_tmpdir=True, move_outputs="move"):
234236
processStatus = "permanentFail"
235237

236238
if self.generatefiles["listing"]:
237-
relink_initialworkdir(self.generatemapper, inplace_update=self.inplace_update)
239+
relink_initialworkdir(self.generatemapper, self.outdir, self.builder.outdir, inplace_update=self.inplace_update)
238240

239241
outputs = self.collect_outputs(self.outdir)
240242
outputs = bytes2str_in_dicts(outputs) # type: ignore
@@ -303,48 +305,50 @@ def run(self, pull_image=True, rm_container=True,
303305
stageFiles(self.pathmapper, ignoreWritable=True, symLink=True)
304306
if self.generatemapper:
305307
stageFiles(self.generatemapper, ignoreWritable=self.inplace_update, symLink=True)
306-
relink_initialworkdir(self.generatemapper, inplace_update=self.inplace_update)
308+
relink_initialworkdir(self.generatemapper, self.outdir, self.builder.outdir, inplace_update=self.inplace_update)
307309

308310
self._execute([], env, rm_tmpdir=rm_tmpdir, move_outputs=move_outputs)
309311

310312

311313
class DockerCommandLineJob(JobBase):
312314

313-
def add_volumes(self, pathmapper, runtime, stage_output):
315+
def add_volumes(self, pathmapper, runtime):
314316
# type: (PathMapper, List[Text], bool) -> None
315317

316318
host_outdir = self.outdir
317319
container_outdir = self.builder.outdir
318320
for src, vol in pathmapper.items():
319321
if not vol.staged:
320322
continue
321-
if stage_output:
322-
containertgt = container_outdir + vol.target[len(host_outdir):]
323+
if vol.target.startswith(container_outdir+"/"):
324+
host_outdir_tgt = os.path.join(host_outdir, vol.target[len(container_outdir)+1:])
323325
else:
324-
containertgt = vol.target
326+
host_outdir_tgt = None
325327
if vol.type in ("File", "Directory"):
326328
if not vol.resolved.startswith("_:"):
327-
runtime.append(u"--volume=%s:%s:ro" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(containertgt)))
329+
runtime.append(u"--volume=%s:%s:ro" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(vol.target)))
328330
elif vol.type == "WritableFile":
329331
if self.inplace_update:
330-
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(containertgt)))
332+
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(vol.target)))
331333
else:
332-
shutil.copy(vol.resolved, vol.target)
334+
shutil.copy(vol.resolved, host_outdir_tgt)
333335
elif vol.type == "WritableDirectory":
334336
if vol.resolved.startswith("_:"):
335337
os.makedirs(vol.target, 0o0755)
336338
else:
337339
if self.inplace_update:
338-
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(containertgt)))
340+
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(vol.target)))
339341
else:
340-
shutil.copytree(vol.resolved, vol.target)
342+
shutil.copytree(vol.resolved, host_outdir_tgt)
341343
elif vol.type == "CreateFile":
342-
createtmp = os.path.join(host_outdir, os.path.basename(vol.target))
343-
with open(createtmp, "wb") as f:
344-
f.write(vol.resolved.encode("utf-8"))
345-
if not vol.target.startswith(container_outdir):
346-
runtime.append(u"--volume=%s:%s:ro" % (docker_windows_path_adjust(createtmp), docker_windows_path_adjust(vol.target)))
347-
344+
if host_outdir_tgt:
345+
with open(host_outdir_tgt, "wb") as f:
346+
f.write(vol.resolved.encode("utf-8"))
347+
else:
348+
fd, createtmp = tempfile.mkstemp(dir=self.tmpdir)
349+
with os.fdopen(fd, "wb") as f:
350+
f.write(vol.resolved.encode("utf-8"))
351+
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(createtmp), docker_windows_path_adjust(vol.target)))
348352

349353
def run(self, pull_image=True, rm_container=True,
350354
rm_tmpdir=True, move_outputs="move", **kwargs):
@@ -384,9 +388,9 @@ def run(self, pull_image=True, rm_container=True,
384388
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(os.path.realpath(self.outdir)), self.builder.outdir))
385389
runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(os.path.realpath(self.tmpdir)), "/tmp"))
386390

387-
self.add_volumes(self.pathmapper, runtime, False)
391+
self.add_volumes(self.pathmapper, runtime)
388392
if self.generatemapper:
389-
self.add_volumes(self.generatemapper, runtime, True)
393+
self.add_volumes(self.generatemapper, runtime)
390394

391395
runtime.append(u"--workdir=%s" % (docker_windows_path_adjust(self.builder.outdir)))
392396
runtime.append(u"--read-only=true")

0 commit comments

Comments
 (0)