summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/nova-rootwrap17
-rw-r--r--nova/openstack/__init__.py15
-rw-r--r--nova/openstack/common/__init__.py15
-rw-r--r--nova/openstack/common/cfg.py30
-rw-r--r--nova/openstack/common/cliutils.py13
-rw-r--r--nova/openstack/common/excutils.py6
-rw-r--r--nova/openstack/common/plugin/pluginmanager.py1
-rw-r--r--nova/openstack/common/policy.py20
-rw-r--r--nova/openstack/common/rpc/impl_zmq.py5
-rw-r--r--nova/openstack/common/rpc/matchmaker.py17
-rw-r--r--nova/openstack/common/setup.py8
-rw-r--r--nova/openstack/common/timeutils.py18
-rw-r--r--nova/openstack/common/version.py14
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