summaryrefslogtreecommitdiffstats
path: root/nova/openstack
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2012-08-16 16:38:17 -0700
committerVishvananda Ishaya <vishvananda@gmail.com>2012-08-16 18:09:46 -0700
commit49428ad47f0c01a2dcc079975823f7b856fb165e (patch)
tree6870fce7555f253bf0a220605eee5af739955af1 /nova/openstack
parent06d1f0dfd5d22ace96b414fd0b71fbaa668b95ce (diff)
downloadnova-49428ad47f0c01a2dcc079975823f7b856fb165e.tar.gz
nova-49428ad47f0c01a2dcc079975823f7b856fb165e.tar.xz
nova-49428ad47f0c01a2dcc079975823f7b856fb165e.zip
Sync changes from openstack common
* Changes to cfg to handle None overrides, tilde expansion, and importing opts. * Changes to timeutils to marshall and unmarshall datetimes. * Cleanups for zeromq and rpc. * Removal of unused imports. Change-Id: Ica7a2e51ea38f37b315be2ff382d4a615dd67207
Diffstat (limited to 'nova/openstack')
-rw-r--r--nova/openstack/common/cfg.py85
-rw-r--r--nova/openstack/common/notifier/api.py1
-rw-r--r--nova/openstack/common/plugin/pluginmanager.py2
-rw-r--r--nova/openstack/common/rpc/common.py2
-rw-r--r--nova/openstack/common/rpc/impl_zmq.py5
-rw-r--r--nova/openstack/common/timeutils.py18
6 files changed, 86 insertions, 27 deletions
diff --git a/nova/openstack/common/cfg.py b/nova/openstack/common/cfg.py
index c0b0161ff..36e5e0ab0 100644
--- a/nova/openstack/common/cfg.py
+++ b/nova/openstack/common/cfg.py
@@ -367,6 +367,11 @@ class ConfigFileValueError(Error):
pass
+def _fixpath(p):
+ """Apply tilde expansion and absolutization to a path."""
+ return os.path.abspath(os.path.expanduser(p))
+
+
def _get_config_dirs(project=None):
"""Return a list of directors where config files may be located.
@@ -384,11 +389,9 @@ def _get_config_dirs(project=None):
~/
/etc/
"""
- fix_path = lambda p: os.path.abspath(os.path.expanduser(p))
-
cfg_dirs = [
- fix_path(os.path.join('~', '.' + project)) if project else None,
- fix_path('~'),
+ _fixpath(os.path.join('~', '.' + project)) if project else None,
+ _fixpath('~'),
os.path.join('/etc', project) if project else None,
'/etc'
]
@@ -809,7 +812,7 @@ class OptGroup(object):
if _is_opt_registered(self._opts, opt):
return False
- self._opts[opt.dest] = {'opt': opt, 'override': None, 'default': None}
+ self._opts[opt.dest] = {'opt': opt}
return True
@@ -1087,7 +1090,7 @@ class ConfigOpts(collections.Mapping):
if _is_opt_registered(self._opts, opt):
return False
- self._opts[opt.dest] = {'opt': opt, 'override': None, 'default': None}
+ self._opts[opt.dest] = {'opt': opt}
return True
@@ -1156,6 +1159,25 @@ class ConfigOpts(collections.Mapping):
for opt in opts:
self.unregister_opt(opt, group, clear_cache=False)
+ def import_opt(self, name, module_str, group=None):
+ """Import an option definition from a module.
+
+ Import a module and check that a given option 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
+ defined by another module it can use this method to explicitly
+ declare the dependency.
+
+ :param name: the name/dest of the opt
+ :param module_str: the name of a module to import
+ :param group: an option OptGroup object or group name
+ :raises: NoSuchOptError, NoSuchGroupError
+ """
+ __import__(module_str)
+ self._get_opt_info(name, group)
+
@__clear_cache
def set_override(self, name, override, group=None):
"""Override an opt value.
@@ -1186,6 +1208,33 @@ class ConfigOpts(collections.Mapping):
opt_info = self._get_opt_info(name, group)
opt_info['default'] = default
+ @__clear_cache
+ def clear_override(self, name, group=None):
+ """Clear an override an opt value.
+
+ Clear a previously set override of the command line, config file
+ and default values of a given option.
+
+ :param name: the name/dest of the opt
+ :param group: an option OptGroup object or group name
+ :raises: NoSuchOptError, NoSuchGroupError
+ """
+ opt_info = self._get_opt_info(name, group)
+ opt_info.pop('override', None)
+
+ @__clear_cache
+ def clear_default(self, name, group=None):
+ """Clear an override an opt's default value.
+
+ Clear a previously set override of the default value of given option.
+
+ :param name: the name/dest of the opt
+ :param group: an option OptGroup object or group name
+ :raises: NoSuchOptError, NoSuchGroupError
+ """
+ opt_info = self._get_opt_info(name, group)
+ opt_info.pop('default', None)
+
def _all_opt_infos(self):
"""A generator function for iteration opt infos."""
for info in self._opts.values():
@@ -1202,8 +1251,8 @@ class ConfigOpts(collections.Mapping):
def _unset_defaults_and_overrides(self):
"""Unset any default or override on all options."""
for info, group in self._all_opt_infos():
- info['default'] = None
- info['override'] = None
+ info.pop('default', None)
+ info.pop('override', None)
def disable_interspersed_args(self):
"""Set parsing to stop on the first non-option.
@@ -1249,10 +1298,10 @@ class ConfigOpts(collections.Mapping):
"""
dirs = []
if self.config_dir:
- dirs.append(self.config_dir)
+ dirs.append(_fixpath(self.config_dir))
for cf in reversed(self.config_file):
- dirs.append(os.path.dirname(cf))
+ dirs.append(os.path.dirname(_fixpath(cf)))
dirs.extend(_get_config_dirs(self.project))
@@ -1326,10 +1375,10 @@ class ConfigOpts(collections.Mapping):
return self.GroupAttr(self, self._get_group(name))
info = self._get_opt_info(name, group)
- default, opt, override = [info[k] for k in sorted(info.keys())]
+ opt = info['opt']
- if override is not None:
- return override
+ if 'override' in info:
+ return info['override']
values = []
if self._cparser is not None:
@@ -1357,8 +1406,8 @@ class ConfigOpts(collections.Mapping):
if values:
return values
- if default is not None:
- return default
+ if 'default' in info:
+ return info['default']
return opt.default
@@ -1433,6 +1482,8 @@ class ConfigOpts(collections.Mapping):
config_dir_glob = os.path.join(self.config_dir, '*.conf')
config_files += sorted(glob.glob(config_dir_glob))
+ config_files = [_fixpath(p) for p in config_files]
+
self._cparser = MultiConfigParser()
try:
@@ -1450,10 +1501,10 @@ class ConfigOpts(collections.Mapping):
:raises: RequiredOptError
"""
for info, group in self._all_opt_infos():
- default, opt, override = [info[k] for k in sorted(info.keys())]
+ opt = info['opt']
if opt.required:
- if (default is not None or override is not None):
+ if ('default' in info or 'override' in info):
continue
if self._get(opt.name, group) is None:
diff --git a/nova/openstack/common/notifier/api.py b/nova/openstack/common/notifier/api.py
index f90a4eba8..95573dd65 100644
--- a/nova/openstack/common/notifier/api.py
+++ b/nova/openstack/common/notifier/api.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import inspect
import uuid
from nova.openstack.common import cfg
diff --git a/nova/openstack/common/plugin/pluginmanager.py b/nova/openstack/common/plugin/pluginmanager.py
index 29656477d..51d06d851 100644
--- a/nova/openstack/common/plugin/pluginmanager.py
+++ b/nova/openstack/common/plugin/pluginmanager.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import imp
-import os
import pkg_resources
from nova.openstack.common import cfg
diff --git a/nova/openstack/common/rpc/common.py b/nova/openstack/common/rpc/common.py
index 01db756eb..eb3416804 100644
--- a/nova/openstack/common/rpc/common.py
+++ b/nova/openstack/common/rpc/common.py
@@ -19,10 +19,8 @@
import copy
import logging
-import sys
import traceback
-from nova.openstack.common import cfg
from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
diff --git a/nova/openstack/common/rpc/impl_zmq.py b/nova/openstack/common/rpc/impl_zmq.py
index 6f215891b..8d6c73206 100644
--- a/nova/openstack/common/rpc/impl_zmq.py
+++ b/nova/openstack/common/rpc/impl_zmq.py
@@ -639,26 +639,22 @@ def create_connection(conf, new=True):
def multicall(conf, *args, **kwargs):
"""Multiple calls."""
- register_opts(conf)
return _multi_send(_call, *args, **kwargs)
def call(conf, *args, **kwargs):
"""Send a message, expect a response."""
- register_opts(conf)
data = _multi_send(_call, *args, **kwargs)
return data[-1]
def cast(conf, *args, **kwargs):
"""Send a message expecting no reply."""
- register_opts(conf)
_multi_send(_cast, *args, **kwargs)
def fanout_cast(conf, context, topic, msg, **kwargs):
"""Send a message to all listening and expect no reply."""
- register_opts(conf)
# NOTE(ewindisch): fanout~ is used because it avoid splitting on .
# and acts as a non-subtle hint to the matchmaker and ZmqProxy.
_multi_send(_cast, context, 'fanout~' + str(topic), msg, **kwargs)
@@ -670,7 +666,6 @@ def notify(conf, context, topic, msg, **kwargs):
Notifications are sent to topic-priority.
This differs from the AMQP drivers which send to topic.priority.
"""
- register_opts(conf)
# NOTE(ewindisch): dot-priority in rpc notifier does not
# work with our assumptions.
topic.replace('.', '-')
diff --git a/nova/openstack/common/timeutils.py b/nova/openstack/common/timeutils.py
index 4416a3b19..ae300e456 100644
--- a/nova/openstack/common/timeutils.py
+++ b/nova/openstack/common/timeutils.py
@@ -106,3 +106,21 @@ def advance_time_seconds(seconds):
def clear_time_override():
"""Remove the overridden time."""
utcnow.override_time = None
+
+
+def marshall_now(now=None):
+ """Make an rpc-safe datetime with microseconds.
+
+ Note: tzinfo is stripped, but not required for relative times."""
+ if not now:
+ now = utcnow()
+ return dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
+ minute=now.minute, second=now.second,
+ microsecond=now.microsecond)
+
+
+def unmarshall_time(tyme):
+ """Unmarshall a datetime dict."""
+ return datetime.datetime(day=tyme['day'], month=tyme['month'],
+ year=tyme['year'], hour=tyme['hour'], minute=tyme['minute'],
+ second=tyme['second'], microsecond=tyme['microsecond'])