|
21 | 21 | from .builder import Builder
|
22 | 22 | from .docker_id import docker_vm_id
|
23 | 23 | from .errors import WorkflowException
|
24 |
| -from .pathmapper import PathMapper |
| 24 | +from .pathmapper import PathMapper, ensure_writable |
25 | 25 | from .process import (UnsupportedRequirement, empty_subtree, get_feature,
|
26 | 26 | stageFiles)
|
27 | 27 | from .utils import bytes2str_in_dicts
|
@@ -98,24 +98,26 @@ def deref_links(outputs): # type: (Any) -> None
|
98 | 98 | for v in outputs:
|
99 | 99 | deref_links(v)
|
100 | 100 |
|
101 |
| -def relink_initialworkdir(pathmapper, inplace_update=False): |
102 |
| - # type: (PathMapper, bool) -> None |
| 101 | +def relink_initialworkdir(pathmapper, host_outdir, container_outdir, inplace_update=False): |
| 102 | + # type: (PathMapper, Text, Text, bool) -> None |
103 | 103 | for src, vol in pathmapper.items():
|
104 | 104 | if not vol.staged:
|
105 | 105 | continue
|
| 106 | + |
106 | 107 | if vol.type in ("File", "Directory") or (inplace_update and
|
107 | 108 | 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) |
112 | 114 | if onWindows():
|
113 | 115 | if vol.type in ("File", "WritableFile"):
|
114 |
| - shutil.copy(vol.resolved,vol.target) |
| 116 | + shutil.copy(vol.resolved, host_outdir_tgt) |
115 | 117 | elif vol.type in ("Directory", "WritableDirectory"):
|
116 |
| - copytree_with_merge(vol.resolved, vol.target) |
| 118 | + copytree_with_merge(vol.resolved, host_outdir_tgt) |
117 | 119 | else:
|
118 |
| - os.symlink(vol.resolved, vol.target) |
| 120 | + os.symlink(vol.resolved, host_outdir_tgt) |
119 | 121 |
|
120 | 122 | class JobBase(object):
|
121 | 123 | def __init__(self): # type: () -> None
|
@@ -160,7 +162,7 @@ def _setup(self, kwargs): # type: (Dict) -> None
|
160 | 162 | make_path_mapper_kwargs = make_path_mapper_kwargs.copy()
|
161 | 163 | del make_path_mapper_kwargs["basedir"]
|
162 | 164 | 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) |
164 | 166 | _logger.debug(u"[job %s] initial work dir %s", self.name,
|
165 | 167 | json.dumps({p: self.generatemapper.mapper(p) for p in self.generatemapper.files()}, indent=4))
|
166 | 168 |
|
@@ -234,7 +236,7 @@ def _execute(self, runtime, env, rm_tmpdir=True, move_outputs="move"):
|
234 | 236 | processStatus = "permanentFail"
|
235 | 237 |
|
236 | 238 | 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) |
238 | 240 |
|
239 | 241 | outputs = self.collect_outputs(self.outdir)
|
240 | 242 | outputs = bytes2str_in_dicts(outputs) # type: ignore
|
@@ -303,48 +305,52 @@ def run(self, pull_image=True, rm_container=True,
|
303 | 305 | stageFiles(self.pathmapper, ignoreWritable=True, symLink=True)
|
304 | 306 | if self.generatemapper:
|
305 | 307 | 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) |
307 | 309 |
|
308 | 310 | self._execute([], env, rm_tmpdir=rm_tmpdir, move_outputs=move_outputs)
|
309 | 311 |
|
310 | 312 |
|
311 | 313 | class DockerCommandLineJob(JobBase):
|
312 | 314 |
|
313 |
| - def add_volumes(self, pathmapper, runtime, stage_output): |
314 |
| - # type: (PathMapper, List[Text], bool) -> None |
| 315 | + def add_volumes(self, pathmapper, runtime): |
| 316 | + # type: (PathMapper, List[Text]) -> None |
315 | 317 |
|
316 | 318 | host_outdir = self.outdir
|
317 | 319 | container_outdir = self.builder.outdir
|
318 | 320 | for src, vol in pathmapper.items():
|
319 | 321 | if not vol.staged:
|
320 | 322 | 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:]) |
323 | 325 | else:
|
324 |
| - containertgt = vol.target |
| 326 | + host_outdir_tgt = None |
325 | 327 | if vol.type in ("File", "Directory"):
|
326 | 328 | 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))) |
328 | 330 | elif vol.type == "WritableFile":
|
329 | 331 | 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))) |
331 | 333 | else:
|
332 |
| - shutil.copy(vol.resolved, vol.target) |
| 334 | + shutil.copy(vol.resolved, host_outdir_tgt) |
| 335 | + ensure_writable(host_outdir_tgt) |
333 | 336 | elif vol.type == "WritableDirectory":
|
334 | 337 | if vol.resolved.startswith("_:"):
|
335 | 338 | os.makedirs(vol.target, 0o0755)
|
336 | 339 | else:
|
337 | 340 | if self.inplace_update:
|
338 |
| - runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(containertgt))) |
| 341 | + runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(vol.resolved), docker_windows_path_adjust(vol.target))) |
339 | 342 | else:
|
340 |
| - shutil.copytree(vol.resolved, vol.target) |
| 343 | + shutil.copytree(vol.resolved, host_outdir_tgt) |
| 344 | + ensure_writable(host_outdir_tgt) |
341 | 345 | 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 |
| - |
| 346 | + if host_outdir_tgt: |
| 347 | + with open(host_outdir_tgt, "wb") as f: |
| 348 | + f.write(vol.resolved.encode("utf-8")) |
| 349 | + else: |
| 350 | + fd, createtmp = tempfile.mkstemp(dir=self.tmpdir) |
| 351 | + with os.fdopen(fd, "wb") as f: |
| 352 | + 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))) |
348 | 354 |
|
349 | 355 | def run(self, pull_image=True, rm_container=True,
|
350 | 356 | rm_tmpdir=True, move_outputs="move", **kwargs):
|
@@ -384,9 +390,9 @@ def run(self, pull_image=True, rm_container=True,
|
384 | 390 | runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(os.path.realpath(self.outdir)), self.builder.outdir))
|
385 | 391 | runtime.append(u"--volume=%s:%s:rw" % (docker_windows_path_adjust(os.path.realpath(self.tmpdir)), "/tmp"))
|
386 | 392 |
|
387 |
| - self.add_volumes(self.pathmapper, runtime, False) |
| 393 | + self.add_volumes(self.pathmapper, runtime) |
388 | 394 | if self.generatemapper:
|
389 |
| - self.add_volumes(self.generatemapper, runtime, True) |
| 395 | + self.add_volumes(self.generatemapper, runtime) |
390 | 396 |
|
391 | 397 | runtime.append(u"--workdir=%s" % (docker_windows_path_adjust(self.builder.outdir)))
|
392 | 398 | runtime.append(u"--read-only=true")
|
|
0 commit comments