# HG changeset patch # User Sylvain Thénault # Date 1244817199 -7200 # Node ID 92ea410806fe0fcea0656cc4ec3dedc6fc5693a4 # Parent b4ffcea3275ba8b63d0b539b4107851e17e34b98 refactor sources configuration, add source to sources when using a cube defining a source diff -r b4ffcea3275b -r 92ea410806fe devtools/migrtest.py --- a/devtools/migrtest.py Fri Jun 12 16:31:32 2009 +0200 +++ b/devtools/migrtest.py Fri Jun 12 16:33:19 2009 +0200 @@ -42,14 +42,14 @@ from logilab.common.shellutils import cp, rm from cubicweb.toolsutils import read_config -from cubicweb.server.serverctl import generate_sources_file +from cubicweb.server.utils import generate_sources_file # XXXX use db-copy instead # test environment configuration chrootpath = '/sandbox/cubicwebtest' tmpdbhost = 'crater' -tmpdbuser = 'syt' +tmpdbuser = 'syt' tmpdbpasswd = 'syt' def play_migration(applhome, applhost='', sudo=False): diff -r b4ffcea3275b -r 92ea410806fe server/serverconfig.py --- a/server/serverconfig.py Fri Jun 12 16:31:32 2009 +0200 +++ b/server/serverconfig.py Fri Jun 12 16:33:19 2009 +0200 @@ -10,14 +10,50 @@ import os from os.path import join, exists -from logilab.common.configuration import Method +from logilab.common.configuration import Method, Configuration, \ + ini_format_section from logilab.common.decorators import wproperty, cached, clear_cache from cubicweb import CW_SOFTWARE_ROOT, RegistryNotFound -from cubicweb.toolsutils import env_path, read_config +from cubicweb.toolsutils import env_path, read_config, restrict_perms_to_user from cubicweb.cwconfig import CubicWebConfiguration, merge_options +def generate_sources_file(sourcesfile, sourcescfg, keys=None): + """serialize repository'sources configuration into a INI like file + + the `keys` parameter may be used to sort sections + """ + if keys is None: + keys = sourcescfg.keys() + else: + for key in sourcescfg: + if not key in keys: + keys.append(key) + stream = open(sourcesfile, 'w') + for uri in keys: + sconfig = sourcescfg[uri] + if isinstance(sconfig, dict): + # get a Configuration object + _sconfig = Configuration(options=SOURCE_TYPES[sconfig['adapter']].options) + for attr, val in sconfig.items(): + if attr == 'uri': + continue + if attr == 'adapter': + _sconfig.adapter = val + else: + _sconfig.set_option(attr, val) + sconfig = _sconfig + optsbysect = list(sconfig.options_by_section()) + assert len(optsbysect) == 1, 'all options for a source should be in the same group' + ini_format_section(stream, uri, optsbysect[0][1]) + if hasattr(sconfig, 'adapter'): + print >> stream + print >> stream, '# adapter for this source (YOU SHOULD NOT CHANGE THIS)' + print >> stream, 'adapter=%s' % sconfig.adapter + print >> stream + + class ServerConfiguration(CubicWebConfiguration): """standalone RQL server""" name = 'repository' @@ -188,16 +224,24 @@ # restricted user, this user usually don't have access to the sources # configuration file (#16102) @cached + def read_sources_file(self): + return read_config(self.sources_file()) + def sources(self): """return a dictionnaries containing sources definitions indexed by sources'uri """ - allsources = read_config(self.sources_file()) + allsources = self.read_sources_file() if self._enabled_sources is None: return allsources return dict((uri, config) for uri, config in allsources.items() if uri in self._enabled_sources or uri == 'admin') + def write_sources_file(self, sourcescfg): + sourcesfile = self.sources_file() + generate_sources_file(sourcesfile, sourcescfg, ['admin', 'system']) + restrict_perms_to_user(sourcesfile) + def pyro_enabled(self): """pyro is always enabled in standalone repository configuration""" return True diff -r b4ffcea3275b -r 92ea410806fe server/serverctl.py --- a/server/serverctl.py Fri Jun 12 16:31:32 2009 +0200 +++ b/server/serverctl.py Fri Jun 12 16:33:19 2009 +0200 @@ -10,12 +10,13 @@ import sys import os -from logilab.common.configuration import REQUIRED, Configuration, ini_format_section +from logilab.common.configuration import REQUIRED, Configuration from logilab.common.clcommands import register_commands, cmd_run, pop_arg from cubicweb import AuthenticationError, ExecutionError, ConfigurationError -from cubicweb.toolsutils import (Command, CommandHandler, confirm, - restrict_perms_to_user) +from cubicweb.toolsutils import Command, CommandHandler, confirm +from cubicweb.server import SOURCE_TYPES +from cubicweb.server.utils import ask_source_config from cubicweb.server.serverconfig import ServerConfiguration @@ -92,41 +93,6 @@ pass return cnx -def generate_sources_file(sourcesfile, sourcescfg, keys=None): - """serialize repository'sources configuration into a INI like file - - the `keys` parameter may be used to sort sections - """ - from cubicweb.server.sources import SOURCE_TYPES - if keys is None: - keys = sourcescfg.keys() - else: - for key in sourcescfg: - if not key in keys: - keys.append(key) - stream = open(sourcesfile, 'w') - for uri in keys: - sconfig = sourcescfg[uri] - if isinstance(sconfig, dict): - # get a Configuration object - _sconfig = Configuration(options=SOURCE_TYPES[sconfig['adapter']].options) - for attr, val in sconfig.items(): - if attr == 'uri': - continue - if attr == 'adapter': - _sconfig.adapter = val - else: - _sconfig.set_option(attr, val) - sconfig = _sconfig - optsbysect = list(sconfig.options_by_section()) - assert len(optsbysect) == 1, 'all options for a source should be in the same group' - ini_format_section(stream, uri, optsbysect[0][1]) - if hasattr(sconfig, 'adapter'): - print >> stream - print >> stream, '# adapter for this source (YOU SHOULD NOT CHANGE THIS)' - print >> stream, 'adapter=%s' % sconfig.adapter - print >> stream - def repo_cnx(config): """return a in-memory repository and a db api connection it""" from cubicweb.dbapi import in_memory_cnx @@ -155,7 +121,6 @@ """create an application by copying files from the given cube and by asking information necessary to build required configuration files """ - from cubicweb.server.sources import SOURCE_TYPES config = self.config print 'application\'s repository configuration' print '-' * 72 @@ -170,25 +135,37 @@ sconfig.adapter = 'native' sconfig.input_config(inputlevel=inputlevel) sourcescfg = {'system': sconfig} + for cube in cubes: + # if a source is named as the cube containing it, we need the + # source to use the cube, so add it. + if cube in SOURCE_TYPES: + sourcescfg[cube] = ask_source_config(cube, inputlevel) while raw_input('enter another source [y/N]: ').strip().lower() == 'y': - sourcetype = raw_input('source type (%s): ' % ', '.join(SOURCE_TYPES.keys())) - sconfig = Configuration(options=SOURCE_TYPES[sourcetype].options) - sconfig.adapter = sourcetype - sourceuri = raw_input('source uri: ').strip() - assert not sourceuri in sourcescfg - sconfig.input_config(inputlevel=inputlevel) - sourcescfg[sourceuri] = sconfig - # module names look like cubes.mycube.themodule - sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1] - # if the source adapter is coming from an external component, ensure - # it's specified in used cubes - if sourcecube != 'cubicweb' and not sourcecube in cubes: - cubes.append(sourcecube) + available = sorted(stype for stype in SOURCE_TYPES + if not stype in cubes) + while True: + sourcetype = raw_input('source type (%s): ' % ', '.join(available)) + if sourcetype in available: + break + print 'unknown source type, use one of the available type' + while True: + sourceuri = raw_input('source uri: ').strip() + if sourceuri not in sourcescfg: + break + print 'uri already used, choose another one' + sourcescfg[sourceuri] = ask_source_config(sourcetype) + sourcemodule = SOURCE_TYPES[sourcetype].module + if not sourcemodule.startswith('cubicweb.'): + # module names look like cubes.mycube.themodule + sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1] + # if the source adapter is coming from an external component, + # ensure it's specified in used cubes + if not sourcecube in cubes: + cubes.append(sourcecube) sconfig = Configuration(options=USER_OPTIONS) sconfig.input_config(inputlevel=inputlevel) sourcescfg['admin'] = sconfig - generate_sources_file(sourcesfile, sourcescfg, ['admin', 'system']) - restrict_perms_to_user(sourcesfile) + config.write_sources_file(sourcescfg) # remember selected cubes for later initialization of the database config.write_bootstrap_cubes_file(cubes) @@ -435,7 +412,7 @@ from cubicweb.server.utils import crypt_password, manager_userpasswd appid = pop_arg(args, 1, msg="No application specified !") config = ServerConfiguration.config_for(appid) - sourcescfg = config.sources() + sourcescfg = config.read_sources_file() try: adminlogin = sourcescfg['admin']['login'] except KeyError: @@ -454,9 +431,7 @@ sconfig['login'] = adminlogin sconfig['password'] = passwd sourcescfg['admin'] = sconfig - sourcesfile = config.sources_file() - generate_sources_file(sourcesfile, sourcescfg) - restrict_perms_to_user(sourcesfile) + config.write_sources_file(sourcescfg) except Exception, ex: cnx.rollback() import traceback diff -r b4ffcea3275b -r 92ea410806fe server/utils.py --- a/server/utils.py Fri Jun 12 16:31:32 2009 +0200 +++ b/server/utils.py Fri Jun 12 16:33:19 2009 +0200 @@ -13,6 +13,10 @@ from getpass import getpass from random import choice +from logilab.common.configuration import Configuration + +from cubicweb.server import SOURCE_TYPES + try: from crypt import crypt except ImportError: @@ -83,6 +87,13 @@ return user, passwd +def ask_source_config(sourcetype, inputlevel=0): + sconfig = Configuration(options=SOURCE_TYPES[sourcetype].options) + sconfig.adapter = sourcetype + sconfig.input_config(inputlevel=inputlevel) + return sconfig + + class LoopTask(object): """threaded task restarting itself once executed""" def __init__(self, interval, func):