diff --git a/runbot/container.py b/runbot/container.py
index 86c51180..06c5d14f 100644
--- a/runbot/container.py
+++ b/runbot/container.py
@@ -166,7 +166,7 @@ def _docker_pull(image_tag):
"""Pull a docker image from a registry.
:param image_tag: the full image tag, including the registry host
e.g.: `dockerhub.runbot102.odoo.com/odoo:PureNobleTest`
- :return: tuple(success, image) where success is a boolean and image a Docker image object or None in case of failure
+ :return: DockerMager.result dict
"""
with DockerManager(image_tag) as dm:
for chunk in dm.consume(dm.docker_client.api.pull(image_tag, stream=True)):
diff --git a/runbot/docker_manager.py b/runbot/docker_manager.py
index 1c298bcb..08072e1e 100644
--- a/runbot/docker_manager.py
+++ b/runbot/docker_manager.py
@@ -57,6 +57,7 @@ class DockerManager:
def __exit__(self, exception_type, exception_value, exception_traceback):
if self.log_progress:
_logger.info('Finished in %.2fs', self.duration)
+ self.result['log_progress'] = self.log_progress
if exception_value:
self.result['success'] = False
_logger.warning(exception_value)
diff --git a/runbot/models/build.py b/runbot/models/build.py
index 11d0fd56..e546125d 100644
--- a/runbot/models/build.py
+++ b/runbot/models/build.py
@@ -16,7 +16,7 @@ from psycopg2 import sql
from psycopg2.extensions import TransactionRollbackError
from ..common import dt2time, now, grep, local_pgadmin_cursor, s2human, dest_reg, os, list_local_dbs, pseudo_markdown, RunbotException, findall, sanitize, markdown_escape
-from ..container import docker_stop, docker_state, Command, docker_run
+from ..container import docker_stop, docker_state, Command, docker_run, docker_pull
from ..fields import JsonDictField
from odoo import models, fields, api
@@ -853,6 +853,15 @@ 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']}")
+ if result['success']:
+ result['image'].tag(kwargs['image_tag'])
+ if result.get('log_progress'):
+ self._log('Docker Run', f'Docker image was pulled {"" if result["success"] else "with errors"}')
+
containers_memory_limit = self.env['ir.config_parameter'].sudo().get_param('runbot.runbot_containers_memory', 0)
if containers_memory_limit and 'memory' not in kwargs:
kwargs['memory'] = int(float(containers_memory_limit) * 1024 ** 3)
diff --git a/runbot/models/docker.py b/runbot/models/docker.py
index c5d6e774..c61971a9 100644
--- a/runbot/models/docker.py
+++ b/runbot/models/docker.py
@@ -128,6 +128,7 @@ class Dockerfile(models.Model):
arch_base = fields.Text(related='template_id.arch_base', readonly=False, related_sudo=True)
dockerfile = fields.Text(compute='_compute_dockerfile', tracking=True)
to_build = fields.Boolean('To Build', help='Build Dockerfile. Check this when the Dockerfile is ready.', default=False)
+ always_pull = fields.Boolean('Always pull', help='Always Pull on the hosts, not only at the use time', default=False, tracking=True)
version_ids = fields.One2many('runbot.version', 'dockerfile_id', string='Versions')
description = fields.Text('Description')
view_ids = fields.Many2many('ir.ui.view', compute='_compute_view_ids', groups="runbot.group_runbot_admin")
diff --git a/runbot/models/host.py b/runbot/models/host.py
index a0dd7b89..d3cdc1d9 100644
--- a/runbot/models/host.py
+++ b/runbot/models/host.py
@@ -130,11 +130,16 @@ class Host(models.Model):
all_tags = set(all_docker_files.mapped('image_tag'))
if docker_registry_host and self.use_remote_docker_registry and not is_registry:
_logger.info('Pulling docker images...')
- for dockerfile in all_docker_files:
+ total_duration = 0
+ for dockerfile in all_docker_files.filtered('always_pull'):
remote_tag = f'dockerhub.{docker_registry_host.name}/{dockerfile.image_tag}'
result = docker_pull(remote_tag)
if result['success']:
result['image'].tag(dockerfile.image_tag)
+ total_duration += result['duration']
+ if total_duration > 60:
+ _logger.warning("Pulling images took more than 60 seconds... will continue later")
+ break
else:
_logger.info('Building docker images...')
for dockerfile in self.env['runbot.dockerfile'].search([('to_build', '=', True)]):
diff --git a/runbot/views/dockerfile_views.xml b/runbot/views/dockerfile_views.xml
index b7b6d1f7..ec6e0e49 100644
--- a/runbot/views/dockerfile_views.xml
+++ b/runbot/views/dockerfile_views.xml
@@ -13,6 +13,7 @@
+
@@ -104,6 +105,8 @@
+
+