cwctl.py
branchstable
changeset 9013 b4bcabf55e77
parent 8994 df64cca71c36
parent 9002 f98d1c46ed9f
child 9251 e4d753c8b1c4
child 9315 5298cfb132e6
--- a/cwctl.py	Fri Jun 14 16:13:24 2013 +0200
+++ b/cwctl.py	Fri Jun 14 16:26:25 2013 +0200
@@ -38,10 +38,9 @@
     def getpgid():
         """win32 getpgid implementation"""
 
-
-
 from logilab.common.clcommands import CommandLine
 from logilab.common.shellutils import ASK
+from logilab.common.configuration import merge_options
 
 from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage
 from cubicweb.utils import support_args
@@ -205,9 +204,12 @@
 class ListCommand(Command):
     """List configurations, cubes and instances.
 
-    list available configurations, installed cubes, and registered instances
+    List available configurations, installed cubes, and registered instances.
+
+    If given, the optional argument allows to restrict listing only a category of items.
     """
     name = 'list'
+    arguments = '[all|cubes|configurations|instances]'
     options = (
         ('verbose',
          {'short': 'v', 'action' : 'store_true',
@@ -216,92 +218,107 @@
 
     def run(self, args):
         """run the command with its specific arguments"""
-        if args:
+        if not args:
+            mode = 'all'
+        elif len(args) == 1:
+            mode = args[0]
+        else:
             raise BadCommandUsage('Too many arguments')
+
         from cubicweb.migration import ConfigurationProblem
-        print 'CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode)
-        print
-        print 'Available configurations:'
-        for config in CONFIGURATIONS:
-            print '*', config.name
-            for line in config.__doc__.splitlines():
-                line = line.strip()
-                if not line:
-                    continue
-                print '   ', line
-        print
-        cfgpb = ConfigurationProblem(cwcfg)
-        try:
-            cubesdir = pathsep.join(cwcfg.cubes_search_path())
-            namesize = max(len(x) for x in cwcfg.available_cubes())
-        except ConfigurationError as ex:
-            print 'No cubes available:', ex
-        except ValueError:
-            print 'No cubes available in %s' % cubesdir
-        else:
-            print 'Available cubes (%s):' % cubesdir
-            for cube in cwcfg.available_cubes():
-                try:
-                    tinfo = cwcfg.cube_pkginfo(cube)
-                    tversion = tinfo.version
-                    cfgpb.add_cube(cube, tversion)
-                except (ConfigurationError, AttributeError) as ex:
-                    tinfo = None
-                    tversion = '[missing cube information: %s]' % ex
-                print '* %s %s' % (cube.ljust(namesize), tversion)
-                if self.config.verbose:
-                    if tinfo:
-                        descr = getattr(tinfo, 'description', '')
-                        if not descr:
-                            descr = getattr(tinfo, 'short_desc', '')
+
+        if mode == 'all':
+            print 'CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode)
+            print
+
+        if mode in ('all', 'config', 'configurations'):
+            print 'Available configurations:'
+            for config in CONFIGURATIONS:
+                print '*', config.name
+                for line in config.__doc__.splitlines():
+                    line = line.strip()
+                    if not line:
+                        continue
+                    print '   ', line
+            print
+
+        if mode in ('all', 'cubes'):
+            cfgpb = ConfigurationProblem(cwcfg)
+            try:
+                cubesdir = pathsep.join(cwcfg.cubes_search_path())
+                namesize = max(len(x) for x in cwcfg.available_cubes())
+            except ConfigurationError as ex:
+                print 'No cubes available:', ex
+            except ValueError:
+                print 'No cubes available in %s' % cubesdir
+            else:
+                print 'Available cubes (%s):' % cubesdir
+                for cube in cwcfg.available_cubes():
+                    try:
+                        tinfo = cwcfg.cube_pkginfo(cube)
+                        tversion = tinfo.version
+                        cfgpb.add_cube(cube, tversion)
+                    except (ConfigurationError, AttributeError) as ex:
+                        tinfo = None
+                        tversion = '[missing cube information: %s]' % ex
+                    print '* %s %s' % (cube.ljust(namesize), tversion)
+                    if self.config.verbose:
+                        if tinfo:
+                            descr = getattr(tinfo, 'description', '')
+                            if not descr:
+                                descr = getattr(tinfo, 'short_desc', '')
+                                if descr:
+                                    warn('[3.8] short_desc is deprecated, update %s'
+                                         ' pkginfo' % cube, DeprecationWarning)
+                                else:
+                                    descr = tinfo.__doc__
                             if descr:
-                                warn('[3.8] short_desc is deprecated, update %s'
-                                     ' pkginfo' % cube, DeprecationWarning)
-                            else:
-                                descr = tinfo.__doc__
-                        if descr:
-                            print '    '+ '    \n'.join(descr.splitlines())
-                    modes = detect_available_modes(cwcfg.cube_dir(cube))
-                    print '    available modes: %s' % ', '.join(modes)
-        print
-        try:
-            regdir = cwcfg.instances_dir()
-        except ConfigurationError as ex:
-            print 'No instance available:', ex
+                                print '    '+ '    \n'.join(descr.splitlines())
+                        modes = detect_available_modes(cwcfg.cube_dir(cube))
+                        print '    available modes: %s' % ', '.join(modes)
             print
-            return
-        instances = list_instances(regdir)
-        if instances:
-            print 'Available instances (%s):' % regdir
-            for appid in instances:
-                modes = cwcfg.possible_configurations(appid)
-                if not modes:
-                    print '* %s (BROKEN instance, no configuration found)' % appid
-                    continue
-                print '* %s (%s)' % (appid, ', '.join(modes))
-                try:
-                    config = cwcfg.config_for(appid, modes[0])
-                except Exception as exc:
-                    print '    (BROKEN instance, %s)' % exc
-                    continue
-        else:
-            print 'No instance available in %s' % regdir
-        print
-        # configuration management problem solving
-        cfgpb.solve()
-        if cfgpb.warnings:
-            print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings)
-        if cfgpb.errors:
-            print 'Errors:'
-            for op, cube, version, src in cfgpb.errors:
-                if op == 'add':
-                    print '* cube', cube,
-                    if version:
-                        print ' version', version,
-                    print 'is not installed, but required by %s' % src
-                else:
-                    print '* cube %s version %s is installed, but version %s is required by %s' % (
-                        cube, cfgpb.cubes[cube], version, src)
+
+        if mode in ('all', 'instances'):
+            try:
+                regdir = cwcfg.instances_dir()
+            except ConfigurationError as ex:
+                print 'No instance available:', ex
+                print
+                return
+            instances = list_instances(regdir)
+            if instances:
+                print 'Available instances (%s):' % regdir
+                for appid in instances:
+                    modes = cwcfg.possible_configurations(appid)
+                    if not modes:
+                        print '* %s (BROKEN instance, no configuration found)' % appid
+                        continue
+                    print '* %s (%s)' % (appid, ', '.join(modes))
+                    try:
+                        config = cwcfg.config_for(appid, modes[0])
+                    except Exception as exc:
+                        print '    (BROKEN instance, %s)' % exc
+                        continue
+            else:
+                print 'No instance available in %s' % regdir
+            print
+
+        if mode == 'all':
+            # configuration management problem solving
+            cfgpb.solve()
+            if cfgpb.warnings:
+                print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings)
+            if cfgpb.errors:
+                print 'Errors:'
+                for op, cube, version, src in cfgpb.errors:
+                    if op == 'add':
+                        print '* cube', cube,
+                        if version:
+                            print ' version', version,
+                        print 'is not installed, but required by %s' % src
+                    else:
+                        print '* cube %s version %s is installed, but version %s is required by %s' % (
+                            cube, cfgpb.cubes[cube], version, src)
 
 def check_options_consistency(config):
     if config.automatic and config.config_level > 0:
@@ -347,6 +364,12 @@
           ' "list" command. Default to "all-in-one", e.g. an installation '
           'embedding both the RQL repository and the web server.',
           }),
+        ('no-db-create',
+         {'short': 'S',
+          'action': 'store_true',
+          'default': False,
+          'help': 'stop after creation and do not continue with db-create',
+          }),
         )
 
     def run(self, args):
@@ -415,7 +438,8 @@
             print 'set %s as owner of the data directory' % config['uid']
             chown(config.appdatahome, config['uid'])
         print '\n-> creation done for %s\n' % repr(config.apphome)[1:-1]
-        helper.postcreate(self.config.automatic, self.config.config_level)
+        if not self.config.no_db_create:
+            helper.postcreate(self.config.automatic, self.config.config_level)
 
     def _handle_win32(self, config, appid):
         if sys.platform != 'win32':
@@ -811,7 +835,6 @@
     name = 'versions'
 
     def versions_instance(self, appid):
-        from logilab.common.changelog import Version
         config = cwcfg.config_for(appid)
         # should not raise error if db versions don't match fs versions
         config.repairing = True
@@ -822,7 +845,6 @@
         for key in sorted(vcconf):
             print key+': %s.%s.%s' % vcconf[key]
 
-
 class ShellCommand(Command):
     """Run an interactive migration shell on an instance. This is a python shell
     with enhanced migration commands predefined in the namespace. An additional
@@ -989,6 +1011,33 @@
         for cube in cwcfg.available_cubes():
             print cube
 
+class ConfigureInstanceCommand(InstanceCommand):
+    """Configure instance.
+
+    <instance>...
+      identifier of the instance to configure.
+    """
+    name = 'configure'
+    actionverb = 'configured'
+
+    options = merge_options(InstanceCommand.options +
+                            (('param',
+                              {'short': 'p', 'type' : 'named', 'metavar' : 'key1:value1,key2:value2',
+                               'default': None,
+                               'help': 'set <key> to <value> in configuration file.',
+                               }),
+                             ))
+
+    def configure_instance(self, appid):
+        if self.config.param is not None:
+            appcfg = cwcfg.config_for(appid)
+            for key, value in self.config.param.iteritems():
+                try:
+                    appcfg.global_set_option(key, value)
+                except KeyError:
+                    raise ConfigurationError('unknown configuration key "%s" for mode %s' % (key, appcfg.name))
+            appcfg.save()
+
 for cmdcls in (ListCommand,
                CreateInstanceCommand, DeleteInstanceCommand,
                StartInstanceCommand, StopInstanceCommand, RestartInstanceCommand,
@@ -998,10 +1047,10 @@
                ShellCommand,
                RecompileInstanceCatalogsCommand,
                ListInstancesCommand, ListCubesCommand,
+               ConfigureInstanceCommand,
                ):
     CWCTL.register(cmdcls)
 
-
 def run(args):
     """command line tool"""
     import os