hobo: improve flexibility in postgresql initial deployment (#15573)

This commit is contained in:
Frédéric Péters 2017-03-23 11:05:21 +01:00
parent 9a7deaf742
commit 32d3e15686
3 changed files with 78 additions and 15 deletions

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import collections
import copy
import cPickle
import json
import os
@ -331,7 +332,7 @@ def test_deploy():
cleanup()
WcsPublisher.APP_DIR = alt_tempdir
fd = open(os.path.join(alt_tempdir, 'hobo.json'), 'w')
hobo_json = HOBO_JSON.copy()
hobo_json = copy.deepcopy(HOBO_JSON)
del hobo_json['services'][1] # authentic
fd.write(json.dumps(HOBO_JSON))
fd.close()
@ -356,3 +357,54 @@ def test_deploy():
['http://wcs.example.net/', os.path.join(alt_tempdir, 'hobo.json')])
pub_cfg = cPickle.load(open(os.path.join(alt_tempdir, 'wcs.example.net', 'config.pck')))
assert pub_cfg['language'] == {'language': 'fr'}
def test_configure_postgresql():
cleanup()
WcsPublisher.APP_DIR = alt_tempdir
fd = open(os.path.join(alt_tempdir, 'hobo.json'), 'w')
hobo_json = copy.deepcopy(HOBO_JSON)
del hobo_json['services'][1] # authentic
fd.write(json.dumps(HOBO_JSON))
fd.close()
service = [x for x in HOBO_JSON.get('services', []) if x.get('service-id') == 'wcs'][0]
hobo_cmd = CmdCheckHobos()
base_options = collections.namedtuple('Options', ['configfile'])(configfile=None)
sub_options_class = collections.namedtuple('Options',
['ignore_timestamp', 'redeploy', 'extra'])
sub_options = sub_options_class(True, False, None)
sys.modules['publisher'] = sys.modules['wcs.publisher']
hobo_cmd.execute(base_options, sub_options,
['http://wcs.example.net/', os.path.join(alt_tempdir, 'hobo.json')])
assert os.path.exists(os.path.join(alt_tempdir, 'wcs.example.net'))
fd = file(os.path.join(alt_tempdir, 'wcs.example.net', 'site-options.cfg'), 'w')
fd.write('[options]\n')
fd.write('postgresql = true\n')
fd.close()
cleanup()
pub = WcsPublisher.create_publisher(register_cron=False, register_tld_names=False)
pub.app_dir = os.path.join(alt_tempdir, 'wcs.example.net')
pub.cfg['postgresql'] = {
'createdb-connection-params': {
'user': 'test',
'database': 'postgres'
},
'database-template-name': 'tests_wcs_%s',
'user': 'fred'
}
pub.write_cfg()
pub.set_config(skip_sql=True)
service['base_url'] = service['base_url'].strip('/')
with mock.patch('psycopg2.connect') as connect:
with mock.patch('subprocess.call') as call:
hobo_cmd.configure_sql(service, pub)
assert connect.call_args_list[0][1] == {'user': 'test', 'database': 'postgres'}
assert connect.call_args_list[1][1] == {'user': 'fred', 'database': 'tests_wcs_wcs_example_net'}
assert call.call_args[0][0][1:] == ['convert-to-sql',
'--dbname', 'tests_wcs_wcs_example_net',
'--user', 'fred', 'wcs.example.net']

View File

@ -124,11 +124,11 @@ class CmdCheckHobos(Command):
print ' skipping'
return
pub.set_config()
self.update_configuration(service, pub)
self.configure_authentication_methods(service, pub)
pub.set_config(skip_sql=True)
if new_site:
self.configure_sql(service, pub)
self.update_configuration(service, pub)
self.configure_authentication_methods(service, pub)
self.update_profile(self.all_services.get('profile', {}), pub)
# Store hobo.json
@ -282,7 +282,7 @@ class CmdCheckHobos(Command):
parsed_url = urllib2.urlparse.urlsplit(service.get('base_url'))
instance_path = parsed_url.netloc
if parsed_url.path:
instance_path = '%s+' % parsed_url.path.replace('/', '+')
instance_path += '+%s' % parsed_url.path.replace('/', '+')
return instance_path
def configure_site_options(self, current_service, pub, ignore_timestamp=False):
@ -383,21 +383,31 @@ class CmdCheckHobos(Command):
import psycopg2
import psycopg2.errorcodes
# determine database name using the instance path; if the template
# database name contained an underscore character, use the first part
# as a prefix to the database name
database_name = pub.cfg['postgresql'].get('database', 'wcs')
# determine database name using the instance path
domain_table_name = self.get_instance_path(service).replace(
'-', '_').replace('.', '_').replace('+', '_')
if not domain_table_name in database_name:
database_name = '%s_%s' % (database_name.split('_')[0], domain_table_name)
if pub.cfg['postgresql'].get('database-template-name'):
database_template_name = pub.cfg['postgresql'].pop('database-template-name')
database_name = (database_template_name % domain_table_name).strip('_')
else:
# legacy way to create a database name, if it contained an
# underscore character, use the first part as a prefix
database_name = pub.cfg['postgresql'].get('database', 'wcs')
if not domain_table_name in database_name:
database_name = '%s_%s' % (database_name.split('_')[0], domain_table_name)
postgresql_cfg = {}
for k, v in pub.cfg['postgresql'].items():
if v:
if v and isinstance(v, basestring):
postgresql_cfg[k] = v
createdb_cfg = pub.cfg['postgresql'].get('createdb-connection-params')
if not createdb_cfg:
createdb_cfg = postgresql_cfg
try:
pgconn = psycopg2.connect(**postgresql_cfg)
pgconn = psycopg2.connect(**createdb_cfg)
except psycopg2.Error as e:
print >> sys.stderr, 'failed to connect to postgresql (%s)' % \
psycopg2.errorcodes.lookup(e.pgcode)
@ -421,6 +431,7 @@ class CmdCheckHobos(Command):
postgresql_cfg['database'] = database_name
pub.cfg['postgresql'] = postgresql_cfg
pub.write_cfg()
pub.set_config(skip_sql=False)
if not new_database:
return

View File

@ -123,7 +123,7 @@ class WcsPublisher(StubWcsPublisher):
def is_using_postgresql(self):
return bool(self.has_site_option('postgresql') and self.cfg.get('postgresql', {}))
def set_config(self, request = None):
def set_config(self, request=None, skip_sql=False):
QommonPublisher.set_config(self, request = request)
filename = os.path.join(self.app_dir, 'config.pck')
if os.path.exists(filename):
@ -150,7 +150,7 @@ class WcsPublisher(StubWcsPublisher):
import wcs.workflows
wcs.workflows.load_extra()
if self.is_using_postgresql():
if self.is_using_postgresql() and not skip_sql:
import sql
self.user_class = sql.SqlUser
self.tracking_code_class = sql.TrackingCode