diff -r b2cc2a51706f -r 58e89f3dfbae cwconfig.py --- a/cwconfig.py Thu Mar 25 14:33:50 2010 +0100 +++ b/cwconfig.py Thu Mar 25 17:55:24 2010 +0100 @@ -15,8 +15,7 @@ * cubicweb migration files are by default searched in `/misc/migration` instead of - `/usr/share/cubicweb/migration/`(unless another emplacement is specified - using `CW_MIGRATION_DIR`. + `/share/cubicweb/migration/` * Cubicweb will start in 'user' mode (see below) @@ -66,9 +65,6 @@ .. envvar:: CW_RUNTIME_DIR Directory where pid files will be written -.. envvar:: CW_MIGRATION_DIR - Directory where cubicweb migration files will be found - :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ @@ -78,12 +74,11 @@ import sys import os import logging -import tempfile from smtplib import SMTP from threading import Lock -from os.path import exists, join, expanduser, abspath, normpath, basename, isdir +from os.path import (exists, join, expanduser, abspath, normpath, + basename, isdir, dirname) from warnings import warn - from logilab.common.decorators import cached, classproperty from logilab.common.deprecation import deprecated from logilab.common.logging_ext import set_log_methods, init_log @@ -131,6 +126,23 @@ % (directory, modes)) return modes[0] +def _find_prefix(start_path=CW_SOFTWARE_ROOT): + """Runs along the parent directories of *start_path* (default to cubicweb source directory) + looking for one containing a 'share/cubicweb' directory. + The first matching directory is assumed as the prefix installation of cubicweb + + Returns the matching prefix or None. + """ + prefix = start_path + old_prefix = None + if not isdir(start_path): + prefix = dirname(start_path) + while not isdir(join(prefix, 'share', 'cubicweb')) and prefix != old_prefix: + old_prefix = prefix + prefix = dirname(prefix) + if isdir(join(prefix, 'share', 'cubicweb')): + return prefix + return sys.prefix # persistent options definition PERSISTENT_OPTIONS = ( @@ -203,6 +215,11 @@ CWDEV = exists(join(CW_SOFTWARE_ROOT, '.hg')) +try: + _INSTALL_PREFIX = os.environ['CW_INSTALL_PREFIX'] +except KeyError: + _INSTALL_PREFIX = _find_prefix() + class CubicWebNoAppConfiguration(ConfigurationMixIn): """base class for cubicweb configuration without a specific instance directory """ @@ -216,25 +233,16 @@ # debug mode debugmode = False - if os.environ.get('APYCOT_ROOT'): - mode = 'test' - # allow to test cubes within apycot using cubicweb not installed by - # apycot - if __file__.startswith(os.environ['APYCOT_ROOT']): - CUBES_DIR = '%(APYCOT_ROOT)s/local/share/cubicweb/cubes/' % os.environ - # create __init__ file - file(join(CUBES_DIR, '__init__.py'), 'w').close() - else: - CUBES_DIR = '/usr/share/cubicweb/cubes/' - elif (CWDEV and _forced_mode != 'system'): + + if (CWDEV and _forced_mode != 'system'): mode = 'user' - CUBES_DIR = abspath(normpath(join(CW_SOFTWARE_ROOT, '../cubes'))) + _CUBES_DIR = join(CW_SOFTWARE_ROOT, '../cubes') else: - if _forced_mode == 'user': - mode = 'user' - else: - mode = 'system' - CUBES_DIR = '/usr/share/cubicweb/cubes/' + mode = _forced_mode or 'system' + _CUBES_DIR = join(_INSTALL_PREFIX, 'cubes') + + CUBES_DIR = env_path('CW_CUBES_DIR', _CUBES_DIR, 'cubes', checkexists=False) + CUBES_PATH = os.environ.get('CW_CUBES_PATH', '').split(os.pathsep) options = ( ('log-threshold', @@ -296,7 +304,6 @@ }), ) # static and class methods used to get instance independant resources ## - @staticmethod def cubicweb_version(): """return installed cubicweb version""" @@ -343,13 +350,10 @@ def cubes_search_path(cls): """return the path of directories where cubes should be searched""" path = [] - try: - for directory in os.environ['CW_CUBES_PATH'].split(os.pathsep): - directory = abspath(normpath(directory)) - if exists(directory) and not directory in path: - path.append(directory) - except KeyError: - pass + for directory in cls.CUBES_PATH: + directory = abspath(normpath(directory)) + if exists(directory) and not directory in path: + path.append(directory) if not cls.CUBES_DIR in path and exists(cls.CUBES_DIR): path.append(cls.CUBES_DIR) return path @@ -365,7 +369,7 @@ @classmethod def cube_dir(cls, cube): """return the cube directory for the given cube id, - raise ConfigurationError if it doesn't exists + raise `ConfigurationError` if it doesn't exists """ for directory in cls.cubes_search_path(): cubedir = join(directory, cube) @@ -383,10 +387,12 @@ """return the information module for the given cube""" cube = CW_MIGRATION_MAP.get(cube, cube) try: - return getattr(__import__('cubes.%s.__pkginfo__' % cube), cube).__pkginfo__ + parent = __import__('cubes.%s.__pkginfo__' % cube) + return getattr(parent, cube).__pkginfo__ except Exception, ex: - raise ConfigurationError('unable to find packaging information for ' - 'cube %s (%s: %s)' % (cube, ex.__class__.__name__, ex)) + raise ConfigurationError( + 'unable to find packaging information for cube %s (%s: %s)' + % (cube, ex.__class__.__name__, ex)) @classmethod def cube_version(cls, cube): @@ -588,6 +594,7 @@ cw_rest_init() def adjust_sys_path(self): + # overriden in CubicWebConfiguration self.cls_adjust_sys_path() def init_log(self, logthreshold=None, debug=False, @@ -637,35 +644,24 @@ """ return None + class CubicWebConfiguration(CubicWebNoAppConfiguration): """base class for cubicweb server and web configurations""" - INSTANCES_DATA_DIR = None - if os.environ.get('APYCOT_ROOT'): - root = os.environ['APYCOT_ROOT'] - REGISTRY_DIR = '%s/etc/cubicweb.d/' % root - if not exists(REGISTRY_DIR): - os.makedirs(REGISTRY_DIR) - RUNTIME_DIR = tempfile.gettempdir() - # allow to test cubes within apycot using cubicweb not installed by - # apycot - if __file__.startswith(os.environ['APYCOT_ROOT']): - MIGRATION_DIR = '%s/local/share/cubicweb/migration/' % root + if CubicWebNoAppConfiguration.mode == 'user': + _INSTANCES_DIR = expanduser('~/etc/cubicweb.d/') + else: #mode = 'system' + if _INSTALL_PREFIX == '/usr': + _INSTANCES_DIR = '/etc/cubicweb.d/' else: - MIGRATION_DIR = '/usr/share/cubicweb/migration/' - else: - if CubicWebNoAppConfiguration.mode == 'user': - REGISTRY_DIR = expanduser('~/etc/cubicweb.d/') - RUNTIME_DIR = tempfile.gettempdir() - INSTANCES_DATA_DIR = REGISTRY_DIR - else: #mode = 'system' - REGISTRY_DIR = '/etc/cubicweb.d/' - RUNTIME_DIR = '/var/run/cubicweb/' - INSTANCES_DATA_DIR = '/var/lib/cubicweb/instances/' - if CWDEV: - MIGRATION_DIR = join(CW_SOFTWARE_ROOT, 'misc', 'migration') - else: - MIGRATION_DIR = '/usr/share/cubicweb/migration/' + _INSTANCES_DIR = join(_INSTALL_PREFIX, 'etc', 'cubicweb.d') + + if os.environ.get('APYCOT_ROOT'): + _cubes_init = join(CubicWebNoAppConfiguration.CUBES_DIR, '__init__.py') + if not exists(_cubes_init): + file(join(_cubes_init), 'w').close() + if not exists(_INSTANCES_DIR): + os.makedirs(_INSTANCES_DIR) # for some commands (creation...) we don't want to initialize gettext set_language = True @@ -711,25 +707,19 @@ ) @classmethod - def runtime_dir(cls): - """run time directory for pid file...""" - return env_path('CW_RUNTIME_DIR', cls.RUNTIME_DIR, 'run time') - - @classmethod - def registry_dir(cls): + def instances_dir(cls): """return the control directory""" - return env_path('CW_INSTANCES_DIR', cls.REGISTRY_DIR, 'registry') - - @classmethod - def instance_data_dir(cls): - """return the instance data directory""" - return env_path('CW_INSTANCES_DATA_DIR', cls.INSTANCES_DATA_DIR, - 'additional data') + return env_path('CW_INSTANCES_DIR', cls._INSTANCES_DIR, 'registry') @classmethod def migration_scripts_dir(cls): """cubicweb migration scripts directory""" - return env_path('CW_MIGRATION_DIR', cls.MIGRATION_DIR, 'migration') + if CWDEV: + return join(CW_SOFTWARE_ROOT, 'misc', 'migration') + mdir = join(_INSTALL_PREFIX, 'share', 'cubicweb', 'migration') + if not exists(path): + raise ConfigurationError('migration path %s doesn\'t exist' % mdir) + return mdir @classmethod def config_for(cls, appid, config=None): @@ -752,9 +742,10 @@ """return the home directory of the instance with the given instance id """ - home = join(cls.registry_dir(), appid) + home = join(cls.instances_dir(), appid) if not exists(home): - raise ConfigurationError('no such instance %s (check it exists with "cubicweb-ctl list")' % appid) + raise ConfigurationError('no such instance %s (check it exists with' + ' "cubicweb-ctl list")' % appid) return home MODES = ('common', 'repository', 'Any', 'web') @@ -777,7 +768,9 @@ def default_log_file(self): """return default path to the log file of the instance'server""" if self.mode == 'user': - basepath = join(tempfile.gettempdir(), '%s-%s' % (basename(self.appid), self.name)) + import tempfile + basepath = join(tempfile.gettempdir(), '%s-%s' % ( + basename(self.appid), self.name)) path = basepath + '.log' i = 1 while exists(path) and i < 100: # arbitrary limit to avoid infinite loop @@ -792,7 +785,13 @@ def default_pid_file(self): """return default path to the pid file of the instance'server""" - return join(self.runtime_dir(), '%s-%s.pid' % (self.appid, self.name)) + if self.mode == 'system': + # XXX not under _INSTALL_PREFIX, right? + rtdir = env_path('CW_RUNTIME_DIR', '/var/run/cubicweb/', 'run time') + else: + import tempfile + rtdir = env_path('CW_RUNTIME_DIR', tempfile.gettempdir(), 'run time') + return join(rtdir, '%s-%s.pid' % (self.appid, self.name)) # instance methods used to get instance specific resources ############# @@ -812,11 +811,17 @@ @property def apphome(self): - return join(self.registry_dir(), self.appid) + return join(self.instances_dir(), self.appid) @property def appdatahome(self): - return join(self.instance_data_dir(), self.appid) + if self.mode == 'system': + # XXX not under _INSTALL_PREFIX, right? + iddir = '/var/lib/cubicweb/instances/' + else: + iddir = self.instances_dir() + iddir = env_path('CW_INSTANCES_DATA_DIR', iddir, 'additional data') + return join(iddir, self.appid) def init_cubes(self, cubes): assert self._cubes is None, self._cubes