Skip to content

Commit a526286

Browse files
committed
[FIX] runbot: do not use remote cursor for dropping local dbs
To find out the list of manually created dbs, rev. 4d94f45 used the cursor that is connected to the master `runbot` database, which may reside on a different cluster/host. - Add a helper to run commands on the local PG cluster instead ("postgres" database). - Modify other commands for local cluster (create/drop db) to use the same cursor. Rename those methods to _local_* to better indicate their local effect.
1 parent 8067425 commit a526286

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

runbot/runbot.py

+37-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- encoding: utf-8 -*-
22

3+
import contextlib
34
import datetime
45
import fcntl
56
import glob
@@ -8,6 +9,7 @@
89
import logging
910
import operator
1011
import os
12+
import psycopg2
1113
import re
1214
import resource
1315
import shutil
@@ -152,6 +154,18 @@ def uniq_list(l):
152154
def fqdn():
153155
return socket.getfqdn()
154156

157+
@contextlib.contextmanager
158+
def local_pgadmin_cursor():
159+
cnx, cr = None, None
160+
try:
161+
cnx = psycopg2.connect("dbname=postgres")
162+
cr = cnx.cursor()
163+
yield cr
164+
cnx.commit()
165+
finally:
166+
if cr: cr.close()
167+
if cnx: cnx.close()
168+
155169
#----------------------------------------------------------
156170
# RunBot Models
157171
#----------------------------------------------------------
@@ -797,17 +811,19 @@ def checkout(self, cr, uid, ids, context=None):
797811
build.write({'server_match': server_match,
798812
'modules': ','.join(modules_to_test)})
799813

800-
def pg_dropdb(self, cr, uid, dbname):
801-
run(['dropdb', dbname])
814+
def _local_pg_dropdb(self, cr, uid, dbname):
815+
with local_pgadmin_cursor() as local_cr:
816+
local_cr.execute('DROP DATABASE "%s" IF EXISTS' % dbname)
802817
# cleanup filestore
803818
datadir = appdirs.user_data_dir()
804819
paths = [os.path.join(datadir, pn, 'filestore', dbname) for pn in 'OpenERP Odoo'.split()]
805820
run(['rm', '-rf'] + paths)
806821

807-
def pg_createdb(self, cr, uid, dbname):
808-
self.pg_dropdb(cr, uid, dbname)
822+
def _local_pg_createdb(self, cr, uid, dbname):
823+
self._local_pg_dropdb(cr, uid, dbname)
809824
_logger.debug("createdb %s", dbname)
810-
run(['createdb', '--encoding=unicode', '--lc-collate=C', '--template=template0', dbname])
825+
with local_pgadmin_cursor() as local_cr:
826+
local_cr.execute("""CREATE DATABASE "%s" TEMPLATE template0 LC_COLLATE 'C' ENCODING 'unicode'""" % dbname)
811827

812828
def cmd(self, cr, uid, ids, context=None):
813829
"""Return a list describing the command to start the build"""
@@ -906,7 +922,7 @@ def job_00_init(self, cr, uid, build, lock_path, log_path):
906922
def job_10_test_base(self, cr, uid, build, lock_path, log_path):
907923
build._log('test_base', 'Start test base module')
908924
# run base test
909-
self.pg_createdb(cr, uid, "%s-base" % build.dest)
925+
self._local_pg_createdb(cr, uid, "%s-base" % build.dest)
910926
cmd, mods = build.cmd()
911927
if grep(build.server("tools/config.py"), "test-enable"):
912928
cmd.append("--test-enable")
@@ -915,7 +931,7 @@ def job_10_test_base(self, cr, uid, build, lock_path, log_path):
915931

916932
def job_20_test_all(self, cr, uid, build, lock_path, log_path):
917933
build._log('test_all', 'Start test all modules')
918-
self.pg_createdb(cr, uid, "%s-all" % build.dest)
934+
self._local_pg_createdb(cr, uid, "%s-all" % build.dest)
919935
cmd, mods = build.cmd()
920936
if grep(build.server("tools/config.py"), "test-enable"):
921937
cmd.append("--test-enable")
@@ -1075,24 +1091,27 @@ def schedule(self, cr, uid, ids, context=None):
10751091

10761092
# cleanup only needed if it was not killed
10771093
if build.state == 'done':
1078-
build.cleanup()
1094+
build._local_cleanup()
10791095

10801096
def skip(self, cr, uid, ids, context=None):
10811097
self.write(cr, uid, ids, {'state': 'done', 'result': 'skipped'}, context=context)
10821098
to_unduplicate = self.search(cr, uid, [('id', 'in', ids), ('duplicate_id', '!=', False)])
10831099
if len(to_unduplicate):
10841100
self.force(cr, uid, to_unduplicate, context=context)
10851101

1086-
def cleanup(self, cr, uid, ids, context=None):
1102+
def _local_cleanup(self, cr, uid, ids, context=None):
10871103
for build in self.browse(cr, uid, ids, context=context):
1088-
cr.execute("""
1089-
SELECT datname
1090-
FROM pg_database
1091-
WHERE pg_get_userbyid(datdba) = current_user
1092-
AND datname LIKE %s
1093-
""", [build.dest + '%'])
1094-
for db, in cr.fetchall():
1095-
self.pg_dropdb(cr, uid, db)
1104+
# Cleanup the *local* cluster
1105+
with local_pgadmin_cursor() as local_cr:
1106+
local_cr.execute("""
1107+
SELECT datname
1108+
FROM pg_database
1109+
WHERE pg_get_userbyid(datdba) = current_user
1110+
AND datname LIKE %s
1111+
""", [build.dest + '%'])
1112+
to_delete = local_cr.fetchall()
1113+
for db, in to_delete:
1114+
self._local_pg_dropdb(cr, uid, db)
10961115

10971116
if os.path.isdir(build.path()) and build.result != 'killed':
10981117
shutil.rmtree(build.path())
@@ -1111,7 +1130,7 @@ def kill(self, cr, uid, ids, result=None, context=None):
11111130
build.write(v)
11121131
cr.commit()
11131132
build.github_status()
1114-
build.cleanup()
1133+
build._local_cleanup()
11151134

11161135
def reap(self, cr, uid, ids):
11171136
while True:

0 commit comments

Comments
 (0)