diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-08-16 16:38:17 -0700 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-08-16 18:09:46 -0700 |
| commit | 49428ad47f0c01a2dcc079975823f7b856fb165e (patch) | |
| tree | 6870fce7555f253bf0a220605eee5af739955af1 | |
| parent | 06d1f0dfd5d22ace96b414fd0b71fbaa668b95ce (diff) | |
| download | nova-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
| -rw-r--r-- | nova/openstack/common/cfg.py | 85 | ||||
| -rw-r--r-- | nova/openstack/common/notifier/api.py | 1 | ||||
| -rw-r--r-- | nova/openstack/common/plugin/pluginmanager.py | 2 | ||||
| -rw-r--r-- | nova/openstack/common/rpc/common.py | 2 | ||||
| -rw-r--r-- | nova/openstack/common/rpc/impl_zmq.py | 5 | ||||
| -rw-r--r-- | nova/openstack/common/timeutils.py | 18 |
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']) |
