diff --git a/runbot/__manifest__.py b/runbot/__manifest__.py index 5085df56..84d15e5d 100644 --- a/runbot/__manifest__.py +++ b/runbot/__manifest__.py @@ -6,7 +6,7 @@ 'author': "Odoo SA", 'website': "http://runbot.odoo.com", 'category': 'Website', - 'version': '5.9', + 'version': '5.10', 'application': True, 'depends': ['base', 'base_automation', 'website'], 'data': [ diff --git a/runbot/container.py b/runbot/container.py index 4134c9d3..0687f82e 100644 --- a/runbot/container.py +++ b/runbot/container.py @@ -137,6 +137,24 @@ def _docker_build(build_dir, image_tag): return dm.result +def docker_tag(identifier_or_tag, new_tag): + return _docker_tag(identifier_or_tag, new_tag) + +def _docker_tag(identifier_or_tag, new_tag): + if not identifier_or_tag: + return + _logger.info('Tagging image %s to "%s"', identifier_or_tag, new_tag) + docker_client = docker.from_env() + repo, tag = new_tag.split(':') # runbot DockerFile tags contains the repo part + try: + image = docker_client.images.get(identifier_or_tag) + image.tag(repo, tag) + except docker.errors.ImageNotFound: + _logger.warning('failed to find docker image with identifier %s', identifier_or_tag) + except docker.errors.APIError: + _logger.warning('failed to retag docker image with identifier %s', identifier_or_tag) + + def docker_push(image_tag, push_url='127.0.0.1:5001'): return _docker_push(image_tag, push_url) diff --git a/runbot/data/dockerfile_data.xml b/runbot/data/dockerfile_data.xml index 9e384bc6..c131f8a6 100644 --- a/runbot/data/dockerfile_data.xml +++ b/runbot/data/dockerfile_data.xml @@ -199,4 +199,15 @@ ENV PIP_BREAK_SYSTEM_PACKAGES=1 RUN python3 -m pip install --no-cache-dir -r /tmp/requirements.txt + + Sync Identifiers + + + ir.actions.server + code + + records.action_sync_identifiers() + + + diff --git a/runbot/migrations/18.0.5.10/post-migration.py b/runbot/migrations/18.0.5.10/post-migration.py new file mode 100644 index 00000000..d1449926 --- /dev/null +++ b/runbot/migrations/18.0.5.10/post-migration.py @@ -0,0 +1,14 @@ +import logging + +_logger = logging.getLogger(__name__) + +def migrate(cr, version): + cr.execute(""" + UPDATE runbot_dockerfile + SET image_identifier = subq.identifier, image_future_identifier = subq.identifier + FROM (SELECT DISTINCT ON (dockerfile_id) dockerfile_id, identifier + FROM runbot_docker_build_result + WHERE result='success' order by dockerfile_id, create_date desc) + AS subq + WHERE runbot_dockerfile.id = subq.dockerfile_id; + """) diff --git a/runbot/models/build.py b/runbot/models/build.py index c191d9c9..9c0673c0 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -853,6 +853,8 @@ class BuildResult(models.Model): ro_volumes[f'/data/build/{dest}'] = source if 'image_tag' not in kwargs: kwargs.update({'image_tag': self.params_id.dockerfile_id.image_tag}) + if self.params_id.config_data.get('docker_use_future') and not kwargs['image_tag'].endswith('.future'): + kwargs['image_tag'] = self.params_id.dockerfile_id.image_future_tag self._log('Preparing', 'Using Dockerfile Tag [%s](/runbot/dockerfile/tag/%s)', kwargs['image_tag'], kwargs['image_tag'], log_type='markdown') docker_registry_url = self.host_id._get_docker_registry_url() if docker_registry_url and self.host_id.use_remote_docker_registry: diff --git a/runbot/models/docker.py b/runbot/models/docker.py index 6c407b2a..59821502 100644 --- a/runbot/models/docker.py +++ b/runbot/models/docker.py @@ -124,7 +124,10 @@ class Dockerfile(models.Model): name = fields.Char('Dockerfile name', required=True, help="Name of Dockerfile") active = fields.Boolean('Active', default=True, tracking=True) + image_identifier = fields.Char('Identifier') + image_future_identifier = fields.Char('Future Identifier') image_tag = fields.Char(compute='_compute_image_tag', store=True) + image_future_tag = fields.Char(compute='_compute_image_future_tag') template_id = fields.Many2one('ir.ui.view', string='Docker Template', domain=[('type', '=', 'qweb')], context={'default_type': 'qweb', 'default_arch_base': ''}) arch_base = fields.Text(related='template_id.arch_base', readonly=False, related_sudo=True) dockerfile = fields.Text(compute='_compute_dockerfile', tracking=True) @@ -198,12 +201,22 @@ class Dockerfile(models.Model): if rec.name: rec.image_tag = 'odoo:%s' % re.sub(r'[ /:\(\)\[\]]', '', rec.name) + @api.depends('image_tag') + def _compute_image_future_tag(self): + for rec in self: + rec.image_future_tag = f'{rec.image_tag}.future' + @api.depends('template_id') def _compute_view_ids(self): for rec in self: keys = re.findall(r' + + + @@ -97,7 +100,7 @@ runbot.dockerfile.list runbot.dockerfile - + diff --git a/runbot/views/res_config_settings_views.xml b/runbot/views/res_config_settings_views.xml index 745fdf5f..f6d864b7 100644 --- a/runbot/views/res_config_settings_views.xml +++ b/runbot/views/res_config_settings_views.xml @@ -97,6 +97,9 @@ + + +