From 8bf7864c3a7a1012704deafff1f0b2ef43c04e55 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Wed, 29 Jan 2025 11:15:08 +0100 Subject: [PATCH] [IMP] runbot: allow to specify a custom docker registry --- runbot/container.py | 8 ++++---- runbot/models/build.py | 7 +++---- runbot/models/host.py | 25 +++++++++++++++++++++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/runbot/container.py b/runbot/container.py index 06c5d14f..4134c9d3 100644 --- a/runbot/container.py +++ b/runbot/container.py @@ -137,11 +137,11 @@ def _docker_build(build_dir, image_tag): return dm.result -def docker_push(image_tag): - return _docker_push(image_tag) +def docker_push(image_tag, push_url='127.0.0.1:5001'): + return _docker_push(image_tag, push_url) -def _docker_push(image_tag): +def _docker_push(image_tag, push_url): """Push a Docker image to the localy hosted docker registry :param image_tag: the image tag (or id) to push :return: tuple(success, msg) where success is a boolean and msg is the error message or None @@ -149,7 +149,7 @@ def _docker_push(image_tag): with DockerManager(image_tag) as dm: image = dm.docker_client.images.get(image_tag) - push_tag = f'127.0.0.1:5001/{image_tag}' + push_tag = f'{push_url}/{image_tag}' image.tag(push_tag) for chunk in dm.consume(dm.docker_client.api.push(push_tag, stream=True)): if not dm.log_progress and 'Pushing' in chunk.get('status', ''): diff --git a/runbot/models/build.py b/runbot/models/build.py index 9daa3d73..7f6edfe1 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -853,10 +853,9 @@ class BuildResult(models.Model): if 'image_tag' not in kwargs: kwargs.update({'image_tag': self.params_id.dockerfile_id.image_tag}) self._log('Preparing', 'Using Dockerfile Tag [%s](/runbot/dockerfile/tag/%s)', kwargs['image_tag'], kwargs['image_tag'], log_type='markdown') - icp = self.env['ir.config_parameter'] - docker_registry_host = self.env['runbot.host'].browse(int(icp.get_param('runbot.docker_registry_host_id', default=0))) - if docker_registry_host and self.host_id.use_remote_docker_registry: - result = docker_pull(f"dockerhub.{docker_registry_host.name}/{kwargs['image_tag']}") + docker_registry_url = self.host_id._get_docker_registry_url() + if docker_registry_url and self.host_id.use_remote_docker_registry: + result = docker_pull(f"{docker_registry_url}/{kwargs['image_tag']}") if result['success']: result['image'].tag(kwargs['image_tag']) if result.get('log_progress'): diff --git a/runbot/models/host.py b/runbot/models/host.py index 3535a58f..2740b267 100644 --- a/runbot/models/host.py +++ b/runbot/models/host.py @@ -121,21 +121,32 @@ class Host(models.Model): self._bootstrap_db_template() self._bootstrap_local_logs_db() + def _get_docker_registry_url(self): + if self.docker_registry_url: + return self.docker_registry_url + icp = self.env['ir.config_parameter'] + docker_registry_url = icp.get_param('runbot.docker_registry_url', default=None) + if docker_registry_url: + return docker_registry_url.strip('/') + docker_registry_host = self.browse(int(icp.get_param('runbot.docker_registry_host_id', default=0))) + if docker_registry_host: + return f'dockerhub.{docker_registry_host.name}'.strip('/') + def _docker_update_images(self): """ build docker images needed by locally pending builds""" self.ensure_one() icp = self.env['ir.config_parameter'] docker_registry_host = self.browse(int(icp.get_param('runbot.docker_registry_host_id', default=0))) - registry_url = self.docker_registry_url.strip('/') if self.docker_registry_url else f'dockerhub.{docker_registry_host.name}' + docker_registry_url = self._get_docker_registry_url() # pull all images from the runbot docker registry is_registry = docker_registry_host == self all_docker_files = self.env['runbot.dockerfile'].search([]) all_tags = set(all_docker_files.mapped('image_tag')) - if docker_registry_host and self.use_remote_docker_registry and not is_registry: + if docker_registry_url and self.use_remote_docker_registry and not is_registry: _logger.info('Pulling docker images...') total_duration = 0 for dockerfile in all_docker_files.filtered('always_pull'): - remote_tag = f'{registry_url}/{dockerfile.image_tag}' + remote_tag = f'{docker_registry_url}/{dockerfile.image_tag}' result = docker_pull(remote_tag) if result['success']: result['image'].tag(dockerfile.image_tag) @@ -149,7 +160,13 @@ class Host(models.Model): dockerfile._build(self) if is_registry: try: - docker_push(dockerfile.image_tag) + docker_push(dockerfile.image_tag) # for now, always push locally + if self.docker_registry_url: + docker_registry_url = self.docker_registry_url + else: + docker_registry_url = icp.get_param('runbot.docker_registry_url', default='').strip('/') + if docker_registry_url: + docker_push(dockerfile.image_tag, docker_registry_url) except ImageNotFound: _logger.warning("Image tag `%s` not found. Skipping push", dockerfile.image_tag)