Skip to content

Reduce bind mounting (and thus --bind args) in containers. #1387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
7 changes: 6 additions & 1 deletion cwltool/command_line_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,8 +877,13 @@ def update_status_output_callback(
)
_logger.debug("[job %s] %s", j.name, json_dumps(builder.job, indent=4))

separateDirs = True
# sufficient conditional for docker/singularity?
if runtimeContext.use_container:
separateDirs = False

builder.pathmapper = self.make_path_mapper(
reffiles, builder.stagedir, runtimeContext, True
reffiles, builder.stagedir, runtimeContext, separateDirs
)
builder.requirements = j.requirements

Expand Down
8 changes: 6 additions & 2 deletions cwltool/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ def append_volume(
runtime: List[str], source: str, target: str, writable: bool = False
) -> None:
"""Add binding arguments to the runtime list."""
if os.path.isfile(source) and target.endswith(os.path.basename(source)) and not writable:
source = os.path.dirname(source)
target = os.path.dirname(target)
options = [
"type=bind",
"source=" + source,
Expand All @@ -260,8 +263,9 @@ def append_volume(
options.append("readonly")
output = StringIO()
csv.writer(output).writerow(options)
mount_arg = output.getvalue().strip()
runtime.append("--mount={}".format(mount_arg))
mount_arg = f"--mount={output.getvalue().strip()}"
if mount_arg not in runtime:
runtime.append(mount_arg)
# Unlike "--volume", "--mount" will fail if the volume doesn't already exist.
if not os.path.exists(source):
os.makedirs(source)
Expand Down
26 changes: 12 additions & 14 deletions cwltool/singularity.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,16 +280,17 @@ def get_from_requirements(

@staticmethod
def append_volume(
runtime: List[str], source: str, target: str, writable: bool = False
runtime: List[str], source: str, target: str, writable: bool = False
) -> None:
runtime.append("--bind")
runtime.append(
"{}:{}:{}".format(
docker_windows_path_adjust(source),
docker_windows_path_adjust(target),
"rw" if writable else "ro",
)
)
src = docker_windows_path_adjust(source)
dst = docker_windows_path_adjust(target)
writable = "rw" if writable else "ro"
if os.path.isfile(src) and dst.endswith(os.path.basename(src)) and writable == 'ro':
src = os.path.dirname(src)
dst = os.path.dirname(dst)
bind_arg = f"--bind={src}:{dst}:{writable}"
if bind_arg not in runtime:
Copy link
Contributor

@ionox0 ionox0 Jun 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried running this PR after getting the argument list too long error when using large number of input directories, and it seems that the source directory here is actually different for each file, and therefore it did not reduce the number of --bind arguments:

...
--bind=/juno/work/access/testing/users/johnsoni/access_qc/5500_HF/jobStore/files/for-job/kind-CWLJob/instance-aop8iz_w/file-34cfcc9ed208473bb67710a5108f1a32:/var/lib/cwl/s5g5ff703f1-41b2-56d3-93b3-7e36c1a37224/all_qc_files/duplex_bam_sequence_qc_dir/C-R0CLHU-N001-d:ro \
--bind=/juno/work/access/testing/users/johnsoni/access_qc/5500_HF/jobStore/files/for-job/kind-CWLJob/instance-aop8iz_w/file-fee328e946c9448c92ee501c6daa4b5a:/var/lib/cwl/s5g5ff703f1-41b2-56d3-93b3-7e36c1a37224/all_qc_files/duplex_bam_sequence_qc_dir/C-R0CLHU-N001-d:ro \
...

It seems toil actually produces different parent directories for files that might have originally came from the same Directory object. So if files that came from the same directory can be stored as such in the jobstore, I would expect this change to fix the issue

runtime.append(bind_arg)

def add_file_or_directory_volume(
self, runtime: List[str], volume: MapperEnt, host_outdir_tgt: Optional[str]
Expand Down Expand Up @@ -403,17 +404,14 @@ def create_runtime(
)
)
else:
runtime.append("--bind")
runtime.append(
"{}:{}:rw".format(
runtime.append("--bind={}:{}:rw".format(
docker_windows_path_adjust(os.path.realpath(self.outdir)),
self.builder.outdir,
)
)
runtime.append("--bind")
tmpdir = "/tmp" # nosec
runtime.append(
"{}:{}:rw".format(
"--bind={}:{}:rw".format(
docker_windows_path_adjust(os.path.realpath(self.tmpdir)), tmpdir
)
)
Expand Down