cubicweb/cwctl.py
changeset 12525 234079d86496
parent 12524 8d3952d7124d
child 12526 b78e3472a7d6
--- a/cubicweb/cwctl.py	Thu Mar 14 16:53:34 2019 +0100
+++ b/cubicweb/cwctl.py	Thu Mar 14 17:04:02 2019 +0100
@@ -24,7 +24,7 @@
 # possible (for cubicweb-ctl reactivity, necessary for instance for usable bash
 # completion). So import locally in command helpers.
 import sys
-from warnings import warn, filterwarnings
+from warnings import filterwarnings
 from os import remove, listdir, system, pathsep
 from os.path import exists, join, isdir
 
@@ -36,8 +36,6 @@
     def getpgid():
         """win32 getpgid implementation"""
 
-from six.moves.urllib.parse import urlparse
-
 from logilab.common.clcommands import CommandLine
 from logilab.common.shellutils import ASK
 from logilab.common.configuration import merge_options
@@ -46,11 +44,11 @@
 from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage
 from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
 from cubicweb.toolsutils import Command, rm, create_dir, underline_title
-from cubicweb.__pkginfo__ import version
+from cubicweb.__pkginfo__ import version as cw_version
 
 # don't check duplicated commands, it occurs when reloading site_cubicweb
 CWCTL = CommandLine('cubicweb-ctl', 'The CubicWeb swiss-knife.',
-                    version=version, check_duplicated_command=False)
+                    version=cw_version, check_duplicated_command=False)
 
 
 def wait_process_end(pid, maxtry=10, waittime=1):
@@ -108,12 +106,12 @@
     arguments = '[<instance>...]'
     options = (
         ("force",
-         {'short': 'f', 'action' : 'store_true',
+         {'short': 'f', 'action': 'store_true',
           'default': False,
           'help': 'force command without asking confirmation',
           }
          ),
-        )
+    )
     actionverb = None
 
     def run(self, args):
@@ -135,14 +133,14 @@
         status = 0
         for appid in args:
             if askconfirm:
-                print('*'*72)
+                print('*' * 72)
                 if not ASK.confirm('%s instance %r ?' % (self.name, appid)):
                     continue
             try:
                 status = max(status, self.run_arg(appid))
             except (KeyboardInterrupt, SystemExit):
                 sys.stderr.write('%s aborted\n' % self.name)
-                return 2 # specific error code
+                return 2  # specific error code
         sys.exit(status)
 
     def run_arg(self, appid):
@@ -151,16 +149,17 @@
             status = cmdmeth(appid) or 0
         except (ExecutionError, ConfigurationError) as ex:
             sys.stderr.write('instance %s not %s: %s\n' % (
-                    appid, self.actionverb, ex))
+                appid, self.actionverb, ex))
             status = 4
         except Exception as ex:
             import traceback
             traceback.print_exc()
             sys.stderr.write('instance %s not %s: %s\n' % (
-                    appid, self.actionverb, ex))
+                appid, self.actionverb, ex))
             status = 8
         return status
 
+
 class InstanceCommandFork(InstanceCommand):
     """Same as `InstanceCommand`, but command is forked in a new environment
     for each argument
@@ -168,12 +167,12 @@
 
     def run_args(self, args, askconfirm):
         if len(args) > 1:
-            forkcmd = ' '.join(w for w in sys.argv if not w in args)
+            forkcmd = ' '.join(w for w in sys.argv if w not in args)
         else:
             forkcmd = None
         for appid in args:
             if askconfirm:
-                print('*'*72)
+                print('*' * 72)
                 if not ASK.confirm('%s instance %r ?' % (self.name, appid)):
                     continue
             if forkcmd:
@@ -197,9 +196,9 @@
     arguments = '[all|cubes|configurations|instances]'
     options = (
         ('verbose',
-         {'short': 'v', 'action' : 'store_true',
+         {'short': 'v', 'action': 'store_true',
           'help': "display more information."}),
-        )
+    )
 
     def run(self, args):
         """run the command with its specific arguments"""
@@ -255,7 +254,7 @@
                             if not descr:
                                 descr = tinfo.__doc__
                             if descr:
-                                print('    '+ '    \n'.join(descr.splitlines()))
+                                print('    ' + '    \n'.join(descr.splitlines()))
                         modes = detect_available_modes(cwcfg.cube_dir(cube))
                         print('    available modes: %s' % ', '.join(modes))
             print()
@@ -289,7 +288,7 @@
             # configuration management problem solving
             cfgpb.solve()
             if cfgpb.warnings:
-                print('Warnings:\n', '\n'.join('* '+txt for txt in 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:
@@ -299,14 +298,18 @@
                             print(' version', version, end=' ')
                         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))
+                        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:
         raise BadCommandUsage('--automatic and --config-level should not be '
                               'used together')
 
+
 class CreateInstanceCommand(Command):
     """Create an instance from a cube. This is a unified
     command which can handle web / server / all-in-one installation
@@ -325,20 +328,20 @@
     min_args = max_args = 2
     options = (
         ('automatic',
-         {'short': 'a', 'action' : 'store_true',
+         {'short': 'a', 'action': 'store_true',
           'default': False,
           'help': 'automatic mode: never ask and use default answer to every '
           'question. this may require that your login match a database super '
           'user (allowed to create database & all).',
           }),
         ('config-level',
-         {'short': 'l', 'type' : 'int', 'metavar': '<level>',
+         {'short': 'l', 'type': 'int', 'metavar': '<level>',
           'default': 0,
           'help': 'configuration level (0..2): 0 will ask for essential '
           'configuration parameters only while 2 will ask for all parameters',
           }),
         ('config',
-         {'short': 'c', 'type' : 'choice', 'metavar': '<install type>',
+         {'short': 'c', 'type': 'choice', 'metavar': '<install type>',
           'choices': ('all-in-one', 'repository', 'pyramid'),
           'default': 'all-in-one',
           'help': 'installation type, telling which part of an instance '
@@ -352,7 +355,7 @@
           'default': False,
           'help': 'stop after creation and do not continue with db-create',
           }),
-        )
+    )
 
     def run(self, args):
         """run the command with its specific arguments"""
@@ -376,12 +379,12 @@
             print(', '.join(available_cube_names(cwcfg)))
             return
         # create the registry directory for this instance
-        print('\n'+underline_title('Creating the instance %s' % appid))
+        print('\n' + underline_title('Creating the instance %s' % appid))
         create_dir(config.apphome)
         # cubicweb-ctl configuration
         if not self.config.automatic:
-            print('\n'+underline_title('Configuring the instance (%s.conf)'
-                                       % configname))
+            print('\n' + underline_title('Configuring the instance (%s.conf)'
+                                         % configname))
             config.input_config('main', self.config.config_level)
         # configuration'specific stuff
         print()
@@ -406,12 +409,12 @@
         if errors:
             print('\n'.join(errors))
             if self.config.automatic \
-                   or not ASK.confirm('error while compiling message catalogs, '
-                                      'continue anyway ?'):
+                or not ASK.confirm('error while compiling message catalogs, '
+                                   'continue anyway ?'):
                 print('creation not completed')
                 return
         # create the additional data directory for this instance
-        if config.appdatahome != config.apphome: # true in dev mode
+        if config.appdatahome != config.apphome:  # true in dev mode
             create_dir(config.appdatahome)
         create_dir(join(config.appdatahome, 'backup'))
         if config['uid']:
@@ -470,29 +473,29 @@
     actionverb = 'started'
     options = (
         ("debug",
-         {'short': 'D', 'action' : 'store_true',
+         {'short': 'D', 'action': 'store_true',
           'help': 'start server in debug mode.'}),
         ("force",
-         {'short': 'f', 'action' : 'store_true',
+         {'short': 'f', 'action': 'store_true',
           'default': False,
           'help': 'start the instance even if it seems to be already \
 running.'}),
         ('profile',
-         {'short': 'P', 'type' : 'string', 'metavar': '<stat file>',
+         {'short': 'P', 'type': 'string', 'metavar': '<stat file>',
           'default': None,
           'help': 'profile code and use the specified file to store stats',
           }),
         ('loglevel',
-         {'short': 'l', 'type' : 'choice', 'metavar': '<log level>',
+         {'short': 'l', 'type': 'choice', 'metavar': '<log level>',
           'default': None, 'choices': ('debug', 'info', 'warning', 'error'),
           'help': 'debug if -D is set, error otherwise',
           }),
         ('param',
-         {'short': 'p', 'type' : 'named', 'metavar' : 'key1:value1,key2:value2',
+         {'short': 'p', 'type': 'named', 'metavar': 'key1:value1,key2:value2',
           'default': {},
           'help': 'override <key> configuration file option with <value>.',
-         }),
-       )
+          }),
+    )
 
     def start_instance(self, appid):
         """start the instance's server"""
@@ -541,7 +544,7 @@
         """stop the instance's server"""
         config = cwcfg.config_for(appid)
         helper = self.config_helper(config, cmdname='stop')
-        helper.poststop() # do this anyway
+        helper.poststop()  # do this anyway
         pidf = config['pid-file']
         if not exists(pidf):
             sys.stderr.write("%s doesn't exist.\n" % pidf)
@@ -637,6 +640,7 @@
             print("running with pid %s" % (pid))
         return status
 
+
 class UpgradeInstanceCommand(InstanceCommandFork):
     """Upgrade an instance after cubicweb and/or component(s) upgrade.
 
@@ -652,17 +656,17 @@
     actionverb = 'upgraded'
     options = InstanceCommand.options + (
         ('force-cube-version',
-         {'short': 't', 'type' : 'named', 'metavar': 'cube1:X.Y.Z,cube2:X.Y.Z',
+         {'short': 't', 'type': 'named', 'metavar': 'cube1:X.Y.Z,cube2:X.Y.Z',
           'default': None,
           'help': 'force migration from the indicated version for the specified cube(s).'}),
 
         ('force-cubicweb-version',
-         {'short': 'e', 'type' : 'string', 'metavar': 'X.Y.Z',
+         {'short': 'e', 'type': 'string', 'metavar': 'X.Y.Z',
           'default': None,
           'help': 'force migration from the indicated cubicweb version.'}),
 
         ('fs-only',
-         {'short': 's', 'action' : 'store_true',
+         {'short': 's', 'action': 'store_true',
           'default': False,
           'help': 'only upgrade files on the file system, not the database.'}),
 
@@ -672,39 +676,39 @@
           'help': 'do NOT update config file if set.'}),
 
         ('nostartstop',
-         {'short': 'n', 'action' : 'store_true',
+         {'short': 'n', 'action': 'store_true',
           'default': False,
           'help': 'don\'t try to stop instance before migration and to restart it after.'}),
 
         ('verbosity',
-         {'short': 'v', 'type' : 'int', 'metavar': '<0..2>',
+         {'short': 'v', 'type': 'int', 'metavar': '<0..2>',
           'default': 1,
           'help': "0: no confirmation, 1: only main commands confirmed, 2 ask \
 for everything."}),
 
         ('backup-db',
-         {'short': 'b', 'type' : 'yn', 'metavar': '<y or n>',
+         {'short': 'b', 'type': 'yn', 'metavar': '<y or n>',
           'default': None,
-          'help': "Backup the instance database before upgrade.\n"\
+          'help': "Backup the instance database before upgrade.\n"
           "If the option is ommitted, confirmation will be ask.",
           }),
 
         ('ext-sources',
-         {'short': 'E', 'type' : 'csv', 'metavar': '<sources>',
+         {'short': 'E', 'type': 'csv', 'metavar': '<sources>',
           'default': None,
           'help': "For multisources instances, specify to which sources the \
 repository should connect to for upgrading. When unspecified or 'migration' is \
 given, appropriate sources for migration will be automatically selected \
 (recommended). If 'all' is given, will connect to all defined sources.",
           }),
-        )
+    )
 
     def upgrade_instance(self, appid):
         print('\n' + underline_title('Upgrading the instance %s' % appid))
         from logilab.common.changelog import Version
         config = cwcfg.config_for(appid)
         instance_running = exists(config['pid-file'])
-        config.repairing = True # notice we're not starting the server
+        config.repairing = True  # notice we're not starting the server
         config.verbosity = self.config.verbosity
         set_sources_mode = getattr(config, 'set_sources_mode', None)
         if set_sources_mode is not None:
@@ -726,7 +730,7 @@
                 config.error('no version information for %s' % cube)
                 continue
             if installedversion > applversion:
-                toupgrade.append( (cube, applversion, installedversion) )
+                toupgrade.append((cube, applversion, installedversion))
         cubicwebversion = config.cubicweb_version()
         if self.config.force_cubicweb_version:
             applcubicwebversion = Version(self.config.force_cubicweb_version)
@@ -804,7 +808,8 @@
             config.set_sources_mode(('migration',))
         vcconf = config.repository().get_versions()
         for key in sorted(vcconf):
-            print(key+': %s.%s.%s' % vcconf[key])
+            print(key + ': %s.%s.%s' % vcconf[key])
+
 
 class ShellCommand(Command):
     """Run an interactive migration shell on an instance. This is a python shell
@@ -827,15 +832,15 @@
     min_args = 1
     options = (
         ('system-only',
-         {'short': 'S', 'action' : 'store_true',
+         {'short': 'S', 'action': 'store_true',
           'help': 'only connect to the system source when the instance is '
           'using multiple sources. You can\'t use this option and the '
           '--ext-sources option at the same time.',
           'group': 'local'
-         }),
+          }),
 
         ('ext-sources',
-         {'short': 'E', 'type' : 'csv', 'metavar': '<sources>',
+         {'short': 'E', 'type': 'csv', 'metavar': '<sources>',
           'help': "For multisources instances, specify to which sources the \
 repository should connect to for upgrading. When unspecified or 'all' given, \
 will connect to all defined sources. If 'migration' is given, appropriate \
@@ -844,12 +849,12 @@
           }),
 
         ('force',
-         {'short': 'f', 'action' : 'store_true',
+         {'short': 'f', 'action': 'store_true',
           'help': 'don\'t check instance is up to date.',
           'group': 'local'
           }),
 
-        )
+    )
 
     def _get_mih(self, appid):
         """ returns migration context handler & shutdown function """
@@ -877,8 +882,8 @@
                         # remember that usage requires instance appid as first argument
                         scripts, args = self.cmdline_parser.largs[1:], self.cmdline_parser.rargs
                         for script in scripts:
-                                mih.cmd_process_script(script, scriptargs=args)
-                                mih.commit()
+                            mih.cmd_process_script(script, scriptargs=args)
+                            mih.commit()
                     else:
                         mih.interactive_shell()
         finally:
@@ -898,7 +903,7 @@
     def i18ninstance_instance(appid):
         """recompile instance's messages catalogs"""
         config = cwcfg.config_for(appid)
-        config.quick_start = True # notify this is not a regular start
+        config.quick_start = True  # notify this is not a regular start
         repo = config.repository()
         if config._cubes is None:
             # web only config
@@ -930,6 +935,7 @@
         for cube in cwcfg.available_cubes():
             print(cube)
 
+
 class ConfigureInstanceCommand(InstanceCommand):
     """Configure instance.
 
@@ -939,13 +945,14 @@
     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.',
-                               }),
-                             ))
+    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:
@@ -954,7 +961,8 @@
                 try:
                     appcfg.global_set_option(key, value)
                 except KeyError:
-                    raise ConfigurationError('unknown configuration key "%s" for mode %s' % (key, appcfg.name))
+                    raise ConfigurationError(
+                        'unknown configuration key "%s" for mode %s' % (key, appcfg.name))
             appcfg.save()
 
 
@@ -984,6 +992,7 @@
 def wsgichoices():
     return tuple(WSGI_CHOICES)
 
+
 if WSGI_CHOICES:
     class WSGIStartHandler(InstanceCommand):
         """Start an interactive wsgi server """
@@ -1012,7 +1021,7 @@
                   'default': None,
                   'choices': ('debug', 'info', 'warning', 'error'),
                   'help': 'debug if -D is set, error otherwise',
-              }),
+                  }),
             )
 
         def wsgi_instance(self, appid):
@@ -1040,10 +1049,8 @@
     CWCTL.register(cmdcls)
 
 
-
 def run(args=sys.argv[1:]):
     """command line tool"""
-    import os
     filterwarnings('default', category=DeprecationWarning)
     cwcfg.load_cwctl_plugins()
     try:
@@ -1055,5 +1062,6 @@
         print(err)
         sys.exit(2)
 
+
 if __name__ == '__main__':
     run()