cwctl.py
branchstable
changeset 7140 ba51dac1115d
parent 7131 5893b899c21f
child 7155 4bab50b02927
equal deleted inserted replaced
7139:20807d3d7cf6 7140:ba51dac1115d
   298                     print 'is not installed, but required by %s' % src
   298                     print 'is not installed, but required by %s' % src
   299                 else:
   299                 else:
   300                     print '* cube %s version %s is installed, but version %s is required by %s' % (
   300                     print '* cube %s version %s is installed, but version %s is required by %s' % (
   301                         cube, cfgpb.cubes[cube], version, src)
   301                         cube, cfgpb.cubes[cube], version, src)
   302 
   302 
       
   303 def check_options_consistency(config):
       
   304     if config.automatic and config.config_level > 0:
       
   305         raise BadCommandUsage('--automatic and --config-level should not be '
       
   306                               'used together')
       
   307 
   303 class CreateInstanceCommand(Command):
   308 class CreateInstanceCommand(Command):
   304     """Create an instance from a cube. This is an unified
   309     """Create an instance from a cube. This is an unified
   305     command which can handle web / server / all-in-one installation
   310     command which can handle web / server / all-in-one installation
   306     according to available parts of the software library and of the
   311     according to available parts of the software library and of the
   307     desired cube.
   312     desired cube.
   308 
   313 
   309     <cube>
   314     <cube>
   310       the name of cube to use (list available cube names using
   315       the name of cube to use (list available cube names using
   311       the "list" command). You can use several cubes by separating
   316       the "list" command). You can use several cubes by separating
   312       them using comma (e.g. 'jpl,eemail')
   317       them using comma (e.g. 'jpl,email')
   313     <instance>
   318     <instance>
   314       an identifier for the instance to create
   319       an identifier for the instance to create
   315     """
   320     """
   316     name = 'create'
   321     name = 'create'
   317     arguments = '<cube> <instance>'
   322     arguments = '<cube> <instance>'
   318     min_args = max_args = 2
   323     min_args = max_args = 2
   319     options = (
   324     options = (
   320         ("config-level",
   325         ('automatic',
       
   326          {'short': 'a', 'action' : 'store_true',
       
   327           'default': False,
       
   328           'help': 'automatic mode: never ask and use default answer to every '
       
   329           'question. this may require that your login match a database super '
       
   330           'user (allowed to create database & all).',
       
   331           }),
       
   332         ('config-level',
   321          {'short': 'l', 'type' : 'int', 'metavar': '<level>',
   333          {'short': 'l', 'type' : 'int', 'metavar': '<level>',
   322           'default': 0,
   334           'default': 0,
   323           'help': 'configuration level (0..2): 0 will ask for essential \
   335           'help': 'configuration level (0..2): 0 will ask for essential '
   324 configuration parameters only while 2 will ask for all parameters',
   336           'configuration parameters only while 2 will ask for all parameters',
   325           }
   337           }),
   326          ),
   338         ('config',
   327         ("config",
       
   328          {'short': 'c', 'type' : 'choice', 'metavar': '<install type>',
   339          {'short': 'c', 'type' : 'choice', 'metavar': '<install type>',
   329           'choices': ('all-in-one', 'repository', 'twisted'),
   340           'choices': ('all-in-one', 'repository', 'twisted'),
   330           'default': 'all-in-one',
   341           'default': 'all-in-one',
   331           'help': 'installation type, telling which part of an instance \
   342           'help': 'installation type, telling which part of an instance '
   332 should be installed. You can list available configurations using the "list" \
   343           'should be installed. You can list available configurations using the'
   333 command. Default to "all-in-one", e.g. an installation embedding both the RQL \
   344           ' "list" command. Default to "all-in-one", e.g. an installation '
   334 repository and the web server.',
   345           'embedding both the RQL repository and the web server.',
   335           }
   346           }),
   336          ),
       
   337         )
   347         )
   338 
   348 
   339     def run(self, args):
   349     def run(self, args):
   340         """run the command with its specific arguments"""
   350         """run the command with its specific arguments"""
   341         from logilab.common.textutils import splitstrip
   351         from logilab.common.textutils import splitstrip
       
   352         check_options_consistency(self.config)
   342         configname = self.config.config
   353         configname = self.config.config
   343         cubes, appid = args
   354         cubes, appid = args
   344         cubes = splitstrip(cubes)
   355         cubes = splitstrip(cubes)
   345         # get the configuration and helper
   356         # get the configuration and helper
   346         config = cwcfg.config_for(appid, configname, creating=True)
   357         config = cwcfg.config_for(appid, configname, creating=True)
   358             return
   369             return
   359         # create the registry directory for this instance
   370         # create the registry directory for this instance
   360         print '\n'+underline_title('Creating the instance %s' % appid)
   371         print '\n'+underline_title('Creating the instance %s' % appid)
   361         create_dir(config.apphome)
   372         create_dir(config.apphome)
   362         # cubicweb-ctl configuration
   373         # cubicweb-ctl configuration
   363         print '\n'+underline_title('Configuring the instance (%s.conf)' % configname)
   374         if not self.config.automatic:
   364         config.input_config('main', self.config.config_level)
   375             print '\n'+underline_title('Configuring the instance (%s.conf)'
       
   376                                        % configname)
       
   377             config.input_config('main', self.config.config_level)
   365         # configuration'specific stuff
   378         # configuration'specific stuff
   366         print
   379         print
   367         helper.bootstrap(cubes, self.config.config_level)
   380         helper.bootstrap(cubes, self.config.automatic, self.config.config_level)
   368         # input for cubes specific options
   381         # input for cubes specific options
   369         sections = set(sect.lower() for sect, opt, odict in config.all_options()
   382         sections = set(sect.lower() for sect, opt, odict in config.all_options()
   370                        if 'type' in odict
   383                        if 'type' in odict
   371                        and odict.get('level') <= self.config.config_level)
   384                        and odict.get('level') <= self.config.config_level)
   372         for section in sections:
   385         for section in sections:
   373             if section not in ('main', 'email', 'pyro'):
   386             if section not in ('main', 'email', 'pyro', 'web'):
   374                 print '\n' + underline_title('%s options' % section)
   387                 print '\n' + underline_title('%s options' % section)
   375                 config.input_config(section, self.config.config_level)
   388                 config.input_config(section, self.config.config_level)
   376         # write down configuration
   389         # write down configuration
   377         config.save()
   390         config.save()
   378         self._handle_win32(config, appid)
   391         self._handle_win32(config, appid)
   383         from cubicweb import i18n
   396         from cubicweb import i18n
   384         langs = [lang for lang, _ in i18n.available_catalogs(join(templdirs[0], 'i18n'))]
   397         langs = [lang for lang, _ in i18n.available_catalogs(join(templdirs[0], 'i18n'))]
   385         errors = config.i18ncompile(langs)
   398         errors = config.i18ncompile(langs)
   386         if errors:
   399         if errors:
   387             print '\n'.join(errors)
   400             print '\n'.join(errors)
   388             if not ASK.confirm('error while compiling message catalogs, '
   401             if self.config.automatic \
   389                                'continue anyway ?'):
   402                    or not ASK.confirm('error while compiling message catalogs, '
       
   403                                       'continue anyway ?'):
   390                 print 'creation not completed'
   404                 print 'creation not completed'
   391                 return
   405                 return
   392         # create the additional data directory for this instance
   406         # create the additional data directory for this instance
   393         if config.appdatahome != config.apphome: # true in dev mode
   407         if config.appdatahome != config.apphome: # true in dev mode
   394             create_dir(config.appdatahome)
   408             create_dir(config.appdatahome)
   397             from logilab.common.shellutils import chown
   411             from logilab.common.shellutils import chown
   398             # this directory should be owned by the uid of the server process
   412             # this directory should be owned by the uid of the server process
   399             print 'set %s as owner of the data directory' % config['uid']
   413             print 'set %s as owner of the data directory' % config['uid']
   400             chown(config.appdatahome, config['uid'])
   414             chown(config.appdatahome, config['uid'])
   401         print '\n-> creation done for %r.\n' % config.apphome
   415         print '\n-> creation done for %r.\n' % config.apphome
   402         helper.postcreate()
   416         helper.postcreate(self.config.automatic)
   403 
   417 
   404     def _handle_win32(self, config, appid):
   418     def _handle_win32(self, config, appid):
   405         if sys.platform != 'win32':
   419         if sys.platform != 'win32':
   406             return
   420             return
   407         service_template = """
   421         service_template = """