diff options
author | Alessio Ababilov <aababilo@yahoo-inc.com> | 2013-02-13 16:34:34 +0200 |
---|---|---|
committer | Alessio Ababilov <aababilo@yahoo-inc.com> | 2013-02-14 11:13:15 +0200 |
commit | 17daedc6cc482111e20e0ec1f884b851a08e953b (patch) | |
tree | f85312c770eb7cadca0e0782f50e8e300f3366ef | |
parent | 4ffddcfa6385703ce9a02f624999f05b388778e6 (diff) | |
download | nova-17daedc6cc482111e20e0ec1f884b851a08e953b.tar.gz nova-17daedc6cc482111e20e0ec1f884b851a08e953b.tar.xz nova-17daedc6cc482111e20e0ec1f884b851a08e953b.zip |
Synchronize code from oslo
Use commit eaab5fae2502198e9fa57d0d90a7204a2bd83b16:
Merge "sort options to make --help output prettier"
(Wed Feb 13 12:52:14 2013 +0000).
Changes:
9669767 Fix PEP8 error in oslo-rootwrap
e3e5e0e Fixes "is not", "not in" syntax usage
d156150 Implements import_group
0ce65aa sort options to make --help output prettier
580c259 Make tox run doctests
d8c4e0c Change Exception MissingArgs's string
6d102bc Provide i18n to those messages without _()
cf705c5 Make project pyflakes clean
9e5912f Fix pep8 E125 errors
4a1ec21 Support testing args for LocalhostMatchMaker
9fd6437 Exchanges should return directed topics
a4b6c31 Allow running test in uninstalled source tree
1461135 timeutils: considers that now is soon
a956f7a Import timeutils.is_soon from keystoneclient
a4b6c31 Allow running test in uninstalled source tree
076e9e5 Add support for directly stringifying VersionInfo
Change-Id: I427508f0882a528d040c89290ff9ca68a1e91bcd
Fixes: bug #1124213
-rwxr-xr-x | bin/nova-rootwrap | 17 | ||||
-rw-r--r-- | nova/openstack/__init__.py | 15 | ||||
-rw-r--r-- | nova/openstack/common/__init__.py | 15 | ||||
-rw-r--r-- | nova/openstack/common/cfg.py | 30 | ||||
-rw-r--r-- | nova/openstack/common/cliutils.py | 13 | ||||
-rw-r--r-- | nova/openstack/common/excutils.py | 6 | ||||
-rw-r--r-- | nova/openstack/common/plugin/pluginmanager.py | 1 | ||||
-rw-r--r-- | nova/openstack/common/policy.py | 20 | ||||
-rw-r--r-- | nova/openstack/common/rpc/impl_zmq.py | 5 | ||||
-rw-r--r-- | nova/openstack/common/rpc/matchmaker.py | 17 | ||||
-rw-r--r-- | nova/openstack/common/setup.py | 8 | ||||
-rw-r--r-- | nova/openstack/common/timeutils.py | 18 | ||||
-rw-r--r-- | nova/openstack/common/version.py | 14 |
13 files changed, 99 insertions, 80 deletions
diff --git a/bin/nova-rootwrap b/bin/nova-rootwrap index 72a8c6309..35e2f47f3 100755 --- a/bin/nova-rootwrap +++ b/bin/nova-rootwrap @@ -20,14 +20,17 @@ Filters which commands a service is allowed to run as another user. - To use this with nova, you should set the following in nova.conf: + To use this with nova, you should set the following in + nova.conf: rootwrap_config=/etc/nova/rootwrap.conf - You also need to let the nova user run nova-rootwrap as root in sudoers: - nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf * + You also need to let the nova user run nova-rootwrap + as root in sudoers: + nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap + /etc/nova/rootwrap.conf * - Service packaging should deploy .filters files only on nodes where they are - needed, to avoid allowing more than is necessary. + Service packaging should deploy .filters files only on nodes where + they are needed, to avoid allowing more than is necessary. """ import ConfigParser @@ -102,8 +105,8 @@ if __name__ == '__main__': exec_dirs=config.exec_dirs) if config.use_syslog: logging.info("(%s > %s) Executing %s (filter match = %s)" % ( - os.getlogin(), pwd.getpwuid(os.getuid())[0], - command, filtermatch.name)) + os.getlogin(), pwd.getpwuid(os.getuid())[0], + command, filtermatch.name)) obj = subprocess.Popen(command, stdin=sys.stdin, diff --git a/nova/openstack/__init__.py b/nova/openstack/__init__.py index 0a3b98867..e69de29bb 100644 --- a/nova/openstack/__init__.py +++ b/nova/openstack/__init__.py @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. diff --git a/nova/openstack/common/__init__.py b/nova/openstack/common/__init__.py index 0a3b98867..e69de29bb 100644 --- a/nova/openstack/common/__init__.py +++ b/nova/openstack/common/__init__.py @@ -1,15 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. diff --git a/nova/openstack/common/cfg.py b/nova/openstack/common/cfg.py index 534a610c0..baecc0c3b 100644 --- a/nova/openstack/common/cfg.py +++ b/nova/openstack/common/cfg.py @@ -863,7 +863,7 @@ class SubCommandOpt(Opt): description=self.description, help=self.help) - if not self.handler is None: + if self.handler is not None: self.handler(subparsers) @@ -1297,6 +1297,24 @@ class ConfigOpts(collections.Mapping): __import__(module_str) self._get_opt_info(name, group) + def import_group(self, group, module_str): + """Import an option group from a module. + + Import a module and check that a given option group is registered. + + This is intended for use with global configuration objects + like cfg.CONF where modules commonly register options with + CONF at module load time. If one module requires an option group + defined by another module it can use this method to explicitly + declare the dependency. + + :param group: an option OptGroup object or group name + :param module_str: the name of a module to import + :raises: ImportError, NoSuchGroupError + """ + __import__(module_str) + self._get_group(group) + @__clear_cache def set_override(self, name, override, group=None): """Override an opt value. @@ -1547,8 +1565,8 @@ class ConfigOpts(collections.Mapping): group = group_or_name if isinstance(group_or_name, OptGroup) else None group_name = group.name if group else group_or_name - if not group_name in self._groups: - if not group is None or not autocreate: + if group_name not in self._groups: + if group is not None or not autocreate: raise NoSuchGroupError(group_name) self.register_group(OptGroup(name=group_name)) @@ -1568,7 +1586,7 @@ class ConfigOpts(collections.Mapping): group = self._get_group(group) opts = group._opts - if not opt_name in opts: + if opt_name not in opts: raise NoSuchOptError(opt_name, group) return opts[opt_name] @@ -1606,7 +1624,7 @@ class ConfigOpts(collections.Mapping): opt = info['opt'] if opt.required: - if ('default' in info or 'override' in info): + if 'default' in info or 'override' in info: continue if self._get(opt.dest, group) is None: @@ -1625,7 +1643,7 @@ class ConfigOpts(collections.Mapping): """ self._args = args - for opt, group in self._all_cli_opts(): + for opt, group in sorted(self._all_cli_opts()): opt._add_to_cli(self._oparser, group) return vars(self._oparser.parse_args(args)) diff --git a/nova/openstack/common/cliutils.py b/nova/openstack/common/cliutils.py index 8f4dc44dd..411bd58f3 100644 --- a/nova/openstack/common/cliutils.py +++ b/nova/openstack/common/cliutils.py @@ -15,7 +15,6 @@ # under the License. import inspect -import string class MissingArgs(Exception): @@ -25,12 +24,10 @@ class MissingArgs(Exception): def __str__(self): if len(self.missing) == 1: - return ("An argument is missing: %(missing)s" % - dict(missing=self.missing[0])) + return "An argument is missing" else: - return ("%(num)d arguments are missing: %(missing)s" % - dict(num=len(self.missing), - missing=string.join(self.missing, ', '))) + return ("%(num)d arguments are missing" % + dict(num=len(self.missing))) def validate_args(fn, *args, **kwargs): @@ -39,11 +36,11 @@ def validate_args(fn, *args, **kwargs): >>> validate_args(lambda a: None) Traceback (most recent call last): ... - MissingArgs: An argument is missing: a + MissingArgs: An argument is missing >>> validate_args(lambda a, b, c, d: None, 0, c=1) Traceback (most recent call last): ... - MissingArgs: 2 arguments are missing: b, d + MissingArgs: 2 arguments are missing :param fn: the function to check :param arg: the positional arguments supplied diff --git a/nova/openstack/common/excutils.py b/nova/openstack/common/excutils.py index 5dd483017..e507efced 100644 --- a/nova/openstack/common/excutils.py +++ b/nova/openstack/common/excutils.py @@ -24,6 +24,8 @@ import logging import sys import traceback +from nova.openstack.common.gettextutils import _ + @contextlib.contextmanager def save_and_reraise_exception(): @@ -43,7 +45,7 @@ def save_and_reraise_exception(): try: yield except Exception: - logging.error('Original exception being dropped: %s' % - (traceback.format_exception(type_, value, tb))) + logging.error(_('Original exception being dropped: %s'), + traceback.format_exception(type_, value, tb)) raise raise type_, value, tb diff --git a/nova/openstack/common/plugin/pluginmanager.py b/nova/openstack/common/plugin/pluginmanager.py index 51d06d851..157ecbf44 100644 --- a/nova/openstack/common/plugin/pluginmanager.py +++ b/nova/openstack/common/plugin/pluginmanager.py @@ -16,6 +16,7 @@ import pkg_resources from nova.openstack.common import cfg +from nova.openstack.common.gettextutils import _ from nova.openstack.common import log as logging from nova.openstack.common.notifier import api as notifier_api diff --git a/nova/openstack/common/policy.py b/nova/openstack/common/policy.py index 496ed972d..626a61aa5 100644 --- a/nova/openstack/common/policy.py +++ b/nova/openstack/common/policy.py @@ -574,19 +574,19 @@ class ParseState(object): for reduction, methname in self.reducers: if (len(self.tokens) >= len(reduction) and - self.tokens[-len(reduction):] == reduction): - # Get the reduction method - meth = getattr(self, methname) + self.tokens[-len(reduction):] == reduction): + # Get the reduction method + meth = getattr(self, methname) - # Reduce the token stream - results = meth(*self.values[-len(reduction):]) + # Reduce the token stream + results = meth(*self.values[-len(reduction):]) - # Update the tokens and values - self.tokens[-len(reduction):] = [r[0] for r in results] - self.values[-len(reduction):] = [r[1] for r in results] + # Update the tokens and values + self.tokens[-len(reduction):] = [r[0] for r in results] + self.values[-len(reduction):] = [r[1] for r in results] - # Check for any more reductions - return self.reduce() + # Check for any more reductions + return self.reduce() def shift(self, tok, value): """Adds one more token to the state. Calls reduce().""" diff --git a/nova/openstack/common/rpc/impl_zmq.py b/nova/openstack/common/rpc/impl_zmq.py index 2c0631548..d562b932f 100644 --- a/nova/openstack/common/rpc/impl_zmq.py +++ b/nova/openstack/common/rpc/impl_zmq.py @@ -772,8 +772,9 @@ def _get_ctxt(): return ZMQ_CTX -def _get_matchmaker(): +def _get_matchmaker(*args, **kwargs): global matchmaker if not matchmaker: - matchmaker = importutils.import_object(CONF.rpc_zmq_matchmaker) + matchmaker = importutils.import_object( + CONF.rpc_zmq_matchmaker, *args, **kwargs) return matchmaker diff --git a/nova/openstack/common/rpc/matchmaker.py b/nova/openstack/common/rpc/matchmaker.py index 8b2c67a44..9eec1df83 100644 --- a/nova/openstack/common/rpc/matchmaker.py +++ b/nova/openstack/common/rpc/matchmaker.py @@ -201,24 +201,25 @@ class FanoutRingExchange(RingExchange): class LocalhostExchange(Exchange): """Exchange where all direct topics are local.""" - def __init__(self): + def __init__(self, host='localhost'): + self.host = host super(Exchange, self).__init__() def run(self, key): - return [(key.split('.')[0] + '.localhost', 'localhost')] + return [('.'.join((key.split('.')[0], self.host)), self.host)] class DirectExchange(Exchange): """ Exchange where all topic keys are split, sending to second half. - i.e. "compute.host" sends a message to "compute" running on "host" + i.e. "compute.host" sends a message to "compute.host" running on "host" """ def __init__(self): super(Exchange, self).__init__() def run(self, key): - b, e = key.split('.', 1) - return [(b, e)] + e = key.split('.', 1)[1] + return [(key, e)] class MatchMakerRing(MatchMakerBase): @@ -237,11 +238,11 @@ class MatchMakerLocalhost(MatchMakerBase): Match Maker where all bare topics resolve to localhost. Useful for testing. """ - def __init__(self): + def __init__(self, host='localhost'): super(MatchMakerLocalhost, self).__init__() - self.add_binding(FanoutBinding(), LocalhostExchange()) + self.add_binding(FanoutBinding(), LocalhostExchange(host)) self.add_binding(DirectBinding(), DirectExchange()) - self.add_binding(TopicBinding(), LocalhostExchange()) + self.add_binding(TopicBinding(), LocalhostExchange(host)) class MatchMakerStub(MatchMakerBase): diff --git a/nova/openstack/common/setup.py b/nova/openstack/common/setup.py index fb187fff4..35680b304 100644 --- a/nova/openstack/common/setup.py +++ b/nova/openstack/common/setup.py @@ -274,7 +274,7 @@ def _get_revno(): return len(revlist.splitlines()) -def get_version_from_git(pre_version): +def _get_version_from_git(pre_version): """Return a version which is equal to the tag that's on the current revision if there is one, or tag plus number of additional revisions if the current revision has no tag.""" @@ -294,7 +294,7 @@ def get_version_from_git(pre_version): return None -def get_version_from_pkg_info(package_name): +def _get_version_from_pkg_info(package_name): """Get the version from PKG-INFO file if we can.""" try: pkg_info_file = open('PKG-INFO', 'r') @@ -325,10 +325,10 @@ def get_version(package_name, pre_version=None): version = os.environ.get("OSLO_PACKAGE_VERSION", None) if version: return version - version = get_version_from_pkg_info(package_name) + version = _get_version_from_pkg_info(package_name) if version: return version - version = get_version_from_git(pre_version) + version = _get_version_from_git(pre_version) if version: return version raise Exception("Versioning for this project requires either an sdist" diff --git a/nova/openstack/common/timeutils.py b/nova/openstack/common/timeutils.py index 0f346087f..e2c274057 100644 --- a/nova/openstack/common/timeutils.py +++ b/nova/openstack/common/timeutils.py @@ -98,6 +98,11 @@ def utcnow(): return datetime.datetime.utcnow() +def iso8601_from_timestamp(timestamp): + """Returns a iso8601 formated date from timestamp""" + return isotime(datetime.datetime.utcfromtimestamp(timestamp)) + + utcnow.override_time = None @@ -162,3 +167,16 @@ def delta_seconds(before, after): except AttributeError: return ((delta.days * 24 * 3600) + delta.seconds + float(delta.microseconds) / (10 ** 6)) + + +def is_soon(dt, window): + """ + Determines if time is going to happen in the next window seconds. + + :params dt: the time + :params window: minimum seconds to remain to consider the time not soon + + :return: True if expiration is within the given duration + """ + soon = (utcnow() + datetime.timedelta(seconds=window)) + return normalize_time(dt) <= soon diff --git a/nova/openstack/common/version.py b/nova/openstack/common/version.py index b16ef4bca..57803b3d5 100644 --- a/nova/openstack/common/version.py +++ b/nova/openstack/common/version.py @@ -33,6 +33,14 @@ class VersionInfo(object): self.version = None self._cached_version = None + def __str__(self): + """Make the VersionInfo object behave like a string.""" + return self.version_string() + + def __repr__(self): + """Include the name.""" + return "VersionInfo(%s:%s)" % (self.package, self.version_string()) + def _get_version_from_pkg_resources(self): """Get the version of the package from the pkg_resources record associated with the package.""" @@ -41,11 +49,11 @@ class VersionInfo(object): provider = pkg_resources.get_provider(requirement) return provider.version except pkg_resources.DistributionNotFound: - # The most likely cause for this is running tests in a tree with + # The most likely cause for this is running tests in a tree # produced from a tarball where the package itself has not been - # installed into anything. Check for a PKG-INFO file. + # installed into anything. Revert to setup-time logic. from nova.openstack.common import setup - return setup.get_version_from_pkg_info(self.package) + return setup.get_version(self.package) def release_string(self): """Return the full version of the package including suffixes indicating |