system/user modes + CWDEV instead of installed/dev mixed modes. Fix behaviour when setting CW_MODE explicitly stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 12 Oct 2009 12:54:01 +0200
branchstable
changeset 3638 648d6dbec630
parent 3637 0a0e86cb5c89
child 3639 0835e5127f36
system/user modes + CWDEV instead of installed/dev mixed modes. Fix behaviour when setting CW_MODE explicitly
cwconfig.py
cwctl.py
cwvreg.py
devtools/devctl.py
etwist/server.py
etwist/twconfig.py
selectors.py
server/serverconfig.py
vregistry.py
web/webconfig.py
--- a/cwconfig.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/cwconfig.py	Mon Oct 12 12:54:01 2009 +0200
@@ -5,6 +5,51 @@
 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 
+
+If cubicweb is a mercurial checkout (eg `CWDEV` is true), located in
+`CW_SOFTWARE_ROOT`:
+
+ * main cubes directory is `<CW_SOFTWARE_ROOT>/../cubes`. You can specify
+   another one with `CW_INSTANCES_DIR` environment variable or simply add some
+   other directories by using `CW_CUBES_PATH`.
+
+ * cubicweb migration files are by default searched in
+   `<CW_SOFTWARE_ROOT>/misc/migration` instead of
+   `/usr/share/cubicweb/migration/`(unless another emplacement is specified
+   using `CW_MIGRATION_DIR`.
+
+ * Cubicweb will start in 'user' mode (see below)
+
+
+On startup, Cubicweb is using a specific *mode*. A mode corresponds to some
+default setting for various resource directories. There are currently 2 main
+modes : 'system', for system wide installation, and 'user', fur user local
+installation (e.g. no root privileges).
+
+'user' mode is activated automatically when cubicweb is a mercurial checkout
+(e.g.  has a .hg directory). You can also force mode by using the `CW_MODE`
+environment variable, to:
+
+* use system wide installation but user specific instances and all, without root
+  privileges on the system (`export CW_MODE=user`)
+
+* use local checkout of cubicweb on system wide instances (requires root
+  privileges on the system (`export CW_MODE=system`)
+
+ Here is the default resource directories settings according to start mode:
+
+* 'system': ::
+
+        CW_INSTANCES_DIR = /etc/cubicweb.d/
+        CW_INSTANCES_DATA_DIR = /var/lib/cubicweb/instances/
+        CW_RUNTIME_DIR = /var/run/cubicweb/
+
+ * 'user': ::
+
+        CW_INSTANCES_DIR = ~/etc/cubicweb.d/
+        CW_INSTANCES_DATA_DIR = ~/etc/cubicweb.d/
+        CW_RUNTIME_DIR = /tmp
+
 .. envvar:: CW_CUBES_PATH
 
    Augments the default search path for cubes
@@ -138,6 +183,8 @@
 _forced_mode = os.environ.get('CW_MODE')
 assert _forced_mode in (None, 'system', 'user')
 
+CWDEV = exists(join(CW_SOFTWARE_ROOT, '.hg'))
+
 class CubicWebNoAppConfiguration(ConfigurationMixIn):
     """base class for cubicweb configuration without a specific instance directory
     """
@@ -148,17 +195,22 @@
     log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s'
     # nor remove appobjects based on unused interface
     cleanup_interface_sobjects = True
+    # debug mode
+    debug = False
 
     if os.environ.get('APYCOT_ROOT'):
         mode = 'test'
         CUBES_DIR = '%(APYCOT_ROOT)s/local/share/cubicweb/cubes/' % os.environ
         # create __init__ file
         file(join(CUBES_DIR, '__init__.py'), 'w').close()
-    elif (exists(join(CW_SOFTWARE_ROOT, '.hg')) and _forced_mode != 'system') or _forced_mode == 'user':
-        mode = 'dev'
+    elif (CWDEV and _forced_mode != 'system'):
+        mode = 'user'
         CUBES_DIR = abspath(normpath(join(CW_SOFTWARE_ROOT, '../cubes')))
     else:
-        mode = 'installed'
+        if _forced_mode == 'user':
+            mode = 'user'
+        else:
+            mode = 'system'
         CUBES_DIR = '/usr/share/cubicweb/cubes/'
 
     options = (
@@ -245,14 +297,14 @@
         """return the shared data directory (i.e. directory where standard
         library views and data may be found)
         """
-        if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'):
+        if CWDEV:
             return join(CW_SOFTWARE_ROOT, 'web')
         return cls.cube_dir('shared')
 
     @classmethod
     def i18n_lib_dir(cls):
         """return instance's i18n directory"""
-        if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'):
+        if CWDEV:
             return join(CW_SOFTWARE_ROOT, 'i18n')
         return join(cls.shared_dir(), 'i18n')
 
@@ -261,7 +313,7 @@
         cubes = set()
         for directory in cls.cubes_search_path():
             for cube in os.listdir(directory):
-                if isdir(join(directory, cube)) and not cube in ('CVS', '.svn', 'shared', '.hg'):
+                if isdir(join(directory, cube)) and not cube == 'shared':
                     cubes.add(cube)
         return sorted(cubes)
 
@@ -497,6 +549,7 @@
                 logthreshold = 'DEBUG'
             else:
                 logthreshold = self['log-threshold']
+        self.debug = debug
         init_log(debug, syslog, logthreshold, logfile, self.log_format)
         # configure simpleTal logger
         logging.getLogger('simpleTAL').setLevel(logging.ERROR)
@@ -538,7 +591,7 @@
 class CubicWebConfiguration(CubicWebNoAppConfiguration):
     """base class for cubicweb server and web configurations"""
 
-    INSTANCE_DATA_DIR = None
+    INSTANCES_DATA_DIR = None
     if CubicWebNoAppConfiguration.mode == 'test':
         root = os.environ['APYCOT_ROOT']
         REGISTRY_DIR = '%s/etc/cubicweb.d/' % root
@@ -546,15 +599,19 @@
         MIGRATION_DIR = '%s/local/share/cubicweb/migration/' % root
         if not exists(REGISTRY_DIR):
             os.makedirs(REGISTRY_DIR)
-    elif CubicWebNoAppConfiguration.mode == 'dev':
-        REGISTRY_DIR = expanduser('~/etc/cubicweb.d/')
-        RUNTIME_DIR = tempfile.gettempdir()
-        MIGRATION_DIR = join(CW_SOFTWARE_ROOT, 'misc', 'migration')
-    else: #mode = 'installed'
-        REGISTRY_DIR = '/etc/cubicweb.d/'
-        INSTANCE_DATA_DIR = '/var/lib/cubicweb/instances/'
-        RUNTIME_DIR = '/var/run/cubicweb/'
-        MIGRATION_DIR = '/usr/share/cubicweb/migration/'
+    else:
+        if CubicWebNoAppConfiguration.mode == 'user':
+            REGISTRY_DIR = expanduser('~/etc/cubicweb.d/')
+            RUNTIME_DIR = tempfile.gettempdir()
+            INSTANCES_DATA_DIR = cls.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/'
 
     # for some commands (creation...) we don't want to initialize gettext
     set_language = True
@@ -612,8 +669,7 @@
     @classmethod
     def instance_data_dir(cls):
         """return the instance data directory"""
-        return env_path('CW_INSTANCES_DATA_DIR',
-                        cls.INSTANCE_DATA_DIR or cls.REGISTRY_DIR,
+        return env_path('CW_INSTANCES_DATA_DIR', cls.INSTANCES_DATA_DIR,
                         'additional data')
 
     @classmethod
@@ -666,7 +722,7 @@
 
     def default_log_file(self):
         """return default path to the log file of the instance'server"""
-        if self.mode == 'dev':
+        if self.mode == 'user':
             basepath = join(tempfile.gettempdir(), '%s-%s' % (basename(self.appid), self.name))
             path = basepath + '.log'
             i = 1
--- a/cwctl.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/cwctl.py	Mon Oct 12 12:54:01 2009 +0200
@@ -18,7 +18,7 @@
 from logilab.common.shellutils import ASK
 
 from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage, underline_title
-from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
+from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CWDEV, CONFIGURATIONS
 from cubicweb.toolsutils import Command, main_run,  rm, create_dir
 
 def wait_process_end(pid, maxtry=10, waittime=1):
@@ -656,7 +656,7 @@
         for cube, fromversion, toversion in toupgrade:
             print '-> migration needed from %s to %s for %s' % (fromversion, toversion, cube)
         # only stop once we're sure we have something to do
-        if not (cwcfg.mode == 'dev' or self.config.nostartstop):
+        if not (CWDEV or self.config.nostartstop):
             StopInstanceCommand().stop_instance(appid)
         # run cubicweb/componants migration scripts
         mih.migrate(vcconf, reversed(toupgrade), self.config)
@@ -679,7 +679,7 @@
         mih.shutdown()
         print
         print '-> instance migrated.'
-        if not (cwcfg.mode == 'dev' or self.config.nostartstop):
+        if not (CWDEV or self.config.nostartstop):
             StartInstanceCommand().start_instance(appid)
         print
 
--- a/cwvreg.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/cwvreg.py	Mon Oct 12 12:54:01 2009 +0200
@@ -337,7 +337,7 @@
     def register_objects(self, path, force_reload=None):
         """overriden to remove objects requiring a missing interface"""
         if force_reload is None:
-            force_reload = self.config.mode == 'dev'
+            force_reload = self.config.debug
         try:
             self._register_objects(path, force_reload)
         except RegistryOutOfDate:
--- a/devtools/devctl.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/devtools/devctl.py	Mon Oct 12 12:54:01 2009 +0200
@@ -489,8 +489,6 @@
         if len(args) != 1:
             raise BadCommandUsage("exactly one argument (cube name) is expected")
         cubename, = args
-        #if ServerConfiguration.mode != "dev":
-        #    self.fail("you can only create new cubes in development mode")
         verbose = self.get('verbose')
         cubesdir = self.get('directory')
         if not cubesdir:
--- a/etwist/server.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/etwist/server.py	Mon Oct 12 12:54:01 2009 +0200
@@ -180,8 +180,8 @@
 
     def render(self, request):
         """Render a page from the root resource"""
-        # reload modified files (only in development or debug mode)
-        if self.config.mode == 'dev' or self.debugmode:
+        # reload modified files in debug mode
+        if self.config.debug:
             self.appli.vreg.register_objects(self.config.vregistry_path())
         if self.config['profile']: # default profiler don't trace threads
             return self.render_request(request)
--- a/etwist/twconfig.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/etwist/twconfig.py	Mon Oct 12 12:54:01 2009 +0200
@@ -47,7 +47,7 @@
           'default': None,
           'help': 'if this option is set, use the specified user to start \
 the repository rather than the user running the command',
-          'group': 'main', 'inputlevel': (WebConfiguration.mode == 'installed') and 0 or 1,
+          'group': 'main', 'inputlevel': WebConfiguration.mode == 'system'
           }),
         ('session-time',
          {'type' : 'int',
--- a/selectors.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/selectors.py	Mon Oct 12 12:54:01 2009 +0200
@@ -64,7 +64,7 @@
 
 def lltrace(selector):
     # don't wrap selectors if not in development mode
-    if CubicWebConfiguration.mode == 'installed':
+    if CubicWebConfiguration.mode == 'system': # XXX config.debug
         return selector
     def traced(cls, *args, **kwargs):
         # /!\ lltrace decorates pure function or __call__ method, this
--- a/server/serverconfig.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/server/serverconfig.py	Mon Oct 12 12:54:01 2009 +0200
@@ -75,12 +75,6 @@
 class ServerConfiguration(CubicWebConfiguration):
     """standalone RQL server"""
     name = 'repository'
-    if os.environ.get('APYCOT_ROOT'):
-        root = os.environ['APYCOT_ROOT']
-    elif CubicWebConfiguration.mode == 'dev':
-        BACKUP_DIR = CubicWebConfiguration.RUNTIME_DIR
-    else:
-        BACKUP_DIR = '/var/lib/cubicweb/backup/'
 
     cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['sobjects'])
     cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['sobjects', 'hooks'])
--- a/vregistry.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/vregistry.py	Mon Oct 12 12:54:01 2009 +0200
@@ -185,7 +185,7 @@
                                      % (args, kwargs.keys(),
                                         [repr(v) for v in appobjects]))
         if len(winners) > 1:
-            if self.config.mode == 'installed':
+            if self.config.debug:
                 self.error('select ambiguity, args: %s\nkwargs: %s %s',
                            args, kwargs.keys(), [repr(v) for v in winners])
             else:
--- a/web/webconfig.py	Mon Oct 12 12:20:51 2009 +0200
+++ b/web/webconfig.py	Mon Oct 12 12:54:01 2009 +0200
@@ -172,7 +172,7 @@
 
         ('print-traceback',
          {'type' : 'yn',
-          'default': not CubicWebConfiguration.mode == 'installed',
+          'default': CubicWebConfiguration.mode != 'system',
           'help': 'print the traceback on the error page when an error occured',
           'group': 'web', 'inputlevel': 2,
           }),