server/serverctl.py
branchstable
changeset 2105 92ea410806fe
parent 1980 35394365b6c1
child 2106 2295f2aba61d
equal deleted inserted replaced
2104:b4ffcea3275b 2105:92ea410806fe
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
     9 
     9 
    10 import sys
    10 import sys
    11 import os
    11 import os
    12 
    12 
    13 from logilab.common.configuration import REQUIRED, Configuration, ini_format_section
    13 from logilab.common.configuration import REQUIRED, Configuration
    14 from logilab.common.clcommands import register_commands, cmd_run, pop_arg
    14 from logilab.common.clcommands import register_commands, cmd_run, pop_arg
    15 
    15 
    16 from cubicweb import AuthenticationError, ExecutionError, ConfigurationError
    16 from cubicweb import AuthenticationError, ExecutionError, ConfigurationError
    17 from cubicweb.toolsutils import (Command, CommandHandler, confirm,
    17 from cubicweb.toolsutils import Command, CommandHandler, confirm
    18                                  restrict_perms_to_user)
    18 from cubicweb.server import SOURCE_TYPES
       
    19 from cubicweb.server.utils import ask_source_config
    19 from cubicweb.server.serverconfig import ServerConfiguration
    20 from cubicweb.server.serverconfig import ServerConfiguration
    20 
    21 
    21 
    22 
    22 # utility functions ###########################################################
    23 # utility functions ###########################################################
    23 
    24 
    90     except AttributeError:
    91     except AttributeError:
    91         # set_isolation_level() is psycopg specific
    92         # set_isolation_level() is psycopg specific
    92         pass
    93         pass
    93     return cnx
    94     return cnx
    94 
    95 
    95 def generate_sources_file(sourcesfile, sourcescfg, keys=None):
       
    96     """serialize repository'sources configuration into a INI like file
       
    97 
       
    98     the `keys` parameter may be used to sort sections
       
    99     """
       
   100     from cubicweb.server.sources import SOURCE_TYPES
       
   101     if keys is None:
       
   102         keys = sourcescfg.keys()
       
   103     else:
       
   104         for key in sourcescfg:
       
   105             if not key in keys:
       
   106                 keys.append(key)
       
   107     stream = open(sourcesfile, 'w')
       
   108     for uri in keys:
       
   109         sconfig = sourcescfg[uri]
       
   110         if isinstance(sconfig, dict):
       
   111             # get a Configuration object
       
   112             _sconfig = Configuration(options=SOURCE_TYPES[sconfig['adapter']].options)
       
   113             for attr, val in sconfig.items():
       
   114                 if attr == 'uri':
       
   115                     continue
       
   116                 if attr == 'adapter':
       
   117                     _sconfig.adapter = val
       
   118                 else:
       
   119                     _sconfig.set_option(attr, val)
       
   120             sconfig = _sconfig
       
   121         optsbysect = list(sconfig.options_by_section())
       
   122         assert len(optsbysect) == 1, 'all options for a source should be in the same group'
       
   123         ini_format_section(stream, uri, optsbysect[0][1])
       
   124         if hasattr(sconfig, 'adapter'):
       
   125             print >> stream
       
   126             print >> stream, '# adapter for this source (YOU SHOULD NOT CHANGE THIS)'
       
   127             print >> stream, 'adapter=%s' % sconfig.adapter
       
   128         print >> stream
       
   129 
       
   130 def repo_cnx(config):
    96 def repo_cnx(config):
   131     """return a in-memory repository and a db api connection it"""
    97     """return a in-memory repository and a db api connection it"""
   132     from cubicweb.dbapi import in_memory_cnx
    98     from cubicweb.dbapi import in_memory_cnx
   133     from cubicweb.server.utils import manager_userpasswd
    99     from cubicweb.server.utils import manager_userpasswd
   134     try:
   100     try:
   153 
   119 
   154     def bootstrap(self, cubes, inputlevel=0):
   120     def bootstrap(self, cubes, inputlevel=0):
   155         """create an application by copying files from the given cube and by
   121         """create an application by copying files from the given cube and by
   156         asking information necessary to build required configuration files
   122         asking information necessary to build required configuration files
   157         """
   123         """
   158         from cubicweb.server.sources import SOURCE_TYPES
       
   159         config = self.config
   124         config = self.config
   160         print 'application\'s repository configuration'
   125         print 'application\'s repository configuration'
   161         print '-' * 72
   126         print '-' * 72
   162         config.input_config('email', inputlevel)
   127         config.input_config('email', inputlevel)
   163         if config.pyro_enabled():
   128         if config.pyro_enabled():
   168         sourcesfile = config.sources_file()
   133         sourcesfile = config.sources_file()
   169         sconfig = Configuration(options=SOURCE_TYPES['native'].options)
   134         sconfig = Configuration(options=SOURCE_TYPES['native'].options)
   170         sconfig.adapter = 'native'
   135         sconfig.adapter = 'native'
   171         sconfig.input_config(inputlevel=inputlevel)
   136         sconfig.input_config(inputlevel=inputlevel)
   172         sourcescfg = {'system': sconfig}
   137         sourcescfg = {'system': sconfig}
       
   138         for cube in cubes:
       
   139             # if a source is named as the cube containing it, we need the
       
   140             # source to use the cube, so add it.
       
   141             if cube in SOURCE_TYPES:
       
   142                 sourcescfg[cube] = ask_source_config(cube, inputlevel)
   173         while raw_input('enter another source [y/N]: ').strip().lower() == 'y':
   143         while raw_input('enter another source [y/N]: ').strip().lower() == 'y':
   174             sourcetype = raw_input('source type (%s): ' % ', '.join(SOURCE_TYPES.keys()))
   144             available = sorted(stype for stype in SOURCE_TYPES
   175             sconfig = Configuration(options=SOURCE_TYPES[sourcetype].options)
   145                                if not stype in cubes)
   176             sconfig.adapter = sourcetype
   146             while True:
   177             sourceuri = raw_input('source uri: ').strip()
   147                 sourcetype = raw_input('source type (%s): ' % ', '.join(available))
   178             assert not sourceuri in sourcescfg
   148                 if sourcetype in available:
   179             sconfig.input_config(inputlevel=inputlevel)
   149                     break
   180             sourcescfg[sourceuri] = sconfig
   150                 print 'unknown source type, use one of the available type'
   181             # module names look like cubes.mycube.themodule
   151             while True:
   182             sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1]
   152                 sourceuri = raw_input('source uri: ').strip()
   183             # if the source adapter is coming from an external component, ensure
   153                 if sourceuri not in sourcescfg:
   184             # it's specified in used cubes
   154                     break
   185             if sourcecube != 'cubicweb' and not sourcecube in cubes:
   155                 print 'uri already used, choose another one'
   186                 cubes.append(sourcecube)
   156             sourcescfg[sourceuri] = ask_source_config(sourcetype)
       
   157             sourcemodule = SOURCE_TYPES[sourcetype].module
       
   158             if not sourcemodule.startswith('cubicweb.'):
       
   159                 # module names look like cubes.mycube.themodule
       
   160                 sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1]
       
   161                 # if the source adapter is coming from an external component,
       
   162                 # ensure it's specified in used cubes
       
   163                 if not sourcecube in cubes:
       
   164                     cubes.append(sourcecube)
   187         sconfig = Configuration(options=USER_OPTIONS)
   165         sconfig = Configuration(options=USER_OPTIONS)
   188         sconfig.input_config(inputlevel=inputlevel)
   166         sconfig.input_config(inputlevel=inputlevel)
   189         sourcescfg['admin'] = sconfig
   167         sourcescfg['admin'] = sconfig
   190         generate_sources_file(sourcesfile, sourcescfg, ['admin', 'system'])
   168         config.write_sources_file(sourcescfg)
   191         restrict_perms_to_user(sourcesfile)
       
   192         # remember selected cubes for later initialization of the database
   169         # remember selected cubes for later initialization of the database
   193         config.write_bootstrap_cubes_file(cubes)
   170         config.write_bootstrap_cubes_file(cubes)
   194 
   171 
   195     def postcreate(self):
   172     def postcreate(self):
   196         if confirm('do you want to create repository\'s system database?'):
   173         if confirm('do you want to create repository\'s system database?'):
   433         """run the command with its specific arguments"""
   410         """run the command with its specific arguments"""
   434         from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
   411         from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
   435         from cubicweb.server.utils import crypt_password, manager_userpasswd
   412         from cubicweb.server.utils import crypt_password, manager_userpasswd
   436         appid = pop_arg(args, 1, msg="No application specified !")
   413         appid = pop_arg(args, 1, msg="No application specified !")
   437         config = ServerConfiguration.config_for(appid)
   414         config = ServerConfiguration.config_for(appid)
   438         sourcescfg = config.sources()
   415         sourcescfg = config.read_sources_file()
   439         try:
   416         try:
   440             adminlogin = sourcescfg['admin']['login']
   417             adminlogin = sourcescfg['admin']['login']
   441         except KeyError:
   418         except KeyError:
   442             print 'could not get cubicweb administrator login'
   419             print 'could not get cubicweb administrator login'
   443             sys.exit(1)
   420             sys.exit(1)
   452                     cursor, withpb=False)
   429                     cursor, withpb=False)
   453             sconfig = Configuration(options=USER_OPTIONS)
   430             sconfig = Configuration(options=USER_OPTIONS)
   454             sconfig['login'] = adminlogin
   431             sconfig['login'] = adminlogin
   455             sconfig['password'] = passwd
   432             sconfig['password'] = passwd
   456             sourcescfg['admin'] = sconfig
   433             sourcescfg['admin'] = sconfig
   457             sourcesfile = config.sources_file()
   434             config.write_sources_file(sourcescfg)
   458             generate_sources_file(sourcesfile, sourcescfg)
       
   459             restrict_perms_to_user(sourcesfile)
       
   460         except Exception, ex:
   435         except Exception, ex:
   461             cnx.rollback()
   436             cnx.rollback()
   462             import traceback
   437             import traceback
   463             traceback.print_exc()
   438             traceback.print_exc()
   464             print 'An error occured:', ex
   439             print 'An error occured:', ex