Update cfg from openstack-common
Use openstack-common's update.py script to pull in some recent changes: * Add the Mapping interface to cfg.ConfigOpts * Add support to cfg for disabling interspersed args Make use of both of these in nova/flags.py. Add some dire warnings to HACKING about directly modifying the copy of openstack-common code. I'm confident they won't be ignored :-) Change-Id: I7ef75d18922c0bbb8844453b48cad0418034bc11
This commit is contained in:
parent
16882ad36b
commit
259d3e356b
15
HACKING.rst
15
HACKING.rst
@ -179,3 +179,18 @@ without the patch and passes with the patch.
|
|||||||
|
|
||||||
For more information on creating unit tests and utilizing the testing
|
For more information on creating unit tests and utilizing the testing
|
||||||
infrastructure in OpenStack Nova, please read nova/testing/README.rst.
|
infrastructure in OpenStack Nova, please read nova/testing/README.rst.
|
||||||
|
|
||||||
|
|
||||||
|
openstack-common
|
||||||
|
----------------
|
||||||
|
|
||||||
|
A number of modules from openstack-common are imported into the project.
|
||||||
|
|
||||||
|
These modules are "incubating" in openstack-common and are kept in sync
|
||||||
|
with the help of openstack-common's update.py script. See:
|
||||||
|
|
||||||
|
http://wiki.openstack.org/CommonLibrary#Incubation
|
||||||
|
|
||||||
|
The copy of the code should never be directly modified here. Please
|
||||||
|
always update openstack-common first and then run the script to copy
|
||||||
|
the changes across.
|
||||||
|
@ -69,7 +69,7 @@ class FlagValues(object):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._conf = cfg.ConfigOpts()
|
self._conf = cfg.ConfigOpts()
|
||||||
self._conf._oparser.disable_interspersed_args()
|
self._conf.disable_interspersed_args()
|
||||||
self._opts = {}
|
self._opts = {}
|
||||||
self.Reset()
|
self.Reset()
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ class FlagValues(object):
|
|||||||
self._conf.set_default(name, default)
|
self._conf.set_default(name, default)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self.FlagValuesDict().iterkeys()
|
return self._conf.iterkeys()
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
self._parse()
|
self._parse()
|
||||||
@ -147,12 +147,12 @@ class FlagValues(object):
|
|||||||
def FlagValuesDict(self):
|
def FlagValuesDict(self):
|
||||||
self._parse()
|
self._parse()
|
||||||
ret = {}
|
ret = {}
|
||||||
for opt in self._opts.values():
|
for name in self._conf:
|
||||||
ret[opt.dest] = getattr(self, opt.dest)
|
ret[name] = getattr(self, name)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def add_option(self, opt):
|
def add_option(self, opt):
|
||||||
if opt.dest in self._opts:
|
if opt.dest in self._conf:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._opts[opt.dest] = opt
|
self._opts[opt.dest] = opt
|
||||||
|
13
nova/openstack/common/README
Normal file
13
nova/openstack/common/README
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
openstack-common
|
||||||
|
----------------
|
||||||
|
|
||||||
|
A number of modules from openstack-common are imported into this project.
|
||||||
|
|
||||||
|
These modules are "incubating" in openstack-common and are kept in sync
|
||||||
|
with the help of openstack-common's update.py script. See:
|
||||||
|
|
||||||
|
http://wiki.openstack.org/CommonLibrary#Incubation
|
||||||
|
|
||||||
|
The copy of the code should never be directly modified here. Please
|
||||||
|
always update openstack-common first and then run the script to copy
|
||||||
|
the changes across.
|
@ -134,24 +134,18 @@ Options can be registered as belonging to a group:
|
|||||||
|
|
||||||
rabbit_host_opt = \
|
rabbit_host_opt = \
|
||||||
cfg.StrOpt('host',
|
cfg.StrOpt('host',
|
||||||
group='rabbit',
|
|
||||||
default='localhost',
|
default='localhost',
|
||||||
help='IP/hostname to listen on'),
|
help='IP/hostname to listen on'),
|
||||||
rabbit_port_opt = \
|
rabbit_port_opt = \
|
||||||
cfg.IntOpt('port',
|
cfg.IntOpt('port',
|
||||||
default=5672,
|
default=5672,
|
||||||
help='Port number to listen on')
|
help='Port number to listen on')
|
||||||
rabbit_ssl_opt = \
|
|
||||||
conf.BoolOpt('use_ssl',
|
|
||||||
default=False,
|
|
||||||
help='Whether to support SSL connections')
|
|
||||||
|
|
||||||
def register_rabbit_opts(conf):
|
def register_rabbit_opts(conf):
|
||||||
conf.register_group(rabbit_group)
|
conf.register_group(rabbit_group)
|
||||||
# options can be registered under a group in any of these ways:
|
# options can be registered under a group in either of these ways:
|
||||||
conf.register_opt(rabbit_host_opt)
|
conf.register_opt(rabbit_host_opt, group=rabbit_group)
|
||||||
conf.register_opt(rabbit_port_opt, group='rabbit')
|
conf.register_opt(rabbit_port_opt, group='rabbit')
|
||||||
conf.register_opt(rabbit_ssl_opt, group=rabbit_group)
|
|
||||||
|
|
||||||
If no group is specified, options belong to the 'DEFAULT' section of config
|
If no group is specified, options belong to the 'DEFAULT' section of config
|
||||||
files:
|
files:
|
||||||
@ -171,7 +165,7 @@ files:
|
|||||||
|
|
||||||
Command-line options in a group are automatically prefixed with the group name:
|
Command-line options in a group are automatically prefixed with the group name:
|
||||||
|
|
||||||
--rabbit-host localhost --rabbit-use-ssl False
|
--rabbit-host localhost --rabbit-port 9999
|
||||||
|
|
||||||
Option values in the default group are referenced as attributes/properties on
|
Option values in the default group are referenced as attributes/properties on
|
||||||
the config manager; groups are also attributes on the config manager, with
|
the config manager; groups are also attributes on the config manager, with
|
||||||
@ -199,14 +193,31 @@ Option values may reference other values using PEP 292 string substitution:
|
|||||||
]
|
]
|
||||||
|
|
||||||
Note that interpolation can be avoided by using '$$'.
|
Note that interpolation can be avoided by using '$$'.
|
||||||
|
|
||||||
|
For command line utilities that dispatch to other command line utilities, the
|
||||||
|
disable_interspersed_args() method is available. If this this method is called,
|
||||||
|
then parsing e.g.
|
||||||
|
|
||||||
|
script --verbose cmd --debug /tmp/mything
|
||||||
|
|
||||||
|
will no longer return:
|
||||||
|
|
||||||
|
['cmd', '/tmp/mything']
|
||||||
|
|
||||||
|
as the leftover arguments, but will instead return:
|
||||||
|
|
||||||
|
['cmd', '--debug', '/tmp/mything']
|
||||||
|
|
||||||
|
i.e. argument parsing is stopped at the first non-option argument.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import collections
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
import copy
|
import copy
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
@ -540,6 +551,7 @@ class BoolOpt(Opt):
|
|||||||
container = self._get_optparse_container(parser, group)
|
container = self._get_optparse_container(parser, group)
|
||||||
kwargs = self._get_optparse_kwargs(group, action='store_false')
|
kwargs = self._get_optparse_kwargs(group, action='store_false')
|
||||||
prefix = self._get_optparse_prefix('no', group)
|
prefix = self._get_optparse_prefix('no', group)
|
||||||
|
kwargs["help"] = "The inverse of --" + self.name
|
||||||
self._add_to_optparse(container, self.name, None, kwargs, prefix)
|
self._add_to_optparse(container, self.name, None, kwargs, prefix)
|
||||||
|
|
||||||
def _get_optparse_kwargs(self, group, action='store_true', **kwargs):
|
def _get_optparse_kwargs(self, group, action='store_true', **kwargs):
|
||||||
@ -681,7 +693,7 @@ class OptGroup(object):
|
|||||||
return self._optparse_group
|
return self._optparse_group
|
||||||
|
|
||||||
|
|
||||||
class ConfigOpts(object):
|
class ConfigOpts(collections.Mapping, object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Config options which may be set on the command line or in config files.
|
Config options which may be set on the command line or in config files.
|
||||||
@ -776,6 +788,23 @@ class ConfigOpts(object):
|
|||||||
"""
|
"""
|
||||||
return self._substitute(self._get(name))
|
return self._substitute(self._get(name))
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
"""Look up an option value and perform string substitution."""
|
||||||
|
return self.__getattr__(key)
|
||||||
|
|
||||||
|
def __contains__(self, key):
|
||||||
|
"""Return True if key is the name of a registered opt or group."""
|
||||||
|
return key in self._opts or key in self._groups
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""Iterate over all registered opt and group names."""
|
||||||
|
for key in self._opts.keys() + self._groups.keys():
|
||||||
|
yield key
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""Return the number of options and option groups."""
|
||||||
|
return len(self._opts) + len(self._groups)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset the state of the object to before it was called."""
|
"""Reset the state of the object to before it was called."""
|
||||||
self._args = None
|
self._args = None
|
||||||
@ -880,6 +909,31 @@ class ConfigOpts(object):
|
|||||||
opt_info = self._get_opt_info(name, group)
|
opt_info = self._get_opt_info(name, group)
|
||||||
opt_info['default'] = default
|
opt_info['default'] = default
|
||||||
|
|
||||||
|
def disable_interspersed_args(self):
|
||||||
|
"""Set parsing to stop on the first non-option.
|
||||||
|
|
||||||
|
If this this method is called, then parsing e.g.
|
||||||
|
|
||||||
|
script --verbose cmd --debug /tmp/mything
|
||||||
|
|
||||||
|
will no longer return:
|
||||||
|
|
||||||
|
['cmd', '/tmp/mything']
|
||||||
|
|
||||||
|
as the leftover arguments, but will instead return:
|
||||||
|
|
||||||
|
['cmd', '--debug', '/tmp/mything']
|
||||||
|
|
||||||
|
i.e. argument parsing is stopped at the first non-option argument.
|
||||||
|
"""
|
||||||
|
self._oparser.disable_interspersed_args()
|
||||||
|
|
||||||
|
def enable_interspersed_args(self):
|
||||||
|
"""Set parsing to not stop on the first non-option.
|
||||||
|
|
||||||
|
This it the default behaviour."""
|
||||||
|
self._oparser.enable_interspersed_args()
|
||||||
|
|
||||||
def log_opt_values(self, logger, lvl):
|
def log_opt_values(self, logger, lvl):
|
||||||
"""Log the value of all registered opts.
|
"""Log the value of all registered opts.
|
||||||
|
|
||||||
@ -900,7 +954,7 @@ class ConfigOpts(object):
|
|||||||
logger.log(lvl, "%-30s = %s", opt_name, getattr(self, opt_name))
|
logger.log(lvl, "%-30s = %s", opt_name, getattr(self, opt_name))
|
||||||
|
|
||||||
for group_name in self._groups:
|
for group_name in self._groups:
|
||||||
group_attr = self.GroupAttr(self, group_name)
|
group_attr = self.GroupAttr(self, self._get_group(group_name))
|
||||||
for opt_name in sorted(self._groups[group_name]._opts):
|
for opt_name in sorted(self._groups[group_name]._opts):
|
||||||
logger.log(lvl, "%-30s = %s",
|
logger.log(lvl, "%-30s = %s",
|
||||||
"%s.%s" % (group_name, opt_name),
|
"%s.%s" % (group_name, opt_name),
|
||||||
@ -916,16 +970,13 @@ class ConfigOpts(object):
|
|||||||
"""Look up an option value.
|
"""Look up an option value.
|
||||||
|
|
||||||
:param name: the opt name (or 'dest', more precisely)
|
:param name: the opt name (or 'dest', more precisely)
|
||||||
:param group: an option OptGroup
|
:param group: an OptGroup
|
||||||
:returns: the option value, or a GroupAttr object
|
:returns: the option value, or a GroupAttr object
|
||||||
:raises: NoSuchOptError, NoSuchGroupError, ConfigFileValueError,
|
:raises: NoSuchOptError, NoSuchGroupError, ConfigFileValueError,
|
||||||
TemplateSubstitutionError
|
TemplateSubstitutionError
|
||||||
"""
|
"""
|
||||||
if group is None and name in self._groups:
|
if group is None and name in self._groups:
|
||||||
return self.GroupAttr(self, name)
|
return self.GroupAttr(self, self._get_group(name))
|
||||||
|
|
||||||
if group is not None:
|
|
||||||
group = self._get_group(group)
|
|
||||||
|
|
||||||
info = self._get_opt_info(name, group)
|
info = self._get_opt_info(name, group)
|
||||||
default, opt, override = map(lambda k: info[k], sorted(info.keys()))
|
default, opt, override = map(lambda k: info[k], sorted(info.keys()))
|
||||||
@ -1027,17 +1078,18 @@ class ConfigOpts(object):
|
|||||||
not_read_ok = filter(lambda f: f not in read_ok, config_files)
|
not_read_ok = filter(lambda f: f not in read_ok, config_files)
|
||||||
raise ConfigFilesNotFoundError(not_read_ok)
|
raise ConfigFilesNotFoundError(not_read_ok)
|
||||||
|
|
||||||
class GroupAttr(object):
|
class GroupAttr(collections.Mapping, object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A helper class representing the option values of a group as attributes.
|
A helper class representing the option values of a group as a mapping
|
||||||
|
and attributes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, conf, group):
|
def __init__(self, conf, group):
|
||||||
"""Construct a GroupAttr object.
|
"""Construct a GroupAttr object.
|
||||||
|
|
||||||
:param conf: a ConfigOpts object
|
:param conf: a ConfigOpts object
|
||||||
:param group: a group name or OptGroup object
|
:param group: an OptGroup object
|
||||||
"""
|
"""
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.group = group
|
self.group = group
|
||||||
@ -1046,6 +1098,23 @@ class ConfigOpts(object):
|
|||||||
"""Look up an option value and perform template substitution."""
|
"""Look up an option value and perform template substitution."""
|
||||||
return self.conf._substitute(self.conf._get(name, self.group))
|
return self.conf._substitute(self.conf._get(name, self.group))
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
"""Look up an option value and perform string substitution."""
|
||||||
|
return self.__getattr__(key)
|
||||||
|
|
||||||
|
def __contains__(self, key):
|
||||||
|
"""Return True if key is the name of a registered opt or group."""
|
||||||
|
return key in self.group._opts
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""Iterate over all registered opt and group names."""
|
||||||
|
for key in self.group._opts.keys():
|
||||||
|
yield key
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""Return the number of options and option groups."""
|
||||||
|
return len(self.group._opts)
|
||||||
|
|
||||||
class StrSubWrapper(object):
|
class StrSubWrapper(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -1118,6 +1187,9 @@ class CommonConfigOpts(ConfigOpts):
|
|||||||
BoolOpt('use-syslog',
|
BoolOpt('use-syslog',
|
||||||
default=False,
|
default=False,
|
||||||
help='Use syslog for logging.'),
|
help='Use syslog for logging.'),
|
||||||
|
StrOpt('syslog-log-facility',
|
||||||
|
default='LOG_USER',
|
||||||
|
help='syslog facility to receive log lines')
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
7
openstack-common.conf
Normal file
7
openstack-common.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
# The list of modules to copy from openstack-common
|
||||||
|
modules=cfg
|
||||||
|
|
||||||
|
# The base module to hold the copy of openstack.common
|
||||||
|
base=nova
|
Loading…
Reference in New Issue
Block a user