|
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