[REM] runbot: drop cron support

The runbot uses leader and builder processes for a while, mainly because
cron are not adapted for such work. Because of memory limit, lack of
controll of execution on multiple hosts, ... The cron was not tested for
a while since only the leader and builder scripts are used.

This commit removes the cron support from the runbot module for easier
maintenance.
This commit is contained in:
Xavier-Do 2025-02-13 09:14:44 +01:00
parent 0594c71c18
commit 9420a9e6c0
5 changed files with 4 additions and 117 deletions

View File

@ -97,14 +97,4 @@ admin_passwd=running_master_password</field>
records.write({'no_build': False}) records.write({'no_build': False})
</field> </field>
</record> </record>
<record id="ir_cron_runbot" model="ir.cron">
<field name="name">Runbot</field>
<field name="active" eval="False"/>
<field name="interval_number">10</field>
<field name="interval_type">seconds</field>
<field name="model_id" ref="model_runbot_runbot"/>
<field name="code">model._cron()</field>
<field name="state">code</field>
</record>
</odoo> </odoo>

View File

@ -196,53 +196,6 @@ class Runbot(models.AbstractModel):
else: else:
_logger.warning('failed to start nginx - failed to kill orphan worker - oh well') _logger.warning('failed to start nginx - failed to kill orphan worker - oh well')
def _get_cron_period(self):
""" Compute a randomized cron period with a 2 min margin below
real cron timeout from config.
"""
cron_limit = config.get('limit_time_real_cron')
req_limit = config.get('limit_time_real')
cron_timeout = cron_limit if cron_limit > -1 else req_limit
return cron_timeout / 2
def _cron(self):
"""
This method is the default cron for new commit discovery and build sheduling.
The cron runs for a long time to avoid spamming logs
"""
pull_info_failures = {}
start_time = time.time()
timeout = self._get_cron_period()
get_param = self.env['ir.config_parameter'].get_param
update_frequency = int(get_param('runbot.runbot_update_frequency', default=10))
runbot_do_fetch = get_param('runbot.runbot_do_fetch')
runbot_do_schedule = get_param('runbot.runbot_do_schedule')
host = self.env['runbot.host']._get_current()
host._set_psql_conn_count()
host.last_start_loop = fields.Datetime.now()
self._commit()
# Bootstrap
host._bootstrap()
if runbot_do_schedule:
host._docker_update_images()
self._source_cleanup()
self.env['runbot.build']._local_cleanup()
self._docker_cleanup()
_logger.info('Starting loop')
if runbot_do_schedule or runbot_do_fetch:
while time.time() - start_time < timeout:
if runbot_do_fetch:
self._fetch_loop_turn(host, pull_info_failures)
if runbot_do_schedule:
sleep_time = self._scheduler_loop_turn(host, update_frequency)
time.sleep(sleep_time)
else:
time.sleep(update_frequency)
self._commit()
host.last_end_loop = fields.Datetime.now()
def _fetch_loop_turn(self, host, pull_info_failures, default_sleep=1): def _fetch_loop_turn(self, host, pull_info_failures, default_sleep=1):
with self._manage_host_exception(host) as manager: with self._manage_host_exception(host) as manager:
repos = self.env['runbot.repo'].search([('mode', '!=', 'disabled')]) repos = self.env['runbot.repo'].search([('mode', '!=', 'disabled')])

View File

@ -133,16 +133,16 @@
<span t-out="end_time"/> <span t-out="end_time"/>
</span> </span>
<t t-set="cron_time" t-value="end_time-start_time"/> <t t-set="loop_time" t-value="end_time-start_time"/>
<t t-set="klass">success</t> <t t-set="klass">success</t>
<t t-if="abs(cron_time) > 10"> <t t-if="abs(loop_time) > 10">
<t t-set="klass">info</t> <t t-set="klass">info</t>
</t> </t>
<t t-if="abs(cron_time) > 60"> <t t-if="abs(loop_time) > 60">
<t t-set="klass">danger</t> <t t-set="klass">danger</t>
</t> </t>
<span t-attf-class="badge text-bg-{{klass}}"> <span t-attf-class="badge text-bg-{{klass}}">
<span t-out="cron_time"/> <span t-out="loop_time"/>
</span> </span>
</div> </div>

View File

@ -5,7 +5,6 @@ from . import test_build_error
from . import test_branch from . import test_branch
from . import test_build from . import test_build
from . import test_schedule from . import test_schedule
from . import test_cron
from . import test_build_config_step from . import test_build_config_step
from . import test_event from . import test_event
from . import test_command from . import test_command

View File

@ -1,55 +0,0 @@
# -*- coding: utf-8 -*-
from unittest.mock import patch
from .common import RunbotCase
class SleepException(Exception):
...
def sleep(time):
raise SleepException()
class TestCron(RunbotCase):
def setUp(self):
super(TestCron, self).setUp()
self.start_patcher('list_local_dbs_patcher', 'odoo.addons.runbot.models.host.list_local_dbs', ['runbot_logs'])
self.start_patcher('_get_cron_period', 'odoo.addons.runbot.models.runbot.Runbot._get_cron_period', 2)
@patch('time.sleep', side_effect=sleep)
@patch('odoo.addons.runbot.models.repo.Repo._update_batches')
def test_cron_schedule(self, mock_update_batches, *args):
""" test that cron_fetch_and_schedule do its work """
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_update_frequency', 1)
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_do_fetch', True)
self.env['runbot.repo'].search([('id', '!=', self.repo_server.id)]).write({'mode': 'disabled'}) # disable all other existing repo than repo_server
try:
self.Runbot._cron()
except SleepException:
pass # sleep raises an exception to avoid to stay stuck in loop
mock_update_batches.assert_called()
@patch('time.sleep', side_effect=sleep)
@patch('odoo.addons.runbot.models.host.Host._docker_update_images')
@patch('odoo.addons.runbot.models.host.Host._bootstrap')
@patch('odoo.addons.runbot.models.runbot.Runbot._scheduler')
def test_cron_build(self, mock_scheduler, mock_host_bootstrap, mock_host_docker_update_images, *args):
""" test that cron_fetch_and_build do its work """
hostname = 'cronhost.runbot.com'
self.patchers['hostname_patcher'].return_value = hostname
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_update_frequency', 1)
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_do_schedule', True)
self.env['runbot.repo'].search([('id', '!=', self.repo_server.id)]).write({'mode': 'disabled'}) # disable all other existing repo than repo_server
try:
self.Runbot._cron()
except SleepException:
pass # sleep raises an exception to avoid to stay stuck in loop
mock_scheduler.assert_called()
mock_host_bootstrap.assert_called()
mock_host_docker_update_images.assert_called()
host = self.env['runbot.host'].search([('name', '=', hostname)])
self.assertTrue(host, 'A new host should have been created')
# self.assertGreater(host.psql_conn_count, 0, 'A least one connection should exist on the current psql batch')