mirror of
https://github.com/odoo/runbot.git
synced 2025-03-16 07:55:45 +07:00
[IMP] runbot: dump database at the end of step
Dump a db at the end of a build, using a new 'finals' cmd part added in order to execute dump even if build fails. Add a link in last step log to download dump.
This commit is contained in:
parent
d869d22f7b
commit
d9b20d6961
@ -32,10 +32,11 @@ ENV COVERAGE_FILE /data/build/.coverage
|
||||
|
||||
|
||||
class Command():
|
||||
def __init__(self, pres, cmd, posts):
|
||||
def __init__(self, pres, cmd, posts, finals=None):
|
||||
self.pres = pres or []
|
||||
self.cmd = cmd
|
||||
self.posts = posts or []
|
||||
self.finals = finals or []
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.cmd, name)
|
||||
@ -44,14 +45,16 @@ class Command():
|
||||
return self.cmd[key]
|
||||
|
||||
def __add__(self, l):
|
||||
return Command(self.pres, self.cmd + l, self.posts)
|
||||
return Command(self.pres, self.cmd + l, self.posts, self.finals)
|
||||
|
||||
def build(self):
|
||||
cmd_chain = []
|
||||
cmd_chain += [' '.join(pre) for pre in self.pres if pre]
|
||||
cmd_chain.append(' '.join(self))
|
||||
cmd_chain += [' '.join(post) for post in self.posts if post]
|
||||
return ' && '.join(cmd_chain)
|
||||
cmd_chain = [' && '.join(cmd_chain)]
|
||||
cmd_chain += [' '.join(final) for final in self.finals if final]
|
||||
return ' ; '.join(cmd_chain)
|
||||
|
||||
|
||||
def docker_build(log_path, build_dir):
|
||||
@ -138,7 +141,7 @@ def docker_get_gateway_ip():
|
||||
def docker_ps():
|
||||
"""Return a list of running containers names"""
|
||||
docker_ps = subprocess.run(['docker', 'ps', '--format', '{{.Names}}'], stderr=subprocess.DEVNULL, stdout=subprocess.PIPE)
|
||||
if docker_ps.returncode !=0:
|
||||
if docker_ps.returncode != 0:
|
||||
return []
|
||||
return docker_ps.stdout.decode().strip().split('\n')
|
||||
|
||||
|
@ -642,7 +642,8 @@ class runbot_build(models.Model):
|
||||
if ending_build:
|
||||
build.update_build_end()
|
||||
|
||||
step_end_message = 'Step %s finished in %s' % (build.job, s2human(build.job_time))
|
||||
step_end_message = 'Step %s finished in %s $$fa-download$$' % (build.job, s2human(build.job_time))
|
||||
step_end_link = 'http://%s/runbot/static/build/%s/logs/%s-%s.sql.gz' % (build.host, build.dest, build.dest, build.active_step.db_name)
|
||||
build.write(build_values)
|
||||
|
||||
if ending_build:
|
||||
@ -652,7 +653,7 @@ class runbot_build(models.Model):
|
||||
build._logger("No result set, setting ok by default")
|
||||
|
||||
if notify_end_job:
|
||||
build._log('end_job', step_end_message)
|
||||
build._log('end_job', step_end_message, log_type='link', path=step_end_link)
|
||||
else:
|
||||
build._logger(step_end_message)
|
||||
|
||||
|
@ -334,6 +334,8 @@ class ConfigStep(models.Model):
|
||||
|
||||
cmd.posts.append(self._post_install_command(build, modules_to_install, py_version)) # coverage post, extra-checks, ...
|
||||
|
||||
cmd.finals.append(['pg_dump', db_name, '|', 'gzip', '>', '/data/build/logs/%s.sql.gz' % db_name])
|
||||
|
||||
max_timeout = int(self.env['ir.config_parameter'].get_param('runbot.runbot_timeout', default=10000))
|
||||
timeout = min(self.cpu_limit, max_timeout)
|
||||
return docker_run(cmd.build(), log_path, build._path(), build._get_docker_name(), cpu_limit=timeout, ro_volumes=exports)
|
||||
|
@ -6,7 +6,7 @@ from odoo import models, fields, api, tools
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
TYPES = [(t, t.capitalize()) for t in 'client server runbot subbuild'.split()]
|
||||
TYPES = [(t, t.capitalize()) for t in 'client server runbot subbuild link'.split()]
|
||||
|
||||
|
||||
class runbot_event(models.Model):
|
||||
|
@ -259,15 +259,26 @@
|
||||
<t t-foreach="logs" t-as="l">
|
||||
<tr t-att-class="dict(ERROR='danger', WARNING='warning', OK='success', SEPARATOR='separator').get(l.level)">
|
||||
<td style="white-space: nowrap;"><t t-esc="l.create_date"/></td>
|
||||
<td><b t-if="l.level != 'SEPARATOR'" t-esc="l.level"/></td>
|
||||
<td><t t-if="l.level != 'SEPARATOR'" t-esc="l.type"/></td>
|
||||
<td><b t-if="l.level != 'SEPARATOR' and l.type != 'link'" t-esc="l.level"/></td>
|
||||
<td><t t-if="l.level != 'SEPARATOR' and l.type != 'link'" t-esc="l.type"/></td>
|
||||
<td>
|
||||
<t t-if="l.type != 'runbot'">
|
||||
<t t-if="l.type not in ('runbot', 'link')">
|
||||
<a t-if="l.type == 'subbuild'" t-attf-href="/runbot/build/{{l.path}}">Sub build #<t t-esc="l.path"/></a>
|
||||
<a t-else="" t-attf-href="https://{{repo.base}}/blob/{{build['name']}}/{{l.path}}#L{{l.line}}"><t t-esc="l.name"/>:<t t-esc="l.line"/></a> <t t-esc="l.func"/>
|
||||
</t>
|
||||
<t t-if="'\n' not in l.message" t-esc="l.message"/>
|
||||
<pre t-if="'\n' in l.message" style="margin:0;padding:0; border: none;"><t t-esc="l.message"/></pre>
|
||||
<t t-if="l.type == 'link' and len(l.message.split('$$')) == 3">
|
||||
<t t-set="message" t-value="l.message.split('$$')"/>
|
||||
<t t-if="message[1].startswith('fa-')">
|
||||
<t t-esc="message[0]"/><a t-attf-href="{{l.path}}"><i t-attf-class="fa {{message[1]}}"/></a><t t-esc="message[2]"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="message[0]"/><a t-attf-href="{{l.path}}"><t t-esc="message[1]"/></a><t t-esc="message[2]"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="'\n' not in l.message" t-esc="l.message"/>
|
||||
<pre t-if="'\n' in l.message" style="margin:0;padding:0; border: none;"><t t-esc="l.message"/></pre>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
@ -107,7 +107,8 @@ class TestBuildConfigStep(common.TransactionCase):
|
||||
cmds = cmd.split(' && ')
|
||||
self.assertEqual(cmds[0], 'sudo pip3 install -r bar/requirements.txt')
|
||||
self.assertEqual(cmds[1].split(' bar/server.py')[0], 'python3 -m coverage run --branch --source /data/build --omit *__manifest__.py')
|
||||
self.assertEqual(cmds[2], 'python3 -m coverage html -d /data/build/coverage --ignore-errors')
|
||||
self.assertEqual(cmds[2].split(' ; ')[0], 'python3 -m coverage html -d /data/build/coverage --ignore-errors')
|
||||
self.assertEqual(cmds[2].split(' ; ')[1], 'pg_dump %s-coverage | gzip > /data/build/logs/%s-coverage.sql.gz' % (self.parent_build.dest, self.parent_build.dest))
|
||||
self.assertEqual(log_path, 'dev/null/logpath')
|
||||
|
||||
mock_docker_run.side_effect = docker_run
|
||||
|
Loading…
Reference in New Issue
Block a user