Skip to content

Commit

Permalink
#518 Add platform option for push and pull
Browse files Browse the repository at this point in the history
  • Loading branch information
d4nj1 committed Jan 3, 2024
1 parent e2f959f commit e4b966e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
33 changes: 22 additions & 11 deletions python_on_whales/components/image/cli_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def prune(self, all: bool = False, filter: Dict[str, str] = {}) -> str:
return run(full_cmd)

def pull(
self, x: Union[str, List[str]], quiet: bool = False
self, x: Union[str, List[str]], quiet: bool = False, platform: str = ""
) -> Union[Image, List[Image]]:
"""Pull one or more docker image(s)
Expand All @@ -488,6 +488,7 @@ def pull(
The progress bars might look strange as multiple
processes are drawing on the terminal at the same time.
quiet: If you don't want to see the progress bars.
platform: If you want to enforce a platform.
Returns:
The Docker image loaded (`python_on_whales.Image` object).
Expand All @@ -498,28 +499,31 @@ def pull(
if x == []:
return []
elif isinstance(x, str):
return self._pull_single_tag(x, quiet=quiet)
return self._pull_single_tag(x, quiet=quiet, platform=platform)
elif isinstance(x, list) and len(x) == 1:
return [self._pull_single_tag(x[0], quiet=quiet)]
return [self._pull_single_tag(x[0], quiet=quiet, platform=platform)]
elif len(x) >= 2:
pool = ThreadPool(4)
generator = self._generate_args_push_pull(x, quiet)
generator = self._generate_args_push_pull(x, quiet, platform)
all_images = pool.starmap(self._pull_single_tag, generator)
pool.close()
pool.join()
return all_images

def _pull_single_tag(self, image_name: str, quiet: bool):
def _pull_single_tag(self, image_name: str, quiet: bool, platform: str):
full_cmd = self.docker_cmd + ["image", "pull"]

if quiet:
full_cmd.append("--quiet")

if platform:
full_cmd.append(f"--platform={platform}")

full_cmd.append(image_name)
run(full_cmd, capture_stdout=quiet, capture_stderr=quiet)
return Image(self.client_config, image_name)

def push(self, x: Union[str, List[str]], quiet: bool = False):
def push(self, x: Union[str, List[str]], quiet: bool = False, platform: str = ""):
"""Push a tag or a repository to a registry
Alias: `docker.push(...)`
Expand All @@ -530,6 +534,7 @@ def push(self, x: Union[str, List[str]], quiet: bool = False):
multiple threads. The progress bars might look strange as multiple
processes are drawing on the terminal at the same time.
quiet: If you don't want to see the progress bars.
platform: If you want to enforce a platform.
# Raises
`python_on_whales.exceptions.NoSuchImage` if one of the images does not exists.
Expand All @@ -542,21 +547,27 @@ def push(self, x: Union[str, List[str]], quiet: bool = False):
if x == []:
return
elif len(x) == 1:
self._push_single_tag(x[0], quiet=quiet)
self._push_single_tag(x[0], quiet=quiet, platform=platform)
elif len(x) >= 2:
pool = ThreadPool(4)
generator = self._generate_args_push_pull(x, quiet)
generator = self._generate_args_push_pull(x, quiet, platform)
pool.starmap(self._push_single_tag, generator)
pool.close()
pool.join()

def _generate_args_push_pull(self, _list: List[str], quiet: bool):
def _generate_args_push_pull(self, _list: List[str], quiet: bool, platform: str):
for tag in _list:
yield tag, quiet
yield tag, quiet, platform

def _push_single_tag(self, tag_or_repo: str, quiet: bool):
def _push_single_tag(self, tag_or_repo: str, quiet: bool, platform: str):
full_cmd = self.docker_cmd + ["image", "push"]

if quiet:
full_cmd.append("--quiet")

if platform:
full_cmd.append(f"--platform={platform}")

full_cmd.append(tag_or_repo)
run(full_cmd, capture_stdout=quiet, capture_stderr=quiet)

Expand Down
8 changes: 4 additions & 4 deletions tests/python_on_whales/components/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ def with_manifest():

@pytest.fixture
def with_platform_variant_manifest(request):
image_with_platform_variant = "arm64v8/busybox:1.35"
image_with_platform_variant = "arm32v7/busybox:1.35"

def remove_docker_image():
docker.image.remove(image_with_platform_variant)

request.addfinalizer(remove_docker_image)
docker.image.pull(image_with_platform_variant, quiet=True)
docker.image.pull(image_with_platform_variant, quiet=True, platform="linux/arm/v7")
return docker.image.inspect(image_with_platform_variant)


Expand Down Expand Up @@ -63,5 +63,5 @@ def test_manifest_annotate(with_manifest):

def test_manifest_platform_variant(with_platform_variant_manifest):
assert "linux" in repr(with_platform_variant_manifest.os)
assert "arm64" in repr(with_platform_variant_manifest.architecture)
assert "v8" in repr(with_platform_variant_manifest.variant)
assert "arm" in repr(with_platform_variant_manifest.architecture)
assert "v7" in repr(with_platform_variant_manifest.variant)

0 comments on commit e4b966e

Please sign in to comment.