cwconfig.py
branchstable
changeset 3638 648d6dbec630
parent 3564 b03cc2416cd5
child 3639 0835e5127f36
equal deleted inserted replaced
3637:0a0e86cb5c89 3638:648d6dbec630
     2 """common configuration utilities for cubicweb
     2 """common configuration utilities for cubicweb
     3 
     3 
     4 :organization: Logilab
     4 :organization: Logilab
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     7 
       
     8 
       
     9 If cubicweb is a mercurial checkout (eg `CWDEV` is true), located in
       
    10 `CW_SOFTWARE_ROOT`:
       
    11 
       
    12  * main cubes directory is `<CW_SOFTWARE_ROOT>/../cubes`. You can specify
       
    13    another one with `CW_INSTANCES_DIR` environment variable or simply add some
       
    14    other directories by using `CW_CUBES_PATH`.
       
    15 
       
    16  * cubicweb migration files are by default searched in
       
    17    `<CW_SOFTWARE_ROOT>/misc/migration` instead of
       
    18    `/usr/share/cubicweb/migration/`(unless another emplacement is specified
       
    19    using `CW_MIGRATION_DIR`.
       
    20 
       
    21  * Cubicweb will start in 'user' mode (see below)
       
    22 
       
    23 
       
    24 On startup, Cubicweb is using a specific *mode*. A mode corresponds to some
       
    25 default setting for various resource directories. There are currently 2 main
       
    26 modes : 'system', for system wide installation, and 'user', fur user local
       
    27 installation (e.g. no root privileges).
       
    28 
       
    29 'user' mode is activated automatically when cubicweb is a mercurial checkout
       
    30 (e.g.  has a .hg directory). You can also force mode by using the `CW_MODE`
       
    31 environment variable, to:
       
    32 
       
    33 * use system wide installation but user specific instances and all, without root
       
    34   privileges on the system (`export CW_MODE=user`)
       
    35 
       
    36 * use local checkout of cubicweb on system wide instances (requires root
       
    37   privileges on the system (`export CW_MODE=system`)
       
    38 
       
    39  Here is the default resource directories settings according to start mode:
       
    40 
       
    41 * 'system': ::
       
    42 
       
    43         CW_INSTANCES_DIR = /etc/cubicweb.d/
       
    44         CW_INSTANCES_DATA_DIR = /var/lib/cubicweb/instances/
       
    45         CW_RUNTIME_DIR = /var/run/cubicweb/
       
    46 
       
    47  * 'user': ::
       
    48 
       
    49         CW_INSTANCES_DIR = ~/etc/cubicweb.d/
       
    50         CW_INSTANCES_DATA_DIR = ~/etc/cubicweb.d/
       
    51         CW_RUNTIME_DIR = /tmp
     7 
    52 
     8 .. envvar:: CW_CUBES_PATH
    53 .. envvar:: CW_CUBES_PATH
     9 
    54 
    10    Augments the default search path for cubes
    55    Augments the default search path for cubes
    11 
    56 
   136     }
   181     }
   137 
   182 
   138 _forced_mode = os.environ.get('CW_MODE')
   183 _forced_mode = os.environ.get('CW_MODE')
   139 assert _forced_mode in (None, 'system', 'user')
   184 assert _forced_mode in (None, 'system', 'user')
   140 
   185 
       
   186 CWDEV = exists(join(CW_SOFTWARE_ROOT, '.hg'))
       
   187 
   141 class CubicWebNoAppConfiguration(ConfigurationMixIn):
   188 class CubicWebNoAppConfiguration(ConfigurationMixIn):
   142     """base class for cubicweb configuration without a specific instance directory
   189     """base class for cubicweb configuration without a specific instance directory
   143     """
   190     """
   144     __metaclass__ = metaconfiguration
   191     __metaclass__ = metaconfiguration
   145     # to set in concrete configuration
   192     # to set in concrete configuration
   146     name = None
   193     name = None
   147     # log messages format (see logging module documentation for available keys)
   194     # log messages format (see logging module documentation for available keys)
   148     log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s'
   195     log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s'
   149     # nor remove appobjects based on unused interface
   196     # nor remove appobjects based on unused interface
   150     cleanup_interface_sobjects = True
   197     cleanup_interface_sobjects = True
       
   198     # debug mode
       
   199     debug = False
   151 
   200 
   152     if os.environ.get('APYCOT_ROOT'):
   201     if os.environ.get('APYCOT_ROOT'):
   153         mode = 'test'
   202         mode = 'test'
   154         CUBES_DIR = '%(APYCOT_ROOT)s/local/share/cubicweb/cubes/' % os.environ
   203         CUBES_DIR = '%(APYCOT_ROOT)s/local/share/cubicweb/cubes/' % os.environ
   155         # create __init__ file
   204         # create __init__ file
   156         file(join(CUBES_DIR, '__init__.py'), 'w').close()
   205         file(join(CUBES_DIR, '__init__.py'), 'w').close()
   157     elif (exists(join(CW_SOFTWARE_ROOT, '.hg')) and _forced_mode != 'system') or _forced_mode == 'user':
   206     elif (CWDEV and _forced_mode != 'system'):
   158         mode = 'dev'
   207         mode = 'user'
   159         CUBES_DIR = abspath(normpath(join(CW_SOFTWARE_ROOT, '../cubes')))
   208         CUBES_DIR = abspath(normpath(join(CW_SOFTWARE_ROOT, '../cubes')))
   160     else:
   209     else:
   161         mode = 'installed'
   210         if _forced_mode == 'user':
       
   211             mode = 'user'
       
   212         else:
       
   213             mode = 'system'
   162         CUBES_DIR = '/usr/share/cubicweb/cubes/'
   214         CUBES_DIR = '/usr/share/cubicweb/cubes/'
   163 
   215 
   164     options = (
   216     options = (
   165        ('log-threshold',
   217        ('log-threshold',
   166          {'type' : 'string', # XXX use a dedicated type?
   218          {'type' : 'string', # XXX use a dedicated type?
   243     @classmethod
   295     @classmethod
   244     def shared_dir(cls):
   296     def shared_dir(cls):
   245         """return the shared data directory (i.e. directory where standard
   297         """return the shared data directory (i.e. directory where standard
   246         library views and data may be found)
   298         library views and data may be found)
   247         """
   299         """
   248         if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'):
   300         if CWDEV:
   249             return join(CW_SOFTWARE_ROOT, 'web')
   301             return join(CW_SOFTWARE_ROOT, 'web')
   250         return cls.cube_dir('shared')
   302         return cls.cube_dir('shared')
   251 
   303 
   252     @classmethod
   304     @classmethod
   253     def i18n_lib_dir(cls):
   305     def i18n_lib_dir(cls):
   254         """return instance's i18n directory"""
   306         """return instance's i18n directory"""
   255         if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'):
   307         if CWDEV:
   256             return join(CW_SOFTWARE_ROOT, 'i18n')
   308             return join(CW_SOFTWARE_ROOT, 'i18n')
   257         return join(cls.shared_dir(), 'i18n')
   309         return join(cls.shared_dir(), 'i18n')
   258 
   310 
   259     @classmethod
   311     @classmethod
   260     def available_cubes(cls):
   312     def available_cubes(cls):
   261         cubes = set()
   313         cubes = set()
   262         for directory in cls.cubes_search_path():
   314         for directory in cls.cubes_search_path():
   263             for cube in os.listdir(directory):
   315             for cube in os.listdir(directory):
   264                 if isdir(join(directory, cube)) and not cube in ('CVS', '.svn', 'shared', '.hg'):
   316                 if isdir(join(directory, cube)) and not cube == 'shared':
   265                     cubes.add(cube)
   317                     cubes.add(cube)
   266         return sorted(cubes)
   318         return sorted(cubes)
   267 
   319 
   268     @classmethod
   320     @classmethod
   269     def cubes_search_path(cls):
   321     def cubes_search_path(cls):
   495         if logthreshold is None:
   547         if logthreshold is None:
   496             if debug:
   548             if debug:
   497                 logthreshold = 'DEBUG'
   549                 logthreshold = 'DEBUG'
   498             else:
   550             else:
   499                 logthreshold = self['log-threshold']
   551                 logthreshold = self['log-threshold']
       
   552         self.debug = debug
   500         init_log(debug, syslog, logthreshold, logfile, self.log_format)
   553         init_log(debug, syslog, logthreshold, logfile, self.log_format)
   501         # configure simpleTal logger
   554         # configure simpleTal logger
   502         logging.getLogger('simpleTAL').setLevel(logging.ERROR)
   555         logging.getLogger('simpleTAL').setLevel(logging.ERROR)
   503 
   556 
   504     def vregistry_path(self):
   557     def vregistry_path(self):
   536         return None
   589         return None
   537 
   590 
   538 class CubicWebConfiguration(CubicWebNoAppConfiguration):
   591 class CubicWebConfiguration(CubicWebNoAppConfiguration):
   539     """base class for cubicweb server and web configurations"""
   592     """base class for cubicweb server and web configurations"""
   540 
   593 
   541     INSTANCE_DATA_DIR = None
   594     INSTANCES_DATA_DIR = None
   542     if CubicWebNoAppConfiguration.mode == 'test':
   595     if CubicWebNoAppConfiguration.mode == 'test':
   543         root = os.environ['APYCOT_ROOT']
   596         root = os.environ['APYCOT_ROOT']
   544         REGISTRY_DIR = '%s/etc/cubicweb.d/' % root
   597         REGISTRY_DIR = '%s/etc/cubicweb.d/' % root
   545         RUNTIME_DIR = tempfile.gettempdir()
   598         RUNTIME_DIR = tempfile.gettempdir()
   546         MIGRATION_DIR = '%s/local/share/cubicweb/migration/' % root
   599         MIGRATION_DIR = '%s/local/share/cubicweb/migration/' % root
   547         if not exists(REGISTRY_DIR):
   600         if not exists(REGISTRY_DIR):
   548             os.makedirs(REGISTRY_DIR)
   601             os.makedirs(REGISTRY_DIR)
   549     elif CubicWebNoAppConfiguration.mode == 'dev':
   602     else:
   550         REGISTRY_DIR = expanduser('~/etc/cubicweb.d/')
   603         if CubicWebNoAppConfiguration.mode == 'user':
   551         RUNTIME_DIR = tempfile.gettempdir()
   604             REGISTRY_DIR = expanduser('~/etc/cubicweb.d/')
   552         MIGRATION_DIR = join(CW_SOFTWARE_ROOT, 'misc', 'migration')
   605             RUNTIME_DIR = tempfile.gettempdir()
   553     else: #mode = 'installed'
   606             INSTANCES_DATA_DIR = cls.REGISTRY_DIR
   554         REGISTRY_DIR = '/etc/cubicweb.d/'
   607         else: #mode = 'system'
   555         INSTANCE_DATA_DIR = '/var/lib/cubicweb/instances/'
   608             REGISTRY_DIR = '/etc/cubicweb.d/'
   556         RUNTIME_DIR = '/var/run/cubicweb/'
   609             RUNTIME_DIR = '/var/run/cubicweb/'
   557         MIGRATION_DIR = '/usr/share/cubicweb/migration/'
   610             INSTANCES_DATA_DIR = '/var/lib/cubicweb/instances/'
       
   611         if CWDEV:
       
   612             MIGRATION_DIR = join(CW_SOFTWARE_ROOT, 'misc', 'migration')
       
   613         else:
       
   614             MIGRATION_DIR = '/usr/share/cubicweb/migration/'
   558 
   615 
   559     # for some commands (creation...) we don't want to initialize gettext
   616     # for some commands (creation...) we don't want to initialize gettext
   560     set_language = True
   617     set_language = True
   561     # set this to true to avoid false error message while creating an instance
   618     # set this to true to avoid false error message while creating an instance
   562     creating = False
   619     creating = False
   610         return env_path('CW_INSTANCES_DIR', cls.REGISTRY_DIR, 'registry')
   667         return env_path('CW_INSTANCES_DIR', cls.REGISTRY_DIR, 'registry')
   611 
   668 
   612     @classmethod
   669     @classmethod
   613     def instance_data_dir(cls):
   670     def instance_data_dir(cls):
   614         """return the instance data directory"""
   671         """return the instance data directory"""
   615         return env_path('CW_INSTANCES_DATA_DIR',
   672         return env_path('CW_INSTANCES_DATA_DIR', cls.INSTANCES_DATA_DIR,
   616                         cls.INSTANCE_DATA_DIR or cls.REGISTRY_DIR,
       
   617                         'additional data')
   673                         'additional data')
   618 
   674 
   619     @classmethod
   675     @classmethod
   620     def migration_scripts_dir(cls):
   676     def migration_scripts_dir(cls):
   621         """cubicweb migration scripts directory"""
   677         """cubicweb migration scripts directory"""
   664         """
   720         """
   665         return self.appid
   721         return self.appid
   666 
   722 
   667     def default_log_file(self):
   723     def default_log_file(self):
   668         """return default path to the log file of the instance'server"""
   724         """return default path to the log file of the instance'server"""
   669         if self.mode == 'dev':
   725         if self.mode == 'user':
   670             basepath = join(tempfile.gettempdir(), '%s-%s' % (basename(self.appid), self.name))
   726             basepath = join(tempfile.gettempdir(), '%s-%s' % (basename(self.appid), self.name))
   671             path = basepath + '.log'
   727             path = basepath + '.log'
   672             i = 1
   728             i = 1
   673             while exists(path) and i < 100: # arbitrary limit to avoid infinite loop
   729             while exists(path) and i < 100: # arbitrary limit to avoid infinite loop
   674                 try:
   730                 try: