diff --git a/buildrunner/docker/__init__.py b/buildrunner/docker/__init__.py index d7267e6..09e6843 100644 --- a/buildrunner/docker/__init__.py +++ b/buildrunner/docker/__init__.py @@ -107,7 +107,9 @@ def force_remove_container(docker_client, container): ) -def get_dockerfile(dockerfile: str, temp_dir: str = None) -> Tuple[str, bool]: +def get_dockerfile( + dockerfile: str, temp_dir: str = None, path: str = None +) -> Tuple[str, bool]: """ Check if the dockerfile exists, if not create a temporary file and write the dockerfile to it. :param dockerfile: the dockerfile @@ -117,7 +119,19 @@ def get_dockerfile(dockerfile: str, temp_dir: str = None) -> Tuple[str, bool]: cleanup_dockerfile = False curr_dockerfile = None - if dockerfile: + if path and path != "." and not dockerfile: + if os.path.exists(path): + if os.path.exists(os.path.join(path, "Dockerfile")): + curr_dockerfile = os.path.join(path, "Dockerfile") + else: + raise BuildRunnerConfigurationError( + f"Path {path} exists but does not contain a Dockerfile" + ) + else: + raise BuildRunnerConfigurationError( + f"Path {path} does not exist, cannot find Dockerfile" + ) + elif dockerfile: if os.path.exists(dockerfile): curr_dockerfile = dockerfile else: diff --git a/buildrunner/docker/multiplatform_image_builder.py b/buildrunner/docker/multiplatform_image_builder.py index 82e42ee..58fed9b 100644 --- a/buildrunner/docker/multiplatform_image_builder.py +++ b/buildrunner/docker/multiplatform_image_builder.py @@ -429,7 +429,7 @@ def build_multiple_images( else: path = "." - dockerfile, cleanup_dockerfile = get_dockerfile(file) + dockerfile, cleanup_dockerfile = get_dockerfile(dockerfile=file, path=path) # Track this newly built image built_image = BuiltImageInfo(id=str(uuid.uuid4())) diff --git a/buildrunner/sshagent/__init__.py b/buildrunner/sshagent/__init__.py index 7c04977..394056e 100644 --- a/buildrunner/sshagent/__init__.py +++ b/buildrunner/sshagent/__init__.py @@ -28,11 +28,12 @@ from paramiko.util import asbytes from paramiko.message import Message +import buildrunner.config +import buildrunner.docker.builder as legacy_builder from buildrunner.errors import ( BuildRunnerConfigurationError, BuildRunnerProcessingError, ) -import buildrunner.docker.builder as legacy_builder SSH_AGENT_PROXY_BUILD_CONTEXT = os.path.join( os.path.dirname(__file__), "SSHAgentProxyImage" @@ -88,7 +89,9 @@ class DockerSSHAgentProxy: implementation that is managed by this class. """ - def __init__(self, docker_client, log, docker_registry): + def __init__( + self, docker_client, log, docker_registry, multiplatform_image_builder + ): """ """ self.docker_client = docker_client self.log = log @@ -97,6 +100,7 @@ def __init__(self, docker_client, log, docker_registry): self._ssh_agent_container = None self._ssh_client = None self._ssh_channel = None + self._multiplatform_image_builder = multiplatform_image_builder def get_info(self): """ @@ -249,15 +253,33 @@ def get_ssh_agent_image(self): """ Get and/or create the image used to proxy the ssh agent to a container. """ + buildrunner_config = buildrunner.config.BuildRunnerConfig.get_instance() if not self._ssh_agent_image: - self.log.write("Creating ssh-agent image\n") - image = legacy_builder.build_image( - path=SSH_AGENT_PROXY_BUILD_CONTEXT, - docker_registry=self.docker_registry, - nocache=False, - pull=False, - ) - self._ssh_agent_image = image + if buildrunner_config.run_config.use_legacy_builder: + self.log.write("Creating ssh-agent image\n") + image = legacy_builder.build_image( + path=SSH_AGENT_PROXY_BUILD_CONTEXT, + docker_registry=self.docker_registry, + nocache=False, + pull=False, + ) + self._ssh_agent_image = image + else: + native_platform = ( + self._multiplatform_image_builder.get_native_platform() + ) + platforms = [native_platform] + built_images_info = ( + self._multiplatform_image_builder.build_multiple_images( + platforms=platforms, + path=SSH_AGENT_PROXY_BUILD_CONTEXT, + cache=False, + pull=False, + use_threading=False, + ) + ) + assert len(built_images_info.built_images) == 1 + self._ssh_agent_image = built_images_info.built_images[0].trunc_digest return self._ssh_agent_image diff --git a/buildrunner/steprunner/tasks/run.py b/buildrunner/steprunner/tasks/run.py index 618627a..c677b85 100644 --- a/buildrunner/steprunner/tasks/run.py +++ b/buildrunner/steprunner/tasks/run.py @@ -825,6 +825,7 @@ def run(self, context: dict): # pylint: disable=too-many-statements,too-many-br self._docker_client, self.step_runner.log, buildrunner_config.global_config.docker_registry, + self.step_runner.multi_platform, ) self._sshagent.start( buildrunner_config.get_ssh_keys_from_aliases( diff --git a/setup.py b/setup.py index 3df85fe..1b83eb5 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ from setuptools import setup, find_packages -BASE_VERSION = "3.12" +BASE_VERSION = "3.13" SOURCE_DIR = os.path.dirname(os.path.abspath(__file__)) BUILDRUNNER_DIR = os.path.join(SOURCE_DIR, "buildrunner") diff --git a/tests/test-files/test-ssh-buildx.yaml b/tests/test-files/test-ssh-buildx.yaml new file mode 100644 index 0000000..8bfb8c7 --- /dev/null +++ b/tests/test-files/test-ssh-buildx.yaml @@ -0,0 +1,17 @@ +use-legacy-builder: True +steps: + clone: + build: + dockerfile: | + FROM {{ DOCKER_REGISTRY }}/rockylinux:8.5 + RUN yum install -y git-core openssh-clients && yum clean all + run: + ssh-keys: ['buildrunner-deploy'] + cmds: + - mkdir ~/.ssh + - ssh-keyscan github.com > ~/.ssh/known_hosts + - chmod 700 ~/.ssh + - chmod 600 ~/.ssh/known_hosts + # Clone into temp directory since the "buildrunner" directory may already exist + - rm -rf /tmp/test-clone + - git clone git@github.com:adobe/buildrunner.git /tmp/test-clone diff --git a/tests/test_builders.py b/tests/test_builders.py index a258d48..605ce49 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -56,10 +56,10 @@ def fixture_set_env(): @pytest.mark.parametrize( - "use_legacy_builder, config,", + "description, use_legacy_builder, config,", [ - # Use default builder ( + "Use buildx builder with platform", False, """ use-legacy-builder: false @@ -74,6 +74,7 @@ def fixture_set_env(): """, ), ( + "Use buildx builder", False, """ use-legacy-builder: false @@ -87,6 +88,7 @@ def fixture_set_env(): """, ), ( + "Overwrite use-legacy-builder with platforms", False, """ use-legacy-builder: true @@ -103,6 +105,7 @@ def fixture_set_env(): """, ), ( + "Use buildx builder with platforms", False, """ use-legacy-builder: false @@ -119,6 +122,7 @@ def fixture_set_env(): """, ), ( + "Default builder with platforms", False, """ steps: @@ -133,8 +137,8 @@ def fixture_set_env(): - linux/arm64 """, ), - # Use legacy builder ( + "Default builder", True, """ steps: @@ -147,6 +151,7 @@ def fixture_set_env(): """, ), ( + "Use legacy builder with platform", True, """ use-legacy-builder: true @@ -161,6 +166,7 @@ def fixture_set_env(): """, ), ( + "Use legacy builder with use-legacy-builder", True, """ use-legacy-builder: true @@ -184,9 +190,11 @@ def fixture_set_env(): def test_builders( mock_buildx_builder, mock_legacy_build, + description, use_legacy_builder, config, ): + _ = description with tempfile.TemporaryDirectory() as tmpdirname: tmp_filename = f"{tmpdirname}/config.yaml" with open(tmp_filename, "w") as f: