Skip to content

Commit 88994e6

Browse files
add support for running tools with singularity
1 parent ae45e91 commit 88994e6

File tree

2 files changed

+103
-49
lines changed

2 files changed

+103
-49
lines changed

planemo/galaxy/config.py

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
)
2828

2929
from galaxy.tool_util.deps import docker_util
30+
from galaxy.tool_util.deps import singularity_util
3031
from galaxy.tool_util.deps.container_volumes import DockerVolume
3132
from galaxy.util.commands import argv_to_str
3233
from galaxy.util.yaml_util import ordered_dump
@@ -125,11 +126,6 @@
125126
"planemo_dest": {
126127
"runner": "planemo_runner",
127128
"require_container": False,
128-
"docker_enabled": False,
129-
"docker_sudo": False,
130-
"docker_sudo_cmd": docker_util.DEFAULT_SUDO_COMMAND,
131-
"docker_cmd": docker_util.DEFAULT_DOCKER_COMMAND,
132-
"docker_volumes": "$defaults",
133129
},
134130
"upload_dest": {"runner": "planemo_runner", "docker_enabled": False},
135131
},
@@ -333,11 +329,14 @@ def local_galaxy_config(ctx, runnables, for_tests=False, **kwds):
333329

334330
# Duplicate block in docker variant above.
335331
if kwds.get("mulled_containers", False):
336-
if not kwds.get("docker", False):
337-
if ctx.get_option_source("docker") != OptionSource.cli:
332+
if not (kwds.get("docker", False) or kwds.get("singularity", False)):
333+
if (
334+
ctx.get_option_source("docker") != OptionSource.cli
335+
and ctx.get_option_source("singularity") != OptionSource.cli
336+
):
338337
kwds["docker"] = True
339338
else:
340-
raise Exception("Specified no docker and mulled containers together.")
339+
raise Exception("Specified --no-docker/--no-singularity and mulled containers together.")
341340
conda_default_options = ("conda_auto_init", "conda_auto_install")
342341
use_conda_options = ("dependency_resolution", "conda_use_local", "conda_prefix", "conda_exec")
343342
if not any(kwds.get(_) for _ in use_conda_options) and all(
@@ -718,7 +717,7 @@ class GalaxyConfig(GalaxyInterface, metaclass=abc.ABCMeta):
718717
719718
This assumes more than an API connection is available - Planemo needs to be able to
720719
start and stop the Galaxy instance, recover logs, etc... There are currently two
721-
implementations - a locally executed Galaxy and one running inside a Docker containe
720+
implementations - a locally executed Galaxy and one running inside a Docker container
722721
"""
723722

724723
@abc.abstractproperty
@@ -1334,26 +1333,43 @@ def _handle_job_config_file(
13341333
"job_conf.yml",
13351334
)
13361335
planemo_dest = JOB_CONFIG_LOCAL["execution"]["environments"]["planemo_dest"]
1337-
planemo_dest["docker_enabled"] = kwds.get("docker", False)
1338-
planemo_dest["docker_sudo"] = kwds.get("docker_sudo", False)
1339-
planemo_dest["docker_sudo_cmd"] = kwds.get("docker_sudo_cmd", docker_util.DEFAULT_SUDO_COMMAND)
1340-
planemo_dest["docker_cmd"] = kwds.get("docker_cmd", docker_util.DEFAULT_DOCKER_COMMAND)
1341-
1342-
docker_host = kwds.get("docker_host", docker_util.DEFAULT_HOST)
1343-
if docker_host:
1344-
planemo_dest["docker_host"] = docker_host
1345-
1346-
volumes = list(kwds.get("docker_extra_volume") or [])
1347-
if test_data_dir:
1348-
volumes.append(f"{test_data_dir}:ro")
1349-
1350-
docker_volumes_str = "$defaults"
1351-
if volumes:
1352-
# exclude tool directories, these are mounted :ro by $defaults
1353-
all_tool_dirs = {os.path.dirname(tool_path) for tool_path in all_tool_paths}
1354-
extra_volumes_str = ",".join(str(v) for v in create_docker_volumes(volumes) if v.path not in all_tool_dirs)
1355-
docker_volumes_str = f"{docker_volumes_str},{extra_volumes_str}"
1356-
planemo_dest["docker_volumes"] = docker_volumes_str
1336+
1337+
for container_type in ["docker", "singularity"]:
1338+
if not kwds.get(container_type, False):
1339+
continue
1340+
planemo_dest[f"{container_type}_enabled"] = kwds.get(container_type, False)
1341+
planemo_dest[f"{container_type}_sudo"] = kwds.get(f"{container_type}_sudo", False)
1342+
planemo_dest[f"{container_type}_sudo_cmd"] = kwds.get(
1343+
f"{container_type}_sudo_cmd",
1344+
docker_util.DEFAULT_SUDO_COMMAND
1345+
if container_type == "docker"
1346+
else singularity_util.DEFAULT_SUDO_COMMAND,
1347+
)
1348+
planemo_dest[f"{container_type}_cmd"] = kwds.get(
1349+
f"{container_type}_cmd",
1350+
docker_util.DEFAULT_DOCKER_COMMAND
1351+
if container_type == "docker"
1352+
else singularity_util.DEFAULT_SINGULARITY_COMMAND,
1353+
)
1354+
if container_type == "docker":
1355+
docker_host = kwds.get("docker_host", docker_util.DEFAULT_HOST)
1356+
if docker_host:
1357+
planemo_dest["docker_host"] = docker_host
1358+
1359+
volumes = list(kwds.get(f"{container_type}_extra_volume") or [])
1360+
if test_data_dir:
1361+
volumes.append(f"{test_data_dir}:ro")
1362+
volumes_str = "$defaults"
1363+
if volumes:
1364+
# exclude tool directories, these are mounted :ro by $defaults
1365+
all_tool_dirs = {os.path.dirname(tool_path) for tool_path in all_tool_paths}
1366+
extra_volumes_str = ",".join(
1367+
str(v) for v in create_docker_volumes(volumes) if v.path not in all_tool_dirs
1368+
)
1369+
volumes_str = f"{volumes_str},{extra_volumes_str}"
1370+
planemo_dest[f"{container_type}_volumes"] = volumes_str
1371+
break
1372+
13571373
JOB_CONFIG_LOCAL["execution"]["environments"]["planemo_dest"] = planemo_dest
13581374
with open(job_config_file, "w") as job_config_fh:
13591375
ordered_dump(JOB_CONFIG_LOCAL, job_config_fh)

planemo/options.py

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
import os
66

77
import click
8-
from galaxy.tool_util.deps import docker_util
8+
from galaxy.tool_util.deps import (
9+
docker_util,
10+
singularity_util,
11+
)
912
from galaxy.tool_util.verify.interactor import DEFAULT_TOOL_TEST_WAIT
1013

1114
from .config import planemo_option
@@ -418,7 +421,7 @@ def mulled_containers_option():
418421
"--mulled_containers",
419422
"--biocontainers",
420423
is_flag=True,
421-
help="Test tools against mulled containers (forces --docker). Disables conda resolution unless any conda option has been set explicitly.",
424+
help="Test tools against mulled containers (requires --docker/--singularity, if none of these are given --docker is used automatically). Disables conda resolution unless any conda option has been set explicitly.",
422425
)
423426

424427

@@ -458,13 +461,23 @@ def docker_extra_volume_option():
458461
readable=True,
459462
resolve_path=True,
460463
)
461-
return planemo_option(
462-
"--docker_extra_volume",
463-
type=arg_type,
464-
default=None,
465-
use_global_config=True,
466-
multiple=True,
467-
help=("Extra path to mount if --engine docker or `--biocontainers` or `--docker`."),
464+
return _compose(
465+
planemo_option(
466+
"--docker_extra_volume",
467+
type=arg_type,
468+
default=None,
469+
use_global_config=True,
470+
multiple=True,
471+
help=("Extra path to mount if --engine docker or `--biocontainers` or `--docker`."),
472+
),
473+
planemo_option(
474+
"--singularity_extra_volume",
475+
type=arg_type,
476+
default=None,
477+
use_global_config=True,
478+
multiple=True,
479+
help=("Extra path to mount if `--biocontainers` and `--singularity`."),
480+
),
468481
)
469482

470483

@@ -914,27 +927,52 @@ def no_cleanup_option():
914927

915928

916929
def docker_enable_option():
917-
return planemo_option("--docker/--no_docker", default=False, help=("Run Galaxy tools in Docker if enabled."))
930+
return _compose(
931+
planemo_option("--docker/--no_docker", default=False, help=("Run Galaxy tools in Docker if enabled.")),
932+
planemo_option(
933+
"--singularity/--no_singularity", default=False, help=("Run Galaxy tools in Singularity if enabled.")
934+
),
935+
)
918936

919937

920938
def docker_cmd_option():
921-
return planemo_option(
922-
"--docker_cmd",
923-
default=docker_util.DEFAULT_DOCKER_COMMAND,
924-
help="Command used to launch docker (defaults to docker).",
939+
return _compose(
940+
planemo_option(
941+
"--docker_cmd",
942+
default=docker_util.DEFAULT_DOCKER_COMMAND,
943+
help=f"Command used to launch docker (defaults to {docker_util.DEFAULT_DOCKER_COMMAND}).",
944+
),
945+
planemo_option(
946+
"--singularity_cmd",
947+
default=singularity_util.DEFAULT_SINGULARITY_COMMAND,
948+
help=f"Command used to launch singularity (defaults to {singularity_util.DEFAULT_SINGULARITY_COMMAND}).",
949+
),
925950
)
926951

927952

928953
def docker_sudo_option():
929-
return planemo_option("--docker_sudo/--no_docker_sudo", is_flag=True, help="Flag to use sudo when running docker.")
954+
return _compose(
955+
planemo_option("--docker_sudo/--no_docker_sudo", is_flag=True, help="Flag to use sudo when running docker."),
956+
planemo_option(
957+
"--singularity_sudo/--no_singularity_sudo", is_flag=True, help="Flag to use sudo when running singularity."
958+
),
959+
)
930960

931961

932962
def docker_sudo_cmd_option():
933-
return planemo_option(
934-
"--docker_sudo_cmd",
935-
help="sudo command to use when --docker_sudo is enabled " + "(defaults to sudo).",
936-
default=docker_util.DEFAULT_SUDO_COMMAND,
937-
use_global_config=True,
963+
return _compose(
964+
planemo_option(
965+
"--docker_sudo_cmd",
966+
help=f"sudo command to use when --docker_sudo is enabled (defaults to {docker_util.DEFAULT_SUDO_COMMAND}).",
967+
default=docker_util.DEFAULT_SUDO_COMMAND,
968+
use_global_config=True,
969+
),
970+
planemo_option(
971+
"--singularity_sudo_cmd",
972+
help=f"sudo command to use when --singularity_sudo is enabled (defaults to {singularity_util.DEFAULT_SUDO_COMMAND}).",
973+
default=docker_util.DEFAULT_SUDO_COMMAND,
974+
use_global_config=True,
975+
),
938976
)
939977

940978

0 commit comments

Comments
 (0)