Skip to content
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

Use load instead of push to support remote builders #94

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions buildrunner/docker/multiplatform_image_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from platform import machine, system
import shutil
import tempfile
import uuid
from typing import Dict, List, Optional

import python_on_whales
Expand Down Expand Up @@ -239,7 +240,6 @@ def _build_with_inject(
inject: dict,
tagged_names: List[str],
platform: str,
push: bool,
path: str,
file: str,
build_args: dict,
Expand Down Expand Up @@ -273,7 +273,7 @@ def _build_with_inject(
context_dir,
tags=tagged_names,
platforms=[platform],
push=push,
load=True,
file=file,
builder=builder,
build_args=build_args
Expand Down Expand Up @@ -324,7 +324,6 @@ def _build_single_image(
inject=inject,
tagged_names=tagged_names,
platform=platform,
push=push,
path=path,
file=file,
build_args=build_args,
Expand All @@ -335,11 +334,14 @@ def _build_single_image(
path,
tags=tagged_names,
platforms=[platform],
push=push,
load=True,
file=file,
build_args=build_args,
builder=builder,
)
# Push after the initial load to support remote builders that cannot access the local registry
if push:
docker.push(tagged_names)

# Check that the images were built and in the registry
# Docker search is not currently implemented in python-on-wheels
Expand Down Expand Up @@ -444,7 +446,7 @@ def get_path(file):

# Updates name to be compatible with docker
image_prefix = "buildrunner-mp"
sanitized_name = f"{image_prefix}-{mp_image_name.replace('/', '-').replace(':', '-')}"
sanitized_name = f"{image_prefix}-{str(uuid.uuid4())}"
base_image_name = f"{self._mp_registry_info.ip_addr}:{self._mp_registry_info.port}/{sanitized_name}"

# Keeps track of the built images {name: [ImageInfo(image_names)]]}
Expand Down
37 changes: 26 additions & 11 deletions tests/test_multiplatform.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@
# FIXME: These tests can be broken if a custom buildx builder is set as default # pylint: disable=fixme


@pytest.fixture(autouse=True)
def fixture_uuid_mock():
with patch('buildrunner.docker.multiplatform_image_builder.uuid') as uuid_mock:
counter = 0
def _get_uuid():
nonlocal counter
counter += 1
return f'uuid{counter}'

uuid_mock.uuid4.side_effect = _get_uuid
yield uuid_mock


def actual_images_match_expected(actual_images, expected_images) -> List[str]:
missing_images = []
found = False
Expand Down Expand Up @@ -187,7 +200,7 @@ def test_find_native_platform(mock_os,
@pytest.mark.parametrize("name, platforms, expected_image_names",[
('test-image-tag-2000',
['linux/arm64'],
['test-image-tag-2000-linux-arm64']
['buildrunner-mp-uuid1-linux-arm64']
)])
def test_tag_single_platform(name, platforms, expected_image_names):
tag='latest'
Expand Down Expand Up @@ -221,7 +234,7 @@ def test_tag_single_platform(name, platforms, expected_image_names):
@pytest.mark.parametrize("name, platforms, expected_image_names",[
('test-image-tag-2000',
['linux/arm64'],
['test-image-tag-2000-linux-arm64']
['buildrunner-mp-uuid1-linux-arm64']
)])
def test_tag_single_platform_multiple_tags(name, platforms, expected_image_names):
tags=['latest', '0.1.0']
Expand Down Expand Up @@ -256,7 +269,7 @@ def test_tag_single_platform_multiple_tags(name, platforms, expected_image_names
@pytest.mark.parametrize("name, platforms, expected_image_names",[
('test-image-tag-2000',
['linux/arm64'],
['test-image-tag-2000-linux-arm64']
['buildrunner-mp-uuid1-linux-arm64']
)])
def test_tag_single_platform_keep_images(name, platforms, expected_image_names):
tag='latest'
Expand Down Expand Up @@ -377,18 +390,19 @@ def test_push_with_dest_names():
@pytest.mark.parametrize("name, platforms, expected_image_names",[
('test-build-image-2000',
['linux/arm64'],
['test-build-image-2000-linux-arm64']
['buildrunner-mp-uuid1-linux-arm64']
),
('test-build-image-2001',
['linux/amd64', 'linux/arm64'],
['test-build-image-2001-linux-amd64', 'test-build-image-2001-linux-arm64']
['buildrunner-mp-uuid1-linux-amd64', 'buildrunner-mp-uuid1-linux-arm64']
)
])
@patch('buildrunner.docker.multiplatform_image_builder.docker.image.remove')
@patch('buildrunner.docker.multiplatform_image_builder.docker.image.inspect')
@patch('buildrunner.docker.multiplatform_image_builder.docker.push')
@patch('buildrunner.docker.multiplatform_image_builder.docker.image.pull')
@patch('buildrunner.docker.multiplatform_image_builder.docker.buildx.build')
def test_build(mock_build, mock_pull, mock_inspect, mock_remove, name, platforms, expected_image_names):
def test_build(mock_build, mock_pull, mock_push, mock_inspect, mock_remove, name, platforms, expected_image_names):
mock_inspect.return_value = MagicMock()
mock_inspect.return_value.id = 'myfakeimageid'
test_path = f'{TEST_DIR}/test-files/multiplatform'
Expand All @@ -408,18 +422,19 @@ def test_build(mock_build, mock_pull, mock_inspect, mock_remove, name, platforms

@patch('buildrunner.docker.multiplatform_image_builder.docker.image.remove')
@patch('buildrunner.docker.multiplatform_image_builder.docker.image.inspect')
@patch('buildrunner.docker.multiplatform_image_builder.docker.push')
@patch('buildrunner.docker.multiplatform_image_builder.docker.image.pull')
@patch('buildrunner.docker.multiplatform_image_builder.docker.buildx.build')
def test_build_multiple_builds(mock_build, mock_pull, mock_inspect, mock_remove):
def test_build_multiple_builds(mock_build, mock_pull, mock_push, mock_inspect, mock_remove):
mock_inspect.return_value = MagicMock()
mock_inspect.return_value.id = 'myfakeimageid'
name1 = 'test-build-multi-image-2001'
platforms1 = ['linux/amd64', 'linux/arm64']
expected_image_names1 = ['test-build-multi-image-2001-linux-amd64', 'test-build-multi-image-2001-linux-arm64']
expected_image_names1 = ['buildrunner-mp-uuid1-linux-amd64', 'buildrunner-mp-uuid1-linux-arm64']

name2 = 'test-build-multi-image-2002'
platforms2 = ['linux/amd64', 'linux/arm64']
expected_image_names2 = ['test-build-multi-image-2002-linux-amd64', 'test-build-multi-image-2002-linux-arm64']
expected_image_names2 = ['buildrunner-mp-uuid2-linux-amd64', 'buildrunner-mp-uuid2-linux-arm64']

test_path = f'{TEST_DIR}/test-files/multiplatform'
with MultiplatformImageBuilder() as mp:
Expand Down Expand Up @@ -454,12 +469,12 @@ def test_build_multiple_builds(mock_build, mock_pull, mock_inspect, mock_remove)
('test-build-tag-image-2000',
['latest', '0.1.0'],
['linux/arm64'],
['test-build-tag-image-2000-linux-arm64']
['buildrunner-mp-uuid1-linux-arm64']
),
('test-build-tag-image-2001',
['latest', '0.2.0'],
['linux/amd64', 'linux/arm64'],
['test-build-tag-image-2001-linux-amd64', 'test-build-tag-image-2001-linux-arm64']
['buildrunner-mp-uuid1-linux-amd64', 'buildrunner-mp-uuid1-linux-arm64']
)
])
def test_build_with_tags(name, tags, platforms, expected_image_names):
Expand Down
Loading