refactor sources configuration, add source to sources when using a cube defining stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 12 Jun 2009 16:33:19 +0200
branchstable
changeset 2105 92ea410806fe
parent 2104 b4ffcea3275b
child 2106 2295f2aba61d
refactor sources configuration, add source to sources when using a cube defining a source
devtools/migrtest.py
server/serverconfig.py
server/serverctl.py
server/utils.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):
--- 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
--- 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
--- 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):