[FIX] runbot: use a custom template to create db

Since cb05f2b9d8, when creating a database, the template1 is used, this
allows to customize the template and install some needed Postgress
extensions.

Unfortunately, it's also a source of build failures. For example, if the
pg_activity util is used on a runbot host, database creation may fail
with a message like this:

source database "template1" is being accessed by other users

It's because pg_activity needs a database and uses template1.

With this commit, template1 is still used by default but can be changed
with a system parameter. That way, a custom template can be created on
runbot hosts and used when creating DB in builds.
This commit is contained in:
Christophe Monniez 2020-02-10 16:45:34 +01:00 committed by XavierDo
parent c816ba2161
commit 3e7d98a6b8
4 changed files with 26 additions and 3 deletions

View File

@ -17,6 +17,7 @@ from odoo.exceptions import UserError, ValidationError
from odoo.http import request
from odoo.tools import appdirs
from collections import defaultdict
from psycopg2 import sql
from subprocess import CalledProcessError
_logger = logging.getLogger(__name__)
@ -863,10 +864,12 @@ class runbot_build(models.Model):
subprocess.call(cmd)
def _local_pg_createdb(self, dbname):
icp = self.env['ir.config_parameter']
db_template = icp.get_param('runbot.runbot_db_template', default='template1')
self._local_pg_dropdb(dbname)
_logger.debug("createdb %s", dbname)
with local_pgadmin_cursor() as local_cr:
local_cr.execute("""CREATE DATABASE "%s" TEMPLATE template1 LC_COLLATE 'C' ENCODING 'unicode'""" % dbname)
local_cr.execute(sql.SQL("""CREATE DATABASE {} TEMPLATE %s LC_COLLATE 'C' ENCODING 'unicode'""").format(sql.Identifier(dbname)), (db_template,))
def _log(self, func, message, level='INFO', log_type='runbot', path='runbot'):
self.ensure_one()

View File

@ -47,6 +47,18 @@ class RunboHost(models.Model):
values['disp_name'] = values['name']
return super().create(values)
def _bootstrap_db_template(self):
""" boostrap template database if needed """
icp = self.env['ir.config_parameter']
db_template = icp.get_param('runbot.runbot_db_template', default='template1')
if db_template and db_template != 'template1':
with local_pgadmin_cursor() as local_cr:
local_cr.execute("""SELECT datname FROM pg_catalog.pg_database WHERE datname = '%s';""" % db_template)
res = local_cr.fetchone()
if not res:
local_cr.execute("""CREATE DATABASE "%s" TEMPLATE template1 LC_COLLATE 'C' ENCODING 'unicode'""" % db_template)
# TODO UPDATE pg_database set datallowconn = false, datistemplate = true (but not enough privileges)
def _bootstrap(self):
""" Create needed directories in static """
dirs = ['build', 'nginx', 'repo', 'sources', 'src', 'docker']
@ -54,6 +66,7 @@ class RunboHost(models.Model):
static_dirs = {d: os.path.join(static_path, d) for d in dirs}
for dir, path in static_dirs.items():
os.makedirs(path, exist_ok=True)
self._bootstrap_db_template()
def _docker_build(self):
""" build docker image """

View File

@ -15,6 +15,7 @@ class ResConfigSettings(models.TransientModel):
runbot_max_age = fields.Integer('Max branch age (in days)')
runbot_logdb_uri = fields.Char('Runbot URI for build logs')
runbot_update_frequency = fields.Integer('Update frequency (in seconds)')
runbot_template = fields.Char('Postgresql template', help="Postgresql template to use when creating DB's")
runbot_message = fields.Text('Frontend warning message')
@api.model
@ -29,7 +30,8 @@ class ResConfigSettings(models.TransientModel):
runbot_max_age=int(get_param('runbot.runbot_max_age', default=30)),
runbot_logdb_uri=get_param('runbot.runbot_logdb_uri', default=False),
runbot_update_frequency=int(get_param('runbot.runbot_update_frequency', default=10)),
runbot_message = get_param('runbot.runbot_message', default=''),
runbot_template=get_param('runbot.runbot_db_template'),
runbot_message=get_param('runbot.runbot_message', default=''),
)
return res
@ -44,4 +46,5 @@ class ResConfigSettings(models.TransientModel):
set_param("runbot.runbot_max_age", self.runbot_max_age)
set_param("runbot.runbot_logdb_uri", self.runbot_logdb_uri)
set_param('runbot.runbot_update_frequency', self.runbot_update_frequency)
set_param('runbot.runbot_db_template', self.runbot_template)
set_param('runbot.runbot_message', self.runbot_message)

View File

@ -50,9 +50,13 @@
<label for="runbot_update_frequency" class="col-xs-3 o_light_label" style="width: 60%;"/>
<field name="runbot_update_frequency" style="width: 30%;"/>
</div>
<div class="mt-16 row">
<label for="runbot_template" class="col-xs-3 o_light_label" style="width: 60%;"/>
<field name="runbot_template" style="width: 30%;"/>
</div>
<div class="mt-16 row">
<label for="runbot_message" class="col-xs-3 o_light_label" style="width: 60%;"/>
<field name="runbot_message" style="width: 30%;"/>
<field name="runbot_message" style="width: 100%;"/>
</div>
</div>
</div>