Sync latest cfg changes from openstack-common

Syncs the following changes from stable/folsom:

 4dc2043 cfg: clean up None value handling
 513bd3a Allow set_default and set_override to use None
 0a36c92 Tilde expansion for --config-file and --config-dir
 038d597 Add import_opt() method to ConfigOpts

Change-Id: I615cdbd6dc7c3ec0218252c202f24c2a2d3aa387
This commit is contained in:
Mark McLoughlin
2012-09-05 11:27:58 +01:00
parent d7041f500b
commit cc9910b50f

View File

@@ -367,6 +367,11 @@ class ConfigFileValueError(Error):
pass 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): def _get_config_dirs(project=None):
"""Return a list of directors where config files may be located. """Return a list of directors where config files may be located.
@@ -384,11 +389,9 @@ def _get_config_dirs(project=None):
~/ ~/
/etc/ /etc/
""" """
fix_path = lambda p: os.path.abspath(os.path.expanduser(p))
cfg_dirs = [ cfg_dirs = [
fix_path(os.path.join('~', '.' + project)) if project else None, _fixpath(os.path.join('~', '.' + project)) if project else None,
fix_path('~'), _fixpath('~'),
os.path.join('/etc', project) if project else None, os.path.join('/etc', project) if project else None,
'/etc' '/etc'
] ]
@@ -809,7 +812,7 @@ class OptGroup(object):
if _is_opt_registered(self._opts, opt): if _is_opt_registered(self._opts, opt):
return False return False
self._opts[opt.dest] = {'opt': opt, 'override': None, 'default': None} self._opts[opt.dest] = {'opt': opt}
return True return True
@@ -1087,7 +1090,7 @@ class ConfigOpts(collections.Mapping):
if _is_opt_registered(self._opts, opt): if _is_opt_registered(self._opts, opt):
return False return False
self._opts[opt.dest] = {'opt': opt, 'override': None, 'default': None} self._opts[opt.dest] = {'opt': opt}
return True return True
@@ -1156,6 +1159,25 @@ class ConfigOpts(collections.Mapping):
for opt in opts: for opt in opts:
self.unregister_opt(opt, group, clear_cache=False) 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 @__clear_cache
def set_override(self, name, override, group=None): def set_override(self, name, override, group=None):
"""Override an opt value. """Override an opt value.
@@ -1186,6 +1208,33 @@ class ConfigOpts(collections.Mapping):
opt_info = self._get_opt_info(name, group) opt_info = self._get_opt_info(name, group)
opt_info['default'] = default 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): def _all_opt_infos(self):
"""A generator function for iteration opt infos.""" """A generator function for iteration opt infos."""
for info in self._opts.values(): for info in self._opts.values():
@@ -1202,8 +1251,8 @@ class ConfigOpts(collections.Mapping):
def _unset_defaults_and_overrides(self): def _unset_defaults_and_overrides(self):
"""Unset any default or override on all options.""" """Unset any default or override on all options."""
for info, group in self._all_opt_infos(): for info, group in self._all_opt_infos():
info['default'] = None info.pop('default', None)
info['override'] = None info.pop('override', None)
def disable_interspersed_args(self): def disable_interspersed_args(self):
"""Set parsing to stop on the first non-option. """Set parsing to stop on the first non-option.
@@ -1249,10 +1298,10 @@ class ConfigOpts(collections.Mapping):
""" """
dirs = [] dirs = []
if self.config_dir: if self.config_dir:
dirs.append(self.config_dir) dirs.append(_fixpath(self.config_dir))
for cf in reversed(self.config_file): 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)) dirs.extend(_get_config_dirs(self.project))
@@ -1326,10 +1375,10 @@ class ConfigOpts(collections.Mapping):
return self.GroupAttr(self, self._get_group(name)) return self.GroupAttr(self, self._get_group(name))
info = self._get_opt_info(name, group) 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: if 'override' in info:
return override return info['override']
values = [] values = []
if self._cparser is not None: if self._cparser is not None:
@@ -1357,8 +1406,8 @@ class ConfigOpts(collections.Mapping):
if values: if values:
return values return values
if default is not None: if 'default' in info:
return default return info['default']
return opt.default return opt.default
@@ -1433,6 +1482,8 @@ class ConfigOpts(collections.Mapping):
config_dir_glob = os.path.join(self.config_dir, '*.conf') config_dir_glob = os.path.join(self.config_dir, '*.conf')
config_files += sorted(glob.glob(config_dir_glob)) config_files += sorted(glob.glob(config_dir_glob))
config_files = [_fixpath(p) for p in config_files]
self._cparser = MultiConfigParser() self._cparser = MultiConfigParser()
try: try:
@@ -1450,10 +1501,10 @@ class ConfigOpts(collections.Mapping):
:raises: RequiredOptError :raises: RequiredOptError
""" """
for info, group in self._all_opt_infos(): 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 opt.required:
if (default is not None or override is not None): if ('default' in info or 'override' in info):
continue continue
if self._get(opt.name, group) is None: if self._get(opt.name, group) is None: