From d2bd24f3d7a481bae4d1a0cdf71295d2903eb425 Mon Sep 17 00:00:00 2001 From: "Jay S. Bryant" Date: Fri, 20 Feb 2015 17:12:49 -0600 Subject: [PATCH] Sync 'versionutils' module from oslo-incubator The versionutils module hasn't had a sync since November of 2014. There have been namespace changes and changes to enable moving to the new oslo_log library. So, we need this sync so that we can move forward with those changes. Current HEAD in OSLO: --------------------- commit e589dde0721a0a67e4030813e582afec6e70d042 Date: Wed Feb 18 03:08:12 2015 +0000 Merge "Have a little fun with release notes" Changes merged with this patch: --------------------- 9bf01f9d - Switch from oslo.config to oslo_config 2fbf5065 - Remove oslo.log code and clean up versionutils API Change-Id: I4344ed8fb234135a199649c5ef7620e4166fbb12 --- cinder/openstack/common/versionutils.py | 58 +++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/cinder/openstack/common/versionutils.py b/cinder/openstack/common/versionutils.py index 39f3996dd..b80b69d68 100644 --- a/cinder/openstack/common/versionutils.py +++ b/cinder/openstack/common/versionutils.py @@ -19,15 +19,24 @@ Helpers for comparing version strings. import functools import inspect +import logging +from oslo.config import cfg import pkg_resources import six from cinder.openstack.common._i18n import _ -from cinder.openstack.common import log as logging LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +opts = [ + cfg.BoolOpt('fatal_deprecations', + default=False, + help='Enables or disables fatal status of deprecations.'), +] class deprecated(object): @@ -127,7 +136,7 @@ class deprecated(object): @six.wraps(func_or_cls) def wrapped(*args, **kwargs): - LOG.deprecated(msg, details) + report_deprecated_feature(LOG, msg, details) return func_or_cls(*args, **kwargs) return wrapped elif inspect.isclass(func_or_cls): @@ -136,10 +145,10 @@ class deprecated(object): # TODO(tsufiev): change `functools` module to `six` as # soon as six 1.7.4 (with fix for passing `assigned` # argument to underlying `functools.wraps`) is released - # and added to the cinder-incubator requrements + # and added to the oslo-incubator requrements @functools.wraps(orig_init, assigned=('__name__', '__doc__')) def new_init(self, *args, **kwargs): - LOG.deprecated(msg, details) + report_deprecated_feature(LOG, msg, details) orig_init(self, *args, **kwargs) func_or_cls.__init__ = new_init return func_or_cls @@ -201,3 +210,44 @@ def is_compatible(requested_version, current_version, same_major=True): return False return current_parts >= requested_parts + + +# Track the messages we have sent already. See +# report_deprecated_feature(). +_deprecated_messages_sent = {} + + +def report_deprecated_feature(logger, msg, *args, **kwargs): + """Call this function when a deprecated feature is used. + + If the system is configured for fatal deprecations then the message + is logged at the 'critical' level and :class:`DeprecatedConfig` will + be raised. + + Otherwise, the message will be logged (once) at the 'warn' level. + + :raises: :class:`DeprecatedConfig` if the system is configured for + fatal deprecations. + """ + stdmsg = _("Deprecated: %s") % msg + CONF.register_opts(opts) + if CONF.fatal_deprecations: + logger.critical(stdmsg, *args, **kwargs) + raise DeprecatedConfig(msg=stdmsg) + + # Using a list because a tuple with dict can't be stored in a set. + sent_args = _deprecated_messages_sent.setdefault(msg, list()) + + if args in sent_args: + # Already logged this message, so don't log it again. + return + + sent_args.append(args) + logger.warn(stdmsg, *args, **kwargs) + + +class DeprecatedConfig(Exception): + message = _("Fatal call to deprecated config: %(msg)s") + + def __init__(self, msg): + super(Exception, self).__init__(self.message % dict(msg=msg)) -- 2.45.2