From 96824046b0844e241497b54c9568f4963abc8090 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Mon, 19 Jan 2026 12:18:29 +0100 Subject: [PATCH] [IMP] runbot: make parent_id a params Some build will use the parent to restore a database, this commits makes taht more explicit by storing the parent as a param when needed. --- runbot/models/build.py | 19 ++++++++++++++++--- runbot/models/build_config.py | 23 ++++++++++++++++++++--- runbot/views/build_views.xml | 1 + 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/runbot/models/build.py b/runbot/models/build.py index ef77696e8..947458008 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -101,6 +101,7 @@ class BuildParameters(models.Model): build_ids = fields.One2many('runbot.build', 'params_id') builds_reference_ids = fields.Many2many('runbot.build', relation='runbot_build_params_references', copy=True) + reference_build_id = fields.Many2one('runbot.build', 'Reference Build', index=True) modules = fields.Char('Modules') upgrade_to_build_id = fields.Many2one('runbot.build', index=True) # use to define sources to use with upgrade script @@ -146,6 +147,8 @@ def get_commit_links_ident(commit_link): 'dockerfile_id': param.dockerfile_id.id, 'skip_requirements': param.skip_requirements, } + if param.reference_build_id: + cleaned_vals['reference_build_id'] = param.reference_build_id.id if param.upgrade_to_build_id: cleaned_vals['upgrade_to_build_dockerfile_id'] = param.upgrade_to_build_id.params_id.dockerfile_id.id cleaned_vals['upgrade_to_build_commits'] = get_commit_links_ident(param.upgrade_to_build_id.params_id.commit_link_ids) @@ -526,7 +529,7 @@ def write(self, values): return res - def _add_child(self, param_values, orphan=False, description=False, additionnal_commit_links=False): + def _add_child(self, param_values, orphan=False, description=False, additionnal_commit_links=False, use_parent=...): build_values = {key: value for key, value in param_values.items() if key not in self.params_id._fields} param_values = {key: value for key, value in param_values.items() if key in self.params_id._fields} @@ -539,6 +542,15 @@ def _add_child(self, param_values, orphan=False, description=False, additionnal_ commit_link_ids |= additionnal_commit_links param_values['commit_link_ids'] = commit_link_ids + config = param_values.get('config_id') or self.params_id.config_id + if isinstance(config, int): + config = self.env['runbot.build.config'].browse(config) + + if use_parent == ...: + use_parent = config._default_uses_parent(param_values) + if use_parent: + param_values['reference_build_id'] = self.id + return self.create({ 'params_id': self.params_id.copy(param_values).id, 'parent_id': self.id, @@ -1397,8 +1409,9 @@ def _cmd(self, python_params=None, py_version=None, local_only=True, sub_command faketime = [] if faketime_params := self.params_id.config_data.get('faketime'): - if self.parent_id: - parent_time_offset = (self.parent_id.build_end or self.create_date) - self.parent_id.build_start + reference_build = self.params_id.reference_build_id or self.parent_id # TODO cleanup parent_id + if reference_build: + parent_time_offset = (reference_build.build_end or self.create_date) - reference_build.build_start faketime_params = (parser.parse(faketime_params) + parent_time_offset).strftime('%Y-%m-%d %H:%M %Z') faketime = ['faketime', faketime_params] diff --git a/runbot/models/build_config.py b/runbot/models/build_config.py index 8371b3f4b..40bc993a9 100644 --- a/runbot/models/build_config.py +++ b/runbot/models/build_config.py @@ -306,6 +306,7 @@ def VARS(vars, path): 'max_builds': OPTIONAL(INT), 'if': OPTIONAL(DYNAMIC_VALUE), 'log': OPTIONAL(DYNAMIC_VALUE), + 'use_parent': OPTIONAL(BOOL), } valid_steps['restore'] = { 'name': REQUIRED(NAME), @@ -382,6 +383,18 @@ def _check_recursion(self, visited=None): for create_config in step.create_config_ids: create_config._check_recursion(visited[:]) + def _default_uses_parent(self, param_values): + if param_values.get('dump_db'): + return False + config_data = param_values.get('config_data', {}) or {} + if config_data.get('dump_url'): + return False + if config_data.get('restore_build_id'): + return False + if config_data.get('dump_trigger_id'): + return False + return any(step.job_type == 'restore' for step in self.step_ids) + class ConfigStepUpgradeDb(models.Model): _name = 'runbot.config.step.upgrade.db' @@ -600,7 +613,7 @@ def _run_step(self, build, **kwargs): return build._docker_run(self, **docker_params) return True - def _run_create_build(self, build, config_data=None, max_build=200): + def _run_create_build(self, build, config_data=None, max_build=200, use_parent=...): if config_data: config_data = {**config_data, **build.params_id.config_data} else: @@ -624,7 +637,7 @@ def _run_create_build(self, build, config_data=None, max_build=200): build._log('create_build', f'More than {max_build} build created, stopping', level='WARNING') return config_name = config_name or create_config.name - child = build._add_child(child_data_values, orphan=self.make_orphan, description=description or config_name) + child = build._add_child(child_data_values, orphan=self.make_orphan, description=description or config_name, use_parent=use_parent) build._log('create_build', 'created with config %s' % config_name, log_type='subbuild', path=str(child.id)) def _make_python_ctx(self, build): @@ -1136,7 +1149,7 @@ def _run_restore(self, build, config_data=None): dump_build = dump_db.build_id else: download_db_suffix = config_data.get('dump_suffix', self.restore_download_db_suffix or 'all') - dump_build = build.parent_id + dump_build = params.reference_build_id or build.parent_id # TODO cleanup parent_id assert download_db_suffix and dump_build download_db_name = '%s-%s' % (dump_build.dest, download_db_suffix) zip_name = '%s.zip' % download_db_name @@ -1618,11 +1631,15 @@ def _run_dynamic(self, build): 'config_name': config_name, 'description': description, } + if current_step.get('use_parent') or (current_step.get('use_parent') is None and any(step.get('job_type') == 'restore' for step in child.get('steps', []))): + # TODO improve, not needed is other restore params are given + child_data['reference_build_id'] = build.id child_data_list.append(child_data) return self._run_create_build( build, {'child_data': child_data_list, 'number_build': current_step.get('number_builds', 1)}, max_build=min(current_step.get('max_builds', 20), 200), + use_parent=current_step.get('use_parent', ...) ) if current_step['job_type'] == 'restore': diff --git a/runbot/views/build_views.xml b/runbot/views/build_views.xml index ce996e5b4..0d60ab89b 100644 --- a/runbot/views/build_views.xml +++ b/runbot/views/build_views.xml @@ -12,6 +12,7 @@ +