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: |