diff -r 2cf127d4f5fd -r b4bcabf55e77 cwctl.py --- 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. + + ... + 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 to 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