Skip to content

Commit 4cc4d4a

Browse files
authored
added --container-engine (#206)
Co-authored-by: Jake Fennick <[email protected]>
1 parent a59bbf6 commit 4cc4d4a

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

cwl_utils/docker_extract.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ def arg_parser() -> argparse.ArgumentParser:
3232
help="Use singularity to pull the image",
3333
action="store_true",
3434
)
35+
parser.add_argument(
36+
"--container-engine",
37+
dest="container_engine",
38+
default="docker",
39+
help="Specify which command to use to run OCI containers.",
40+
)
3541
return parser
3642

3743

@@ -51,9 +57,13 @@ def run(args: argparse.Namespace) -> int:
5157
print(f"Unable to save image from {req} due to lack of 'dockerPull'.")
5258
continue
5359
if args.singularity:
54-
image_puller: ImagePuller = SingularityImagePuller(req.dockerPull, args.dir)
60+
image_puller: ImagePuller = SingularityImagePuller(
61+
req.dockerPull, args.dir, "singularity"
62+
)
5563
else:
56-
image_puller = DockerImagePuller(req.dockerPull, args.dir)
64+
image_puller = DockerImagePuller(
65+
req.dockerPull, args.dir, args.container_engine
66+
)
5767
image_puller.save_docker_image()
5868
return 0
5969

cwl_utils/image_puller.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515

1616

1717
class ImagePuller(ABC):
18-
def __init__(self, req: str, save_directory: str) -> None:
18+
def __init__(self, req: str, save_directory: str, cmd: str) -> None:
1919
"""Create an ImagePuller."""
2020
self.req = req
2121
self.save_directory = save_directory
22+
self.cmd = cmd
2223

2324
@abstractmethod
2425
def get_image_name(self) -> str:
@@ -45,7 +46,11 @@ class DockerImagePuller(ImagePuller):
4546

4647
def get_image_name(self) -> str:
4748
"""Get the name of the tarball."""
48-
return "".join(self.req.split("/")) + ".tar"
49+
name = "".join(self.req.split("/")) + ".tar"
50+
# Replace colons with underscores in the name.
51+
# See https://github.com/containers/podman/issues/489
52+
name = name.replace(":", "_")
53+
return name
4954

5055
def generate_udocker_loading_command(self) -> str:
5156
"""Generate the udocker loading command."""
@@ -54,10 +59,10 @@ def generate_udocker_loading_command(self) -> str:
5459
def save_docker_image(self) -> None:
5560
"""Download and save the software container image to disk as a docker tarball."""
5661
_LOGGER.info(f"Pulling {self.req} with Docker...")
57-
cmd_pull = ["docker", "pull", self.req]
62+
cmd_pull = [self.cmd, "pull", self.req]
5863
ImagePuller._run_command_pull(cmd_pull)
5964
cmd_save = [
60-
"docker",
65+
self.cmd,
6166
"save",
6267
"-o",
6368
os.path.join(self.save_directory, self.get_image_name()),
@@ -76,9 +81,9 @@ class SingularityImagePuller(ImagePuller):
7681
CHARS_TO_REPLACE = ["/"]
7782
NEW_CHAR = "_"
7883

79-
def __init__(self, req: str, save_directory: str) -> None:
84+
def __init__(self, req: str, save_directory: str, cmd: str) -> None:
8085
"""Create a Singularity-based software container image downloader."""
81-
super().__init__(req, save_directory)
86+
super().__init__(req, save_directory, cmd)
8287

8388
def get_image_name(self) -> str:
8489
"""Determine the file name appropriate to the installed version of Singularity."""
@@ -99,7 +104,7 @@ def save_docker_image(self) -> None:
99104
"""Pull down the Docker container image in the Singularity image format."""
100105
_LOGGER.info(f"Pulling {self.req} with Singularity...")
101106
cmd_pull = [
102-
"singularity",
107+
self.cmd,
103108
"pull",
104109
"--name",
105110
os.path.join(self.save_directory, self.get_image_name()),

tests/test_docker_extract.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,22 @@ def test_traverse_workflow() -> None:
2424
assert len(reqs) == 1
2525
for req in reqs:
2626
assert req.dockerPull
27-
image_puller = DockerImagePuller(req.dockerPull, tmpdir)
27+
image_puller = DockerImagePuller(req.dockerPull, tmpdir, "docker")
28+
image_puller.save_docker_image()
29+
_ = image_puller.generate_udocker_loading_command()
30+
31+
32+
@mark.skipif(which("podman") is None, reason="podman is not available")
33+
def test_traverse_workflow_podman() -> None:
34+
"""Test container extraction tool using Podman."""
35+
loaded = parser.load_document(TEST_CWL)
36+
37+
with TemporaryDirectory() as tmpdir:
38+
reqs = set(traverse(loaded))
39+
assert len(reqs) == 1
40+
for req in reqs:
41+
assert req.dockerPull
42+
image_puller = DockerImagePuller(req.dockerPull, tmpdir, "podman")
2843
image_puller.save_docker_image()
2944
_ = image_puller.generate_udocker_loading_command()
3045

@@ -39,5 +54,5 @@ def test_traverse_workflow_singularity() -> None:
3954
assert len(reqs) == 1
4055
for req in reqs:
4156
assert req.dockerPull
42-
image_puller = SingularityImagePuller(req.dockerPull, tmpdir)
57+
image_puller = SingularityImagePuller(req.dockerPull, tmpdir, "singularity")
4358
image_puller.save_docker_image()

0 commit comments

Comments
 (0)