Merge "Synchronize code from oslo"
This commit is contained in:
commit
26389d30f2
@ -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,
|
||||
|
@ -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.
|
@ -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.
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()."""
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user