[webctl] Generate static data directory on upgrade (closes #2167873)
authorJulien Cristau <julien.cristau@logilab.fr>
Thu, 12 Dec 2013 18:25:45 +0100
changeset 9372 e87a808a4c32
parent 9371 1348202527a6
child 9373 d5d9acadb975
[webctl] Generate static data directory on upgrade (closes #2167873) - if the folder already exists, ``upgrade`` asks for deletion, - add an option (``generate-staticdir``) to allow skipping this task. - add an option (``staticdir-path``) to specify the static data folder path. The ``gen-static-datadir`` command allows to specify the target folder but there is otherwise no way to retrieve this information during upgrade.
cwctl.py
etwist/twctl.py
web/webconfig.py
web/webctl.py
--- a/cwctl.py	Thu Dec 12 16:18:58 2013 +0100
+++ b/cwctl.py	Thu Dec 12 18:25:45 2013 +0100
@@ -752,6 +752,7 @@
         mih = config.migration_handler()
         repo = mih.repo_connect()
         vcconf = repo.get_versions()
+        helper = self.config_helper(config, required=False)
         if self.config.force_cube_version:
             for cube, version in self.config.force_cube_version.iteritems():
                 vcconf[cube] = Version(version)
@@ -790,6 +791,8 @@
         if not self.i18nupgrade(config):
             return
         print
+        if helper:
+            helper.postupgrade(repo)
         print '-> instance migrated.'
         if instance_running and not (CWDEV or self.config.nostartstop):
             # restart instance through fork to get a proper environment, avoid
--- a/etwist/twctl.py	Thu Dec 12 16:18:58 2013 +0100
+++ b/etwist/twctl.py	Thu Dec 12 18:25:45 2013 +0100
@@ -22,7 +22,7 @@
 from logilab.common.shellutils import rm
 
 from cubicweb.toolsutils import CommandHandler
-from cubicweb.web.webctl import WebCreateHandler
+from cubicweb.web.webctl import WebCreateHandler, WebUpgradeHandler
 
 # trigger configuration registration
 import cubicweb.etwist.twconfig # pylint: disable=W0611
@@ -48,6 +48,9 @@
     def poststop(self):
         pass
 
+class TWUpgradeHandler(WebUpgradeHandler):
+    cfgname = 'twisted'
+
 
 try:
     from cubicweb.server import serverctl
@@ -73,5 +76,8 @@
         cfgname = 'all-in-one'
         subcommand = 'cubicweb-twisted'
 
+    class AllInOneUpgradeHandler(TWUpgradeHandler):
+        cfgname = 'all-in-one'
+
 except ImportError:
     pass
--- a/web/webconfig.py	Thu Dec 12 16:18:58 2013 +0100
+++ b/web/webconfig.py	Thu Dec 12 18:25:45 2013 +0100
@@ -235,6 +235,18 @@
           'help': 'anonymize the connection before executing any jsonp query.',
           'group': 'web', 'level': 1
           }),
+        ('generate-staticdir',
+         {'type': 'yn',
+          'default': True,
+          'help': 'Generate the static data resource directory on upgrade.',
+          'group': 'web', 'level': 2,
+          }),
+        ('staticdir-path',
+         {'type': 'string',
+          'default': None,
+          'help': 'The static data resource directory path.',
+          'group': 'web', 'level': 2,
+          }),
         ))
 
     def __init__(self, *args, **kwargs):
--- a/web/webctl.py	Thu Dec 12 16:18:58 2013 +0100
+++ b/web/webctl.py	Thu Dec 12 18:25:45 2013 +0100
@@ -22,7 +22,7 @@
 __docformat__ = "restructuredtext en"
 
 import os, os.path as osp
-from shutil import copy
+from shutil import copy, rmtree
 
 from logilab.common.shellutils import ASK
 
@@ -58,30 +58,24 @@
         """hooks called once instance's initialization has been completed"""
 
 
-class GenStaticDataDir(Command):
+class GenStaticDataDirMixIn(object):
     """Create a directory merging all data directory content from cubes and CW.
     """
-    name = 'gen-static-datadir'
-    arguments = '<instance> [dirpath]'
-    min_args = 1
-    max_args = 2
-
-    options = ()
-
-    def run(self, args):
-        appid = args.pop(0)
-        config = cwcfg.config_for(appid)
-        if args:
-            dest = args[0]
-        else:
+    def generate_static_dir(self, config, dest=None, ask_clean=False, repo=None):
+        if not dest:
+            dest = config['staticdir-path']
+        if not dest:
             dest = osp.join(config.appdatahome, 'data')
         if osp.exists(dest):
-            raise ExecutionError('Directory %s already exists. '
-                                 'Remove it first.' % dest)
+            if (not ask_clean or
+                not ASK.confirm('Remove existing data directory %s?' % dest)):
+                raise ExecutionError('Directory %s already exists. '
+                                     'Remove it first.' % dest)
+            rmtree(dest)
         config.quick_start = True # notify this is not a regular start
         # list all resources (no matter their order)
         resources = set()
-        for datadir in self._datadirs(config):
+        for datadir in self._datadirs(config, repo=repo):
             for dirpath, dirnames, filenames in os.walk(datadir):
                 rel_dirpath = dirpath[len(datadir)+1:]
                 resources.update(osp.join(rel_dirpath, f) for f in filenames)
@@ -98,8 +92,9 @@
         print ('You can use apache rewrite rule below :\n'
                'RewriteRule ^/data/(.*) %s/$1 [L]' % dest)
 
-    def _datadirs(self, config):
-        repo = config.repository()
+    def _datadirs(self, config, repo=None):
+        if repo is None:
+            repo = config.repository()
         if config._cubes is None:
             # web only config
             config.init_cubes(repo.get_cubes())
@@ -109,4 +104,34 @@
                 yield cube_datadir
         yield osp.join(config.shared_dir(), 'data')
 
+
+class WebUpgradeHandler(CommandHandler, GenStaticDataDirMixIn):
+    cmdname = 'upgrade'
+
+    def postupgrade(self, repo):
+        config = self.config
+        if not config['generate-staticdir']:
+            return
+        self.generate_static_dir(config, ask_clean=True, repo=repo)
+
+
+class GenStaticDataDir(Command, GenStaticDataDirMixIn):
+    """Create a directory merging all data directory content from cubes and CW.
+    """
+    name = 'gen-static-datadir'
+    arguments = '<instance> [dirpath]'
+    min_args = 1
+    max_args = 2
+
+    options = ()
+
+    def run(self, args):
+        appid = args.pop(0)
+        config = cwcfg.config_for(appid)
+        dest = None
+        if args:
+            dest = args[0]
+        self.generate_static_dir(config, dest)
+
+
 CWCTL.register(GenStaticDataDir)