[PATCH 2 of 7] [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands

Laurent Peuch cortex at worlddomination.be
Wed Sep 4 17:48:30 CEST 2019


On Wed, Sep 04, 2019 at 09:22:18AM +0200, Noé Gaumont wrote:
> Hi,
> 
> Thanks for this patch (and the whole series).
> 
> Could you explain why you moved ShellCommand.options  from class attributes
> to instance attribute?
> I did not see any obvious reason (but did not spend time on it).

I'm sorry but I don't see where I did that in that patch or in any
other patches of the series :x can you point me the line please?

> On 01/09/2019 04:06, Laurent Peuch wrote:
> ># HG changeset patch
> ># User Laurent Peuch <cortex at worlddomination.be>
> ># Date 1558454897 -7200
> >#      Tue May 21 18:08:17 2019 +0200
> ># Node ID b533d93f38ee32f597c830adf70f661abeddb706
> ># Parent  a63c93f27994cbb440a0431c1809166216eaa712
> >[cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
> >
> >diff --git a/cubicweb/cwctl.py b/cubicweb/cwctl.py
> >--- a/cubicweb/cwctl.py
> >+++ b/cubicweb/cwctl.py
> >@@ -44,6 +44,8 @@ from cubicweb.cwconfig import CubicWebCo
> >  from cubicweb.toolsutils import Command, rm, create_dir, underline_title
> >  from cubicweb.__pkginfo__ import version as cw_version
> >+LOG_LEVELS = ('debug', 'info', 'warning', 'error')
> >+
> >  # don't check duplicated commands, it occurs when reloading site_cubicweb
> >  CWCTL = CommandLine('cubicweb-ctl', 'The CubicWeb swiss-knife.',
> >                      version=cw_version, check_duplicated_command=False)
> >@@ -126,6 +128,13 @@ class InstanceCommand(Command):
> >            'help': 'launch pdb on exception',
> >            }
> >           ),
> >+        ("loglevel",
> >+         {'type': 'choice', 'default': None, 'metavar': '<log level>',
> >+          'choices': LOG_LEVELS, 'short': 'l',
> >+          'help': 'allow to specify log level for debugging (choices: %s)'
> >+                  % (', '.join(LOG_LEVELS)),
> >+          }
> >+         ),
> >      )
> >      actionverb = None
> >@@ -136,6 +145,19 @@ class InstanceCommand(Command):
> >          appid = args[0]
> >          cmdmeth = getattr(self, '%s_instance' % self.name)
> >+        # debugmode=True is to force to have a StreamHandler used instead of
> >+        # writting the logs into a file in /tmp
> >+        self.cwconfig = cwcfg.config_for(appid, debugmode=True)
> >+
> >+        # by default loglevel is 'error' but we keep the default value to None
> >+        # because some subcommands (e.g: pyramid) can override the loglevel in
> >+        # certain situations if it's not explicitly set by the user and we want
> >+        # to detect that (the "None" case)
> >+        if self['loglevel'] is None:
> >+            init_cmdline_log_threshold(self.cwconfig, 'error')
> >+        else:
> >+            init_cmdline_log_threshold(self.cwconfig, self['loglevel'])
> >+
> >          try:
> >              status = cmdmeth(appid) or 0
> >          except (ExecutionError, ConfigurationError) as ex:
> >@@ -415,7 +437,6 @@ class DeleteInstanceCommand(Command):
> >      name = 'delete'
> >      arguments = '<instance>'
> >      min_args = max_args = 1
> >-    options = ()
> >      def run(self, args):
> >          """run the command with its specific arguments"""
> >@@ -590,14 +611,13 @@ class ListVersionsInstanceCommand(Instan
> >      name = 'versions'
> >      def versions_instance(self, appid):
> >-        config = cwcfg.config_for(appid)
> >          # should not raise error if db versions don't match fs versions
> >-        config.repairing = True
> >+        self.cwconfig.repairing = True
> >          # no need to load all appobjects and schema
> >-        config.quick_start = True
> >-        if hasattr(config, 'set_sources_mode'):
> >-            config.set_sources_mode(('migration',))
> >-        vcconf = config.repository().get_versions()
> >+        self.cwconfig.quick_start = True
> >+        if hasattr(self.cwconfig, 'set_sources_mode'):
> >+            self.cwconfig.set_sources_mode(('migration',))
> >+        vcconf = self.cwconfig.repository().get_versions()
> >          for key in sorted(vcconf):
> >              print(key + ': %s.%s.%s' % vcconf[key])
> >@@ -622,7 +642,7 @@ class ShellCommand(Command):
> >      arguments = '<instance> [batch command file(s)] [-- <script arguments>]'
> >      min_args = 1
> >      max_args = None
> >-    options = (
> >+    options = merge_options((
> >          ('system-only',
> >           {'short': 'S', 'action': 'store_true',
> >            'help': 'only connect to the system source when the instance is '
> >@@ -646,7 +666,7 @@ sources for migration will be automatica
> >            'group': 'local'
> >            }),
> >-    )
> >+    ) + InstanceCommand.options)
> >      def _get_mih(self, appid):
> >          """ returns migration context handler & shutdown function """
> >@@ -690,16 +710,14 @@ class RecompileInstanceCatalogsCommand(I
> >      """
> >      name = 'i18ninstance'
> >-    @staticmethod
> >-    def i18ninstance_instance(appid):
> >+    def i18ninstance_instance(self, appid):
> >          """recompile instance's messages catalogs"""
> >-        config = cwcfg.config_for(appid)
> >-        config.quick_start = True  # notify this is not a regular start
> >-        repo = config.repository()
> >-        if config._cubes is None:
> >+        self.cwconfig.quick_start = True  # notify this is not a regular start
> >+        repo = self.cwconfig.repository()
> >+        if self.cwconfig._cubes is None:
> >              # web only config
> >-            config.init_cubes(repo.get_cubes())
> >-        errors = config.i18ncompile()
> >+            self.cwconfig.init_cubes(repo.get_cubes())
> >+        errors = self.cwconfig.i18ncompile()
> >          if errors:
> >              print('\n'.join(errors))
> >@@ -747,14 +765,13 @@ class ConfigureInstanceCommand(InstanceC
> >      def configure_instance(self, appid):
> >          if self.config.param is not None:
> >-            appcfg = cwcfg.config_for(appid)
> >              for key, value in self.config.param.items():
> >                  try:
> >-                    appcfg.global_set_option(key, value)
> >+                    self.cwconfig.global_set_option(key, value)
> >                  except KeyError:
> >                      raise ConfigurationError(
> >-                        'unknown configuration key "%s" for mode %s' % (key, appcfg.name))
> >-            appcfg.save()
> >+                        'unknown configuration key "%s" for mode %s' % (key, self.cwconfig.name))
> >+            self.cwconfig.save()
> >  for cmdcls in (ListCommand,
> >diff --git a/cubicweb/pyramid/pyramidctl.py b/cubicweb/pyramid/pyramidctl.py
> >--- a/cubicweb/pyramid/pyramidctl.py
> >+++ b/cubicweb/pyramid/pyramidctl.py
> >@@ -35,7 +35,6 @@ import warnings
> >  from logilab.common.configuration import merge_options
> >-from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
> >  from cubicweb.cwctl import CWCTL, InstanceCommand, init_cmdline_log_threshold
> >  from cubicweb.pyramid import wsgi_application_from_cwconfig
> >  from cubicweb.pyramid.config import get_random_secret_key
> >@@ -48,7 +47,6 @@ import waitress
> >  MAXFD = 1024
> >  DBG_FLAGS = ('RQL', 'SQL', 'REPO', 'HOOKS', 'OPS', 'SEC', 'MORE')
> >-LOG_LEVELS = ('debug', 'info', 'warning', 'error')
> >  def _generate_pyramid_ini_file(pyramid_ini_path):
> >@@ -110,12 +108,6 @@ class PyramidStartHandler(InstanceComman
> >          ('reload-interval',
> >           {'type': 'int', 'default': 1,
> >            'help': 'Interval, in seconds, between file modifications checks'}),
> >-        ('loglevel',
> >-         {'short': 'l', 'type': 'choice', 'metavar': '<log level>',
> >-          'default': None, 'choices': LOG_LEVELS,
> >-          'help': 'debug if -D is set, error otherwise; '
> >-                  'one of %s' % (LOG_LEVELS,),
> >-          }),
> >          ('dbglevel',
> >           {'type': 'multiple_choice', 'metavar': '<dbg level>',
> >            'default': None,
> >@@ -248,13 +240,10 @@ class PyramidStartHandler(InstanceComman
> >          autoreload = self['reload'] or self['debug']
> >-        # debugmode=True is to force to have a StreamHandler used instead of
> >-        # writting the logs into a file in /tmp
> >-        cwconfig = cwcfg.config_for(appid, debugmode=True)
> >-        filelist_path = os.path.join(cwconfig.apphome,
> >+        filelist_path = os.path.join(self.cwconfig.apphome,
> >                                       '.pyramid-reload-files.list')
> >-        pyramid_ini_path = os.path.join(cwconfig.apphome, "pyramid.ini")
> >+        pyramid_ini_path = os.path.join(self.cwconfig.apphome, "pyramid.ini")
> >          if not os.path.exists(pyramid_ini_path):
> >              _generate_pyramid_ini_file(pyramid_ini_path)
> >@@ -265,26 +254,28 @@ class PyramidStartHandler(InstanceComman
> >              _turn_sigterm_into_systemexit()
> >              self.debug('Running reloading file monitor')
> >              extra_files = [sys.argv[0]]
> >-            extra_files.extend(self.configfiles(cwconfig))
> >-            extra_files.extend(self.i18nfiles(cwconfig))
> >+            extra_files.extend(self.configfiles(self.cwconfig))
> >+            extra_files.extend(self.i18nfiles(self.cwconfig))
> >              self.install_reloader(
> >                  self['reload-interval'], extra_files,
> >                  filelist_path=filelist_path)
> >          if self['dbglevel']:
> >-            self['loglevel'] = 'debug'
> >              set_debug('|'.join('DBG_' + x.upper() for x in self['dbglevel']))
> >-        init_cmdline_log_threshold(cwconfig, self['loglevel'])
> >+
> >+        # if no loglevel is specified and --debug or --dbglevel are here, set log level at debug
> >+        if self['loglevel'] is None and (self['debug'] or self['dbglevel']):
> >+            init_cmdline_log_threshold(self.cwconfig, 'debug')
> >          app = wsgi_application_from_cwconfig(
> >-            cwconfig, profile=self['profile'],
> >+            self.cwconfig, profile=self['profile'],
> >              profile_output=self['profile-output'],
> >              profile_dump_every=self['profile-dump-every']
> >          )
> >-        host = cwconfig['interface']
> >-        port = cwconfig['port'] or 8080
> >-        url_scheme = ('https' if cwconfig['base-url'].startswith('https')
> >+        host = self.cwconfig['interface']
> >+        port = self.cwconfig['port'] or 8080
> >+        url_scheme = ('https' if self.cwconfig['base-url'].startswith('https')
> >                        else 'http')
> >          repo = app.application.registry['cubicweb.repository']
> >          warnings.warn(
> >diff --git a/cubicweb/test/unittest_cwctl.py b/cubicweb/test/unittest_cwctl.py
> >--- a/cubicweb/test/unittest_cwctl.py
> >+++ b/cubicweb/test/unittest_cwctl.py
> >@@ -108,8 +108,11 @@ class InstanceCommandTest(unittest.TestC
> >          self.CWCTL.register(_TestCommand)
> >          self.CWCTL.register(_TestFailCommand)
> >+        self.fake_config = MagicMock()
> >+        self.fake_config.global_set_option = MagicMock()
> >+
> >          # pretend that this instance exists
> >-        patcher = patch.object(cwcfg, 'config_for', return_value=object())
> >+        patcher = patch.object(cwcfg, 'config_for', return_value=self.fake_config)
> >          patcher.start()
> >          self.addCleanup(patcher.stop)
> >@@ -164,6 +167,17 @@ class InstanceCommandTest(unittest.TestC
> >          test_fail_instance.assert_called_once()
> >+    def test_set_loglevel(self):
> >+        LOG_LEVELS = ('debug', 'info', 'warning', 'error')
> >+
> >+        for log_level in LOG_LEVELS:
> >+            with self.assertRaises(SystemExit) as cm:
> >+                self.CWCTL.run(["test", "some_instance", "--loglevel", log_level])
> >+            self.assertEqual(cm.exception.code, 0)
> >+
> >+            self.fake_config.global_set_option.assert_called_with('log-threshold',
> >+                                                                  log_level.upper())
> >+
> >  if __name__ == '__main__':
> >      unittest.main()
> >diff --git a/doc/changes/3.27.rst b/doc/changes/3.27.rst
> >--- a/doc/changes/3.27.rst
> >+++ b/doc/changes/3.27.rst
> >@@ -20,6 +20,9 @@ New features
> >  * add a --pdb flag to all cubicweb-ctl command to launch (i)pdb if an exception
> >    occurs during a command execution.
> >+* the --loglevel flag is available for all cubicweb-ctl instance commands (and
> >+  not only the ``pyramid`` one)
> >+
> >  Backwards incompatible changes
> >  ------------------------------

-- 

Laurent Peuch -- Bram



More information about the cubicweb-devel mailing list