move some documentation out of the source files
The cfg module is very large, and starts with a huge block of documentation. This patch moves that information into separate files in the reference section of the docs. A few formatting fixes need to be made to have it build cleanly, but the content is not changed in a substantive way. Change-Id: I86aa90bbf180b5dc9acbcedb024e5361d49954c3 Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
ce150b1037
commit
bd463ee3b6
16
doc/source/reference/accessing.rst
Normal file
16
doc/source/reference/accessing.rst
Normal file
@ -0,0 +1,16 @@
|
||||
======================================
|
||||
Accessing Option Values In Your Code
|
||||
======================================
|
||||
|
||||
Option values in the default group are referenced as attributes/properties on
|
||||
the config manager; groups are also attributes on the config manager, with
|
||||
attributes for each of the options associated with the group:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
server.start(app, conf.bind_port, conf.bind_host, conf)
|
||||
|
||||
self.connection = kombu.connection.BrokerConnection(
|
||||
hostname=conf.rabbit.host,
|
||||
port=conf.rabbit.port,
|
||||
...)
|
@ -1,5 +0,0 @@
|
||||
--------------
|
||||
The cfg Module
|
||||
--------------
|
||||
|
||||
.. automodule:: oslo_config.cfg
|
37
doc/source/reference/command-line.rst
Normal file
37
doc/source/reference/command-line.rst
Normal file
@ -0,0 +1,37 @@
|
||||
======================
|
||||
Command Line Options
|
||||
======================
|
||||
|
||||
Positional Command Line Arguments
|
||||
---------------------------------
|
||||
|
||||
Positional command line arguments are supported via a 'positional' Opt
|
||||
constructor argument:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
>>> conf = cfg.ConfigOpts()
|
||||
>>> conf.register_cli_opt(cfg.MultiStrOpt('bar', positional=True))
|
||||
True
|
||||
>>> conf(['a', 'b'])
|
||||
>>> conf.bar
|
||||
['a', 'b']
|
||||
|
||||
Sub-Parsers
|
||||
-----------
|
||||
|
||||
It is also possible to use argparse "sub-parsers" to parse additional
|
||||
command line arguments using the SubCommandOpt class:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
>>> def add_parsers(subparsers):
|
||||
... list_action = subparsers.add_parser('list')
|
||||
... list_action.add_argument('id')
|
||||
...
|
||||
>>> conf = cfg.ConfigOpts()
|
||||
>>> conf.register_cli_opt(cfg.SubCommandOpt('action', handler=add_parsers))
|
||||
True
|
||||
>>> conf(args=['list', '10'])
|
||||
>>> conf.action.name, conf.action.id
|
||||
('list', '10')
|
84
doc/source/reference/configuration-files.rst
Normal file
84
doc/source/reference/configuration-files.rst
Normal file
@ -0,0 +1,84 @@
|
||||
=============================
|
||||
Loading Configuration Files
|
||||
=============================
|
||||
|
||||
The config manager has two CLI options defined by default, ``--config-file``
|
||||
and ``--config-dir``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class ConfigOpts(object):
|
||||
|
||||
def __call__(self, ...):
|
||||
|
||||
opts = [
|
||||
MultiStrOpt('config-file',
|
||||
...),
|
||||
StrOpt('config-dir',
|
||||
...),
|
||||
]
|
||||
|
||||
self.register_cli_opts(opts)
|
||||
|
||||
Option values are parsed from any supplied config files using
|
||||
oslo_config.iniparser. If none are specified, a default set is used
|
||||
for example glance-api.conf and glance-common.conf:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
bind_port = 9292
|
||||
|
||||
glance-common.conf:
|
||||
[DEFAULT]
|
||||
bind_host = 0.0.0.0
|
||||
|
||||
Lines in a configuration file should not start with whitespace. A
|
||||
configuration file also supports comments, which must start with '#' or ';'.
|
||||
Option values in config files and those on the command line are parsed
|
||||
in order. The same option (includes deprecated option name and current
|
||||
option name) can appear many times, in config files or on the command line.
|
||||
Later values always override earlier ones.
|
||||
|
||||
The order of configuration files inside the same configuration directory is
|
||||
defined by the alphabetic sorting order of their file names.
|
||||
|
||||
The parsing of CLI args and config files is initiated by invoking the config
|
||||
manager for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
conf = cfg.ConfigOpts()
|
||||
conf.register_opt(cfg.BoolOpt('verbose', ...))
|
||||
conf(sys.argv[1:])
|
||||
if conf.verbose:
|
||||
...
|
||||
|
||||
Option Value Interpolation
|
||||
--------------------------
|
||||
|
||||
Option values may reference other values using PEP 292 string substitution:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('state_path',
|
||||
default=os.path.join(os.path.dirname(__file__), '../'),
|
||||
help='Top-level directory for maintaining nova state.'),
|
||||
cfg.StrOpt('sqlite_db',
|
||||
default='nova.sqlite',
|
||||
help='File name for SQLite.'),
|
||||
cfg.StrOpt('sql_connection',
|
||||
default='sqlite:///$state_path/$sqlite_db',
|
||||
help='Connection string for SQL database.'),
|
||||
]
|
||||
|
||||
.. note::
|
||||
|
||||
Interpolation can be avoided by using `$$`.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use `.` to delimit option from other groups, e.g.
|
||||
${mygroup.myoption}.
|
314
doc/source/reference/defining.rst
Normal file
314
doc/source/reference/defining.rst
Normal file
@ -0,0 +1,314 @@
|
||||
==================
|
||||
Defining Options
|
||||
==================
|
||||
|
||||
Configuration options may be set on the command line or in config files.
|
||||
|
||||
The schema for each option is defined using the
|
||||
:class:`Opt` class or its sub-classes, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_config import types
|
||||
|
||||
PortType = types.Integer(1, 65535)
|
||||
|
||||
common_opts = [
|
||||
cfg.StrOpt('bind_host',
|
||||
default='0.0.0.0',
|
||||
help='IP address to listen on.'),
|
||||
cfg.Opt('bind_port',
|
||||
type=PortType,
|
||||
default=9292,
|
||||
help='Port number to listen on.')
|
||||
]
|
||||
|
||||
Option Types
|
||||
------------
|
||||
|
||||
Options can have arbitrary types via the `type` parameter to the :class:`Opt`
|
||||
constructor. The `type` parameter is a callable object that takes a string and
|
||||
either returns a value of that particular type or raises :class:`ValueError` if
|
||||
the value can not be converted.
|
||||
|
||||
For convenience, there are predefined option subclasses in
|
||||
:mod:`oslo_config.cfg` that set the option `type` as in the following table:
|
||||
|
||||
====================================== ======
|
||||
Type Option
|
||||
====================================== ======
|
||||
:class:`oslo_config.types.String` :class:`oslo_config.cfg.StrOpt`
|
||||
:class:`oslo_config.types.String` :class:`oslo_config.cfg.SubCommandOpt`
|
||||
:class:`oslo_config.types.Boolean` :class:`oslo_config.cfg.BoolOpt`
|
||||
:class:`oslo_config.types.Integer` :class:`oslo_config.cfg.IntOpt`
|
||||
:class:`oslo_config.types.Float` :class:`oslo_config.cfg.FloatOpt`
|
||||
:class:`oslo_config.types.Port` :class:`oslo_config.cfg.PortOpt`
|
||||
:class:`oslo_config.types.List` :class:`oslo_config.cfg.ListOpt`
|
||||
:class:`oslo_config.types.Dict` :class:`oslo_config.cfg.DictOpt`
|
||||
:class:`oslo_config.types.IPAddress` :class:`oslo_config.cfg.IPOpt`
|
||||
:class:`oslo_config.types.Hostname` :class:`oslo_config.cfg.HostnameOpt`
|
||||
:class:`oslo_config.types.HostAddress` :class:`oslo_config.cfg.HostAddressOpt`
|
||||
:class:`oslo_config.types.URI` :class:`oslo_config.cfg.URIOpt`
|
||||
====================================== ======
|
||||
|
||||
For :class:`oslo_config.cfg.MultiOpt` the `item_type` parameter defines
|
||||
the type of the values. For convenience, :class:`oslo_config.cfg.MultiStrOpt`
|
||||
is :class:`~oslo_config.cfg.MultiOpt` with the `item_type` parameter set to
|
||||
:class:`oslo_config.types.MultiString`.
|
||||
|
||||
The following example defines options using the convenience classes:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
enabled_apis_opt = cfg.ListOpt('enabled_apis',
|
||||
default=['ec2', 'osapi_compute'],
|
||||
help='List of APIs to enable by default.')
|
||||
|
||||
DEFAULT_EXTENSIONS = [
|
||||
'nova.api.openstack.compute.contrib.standard_extensions'
|
||||
]
|
||||
osapi_compute_extension_opt = cfg.MultiStrOpt('osapi_compute_extension',
|
||||
default=DEFAULT_EXTENSIONS)
|
||||
|
||||
Registering Options
|
||||
-------------------
|
||||
|
||||
Option schemas are registered with the config manager at runtime, but before
|
||||
the option is referenced:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class ExtensionManager(object):
|
||||
|
||||
enabled_apis_opt = cfg.ListOpt(...)
|
||||
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.conf.register_opt(enabled_apis_opt)
|
||||
...
|
||||
|
||||
def _load_extensions(self):
|
||||
for ext_factory in self.conf.osapi_compute_extension:
|
||||
....
|
||||
|
||||
A common usage pattern is for each option schema to be defined in the module or
|
||||
class which uses the option:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
opts = ...
|
||||
|
||||
def add_common_opts(conf):
|
||||
conf.register_opts(opts)
|
||||
|
||||
def get_bind_host(conf):
|
||||
return conf.bind_host
|
||||
|
||||
def get_bind_port(conf):
|
||||
return conf.bind_port
|
||||
|
||||
An option may optionally be made available via the command line. Such options
|
||||
must be registered with the config manager before the command line is parsed
|
||||
(for the purposes of --help and CLI arg validation):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
cli_opts = [
|
||||
cfg.BoolOpt('verbose',
|
||||
short='v',
|
||||
default=False,
|
||||
help='Print more verbose output.'),
|
||||
cfg.BoolOpt('debug',
|
||||
short='d',
|
||||
default=False,
|
||||
help='Print debugging output.'),
|
||||
]
|
||||
|
||||
def add_common_opts(conf):
|
||||
conf.register_cli_opts(cli_opts)
|
||||
|
||||
Option Groups
|
||||
-------------
|
||||
|
||||
Options can be registered as belonging to a group:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rabbit_group = cfg.OptGroup(name='rabbit',
|
||||
title='RabbitMQ options')
|
||||
|
||||
rabbit_host_opt = cfg.StrOpt('host',
|
||||
default='localhost',
|
||||
help='IP/hostname to listen on.'),
|
||||
rabbit_port_opt = cfg.PortOpt('port',
|
||||
default=5672,
|
||||
help='Port number to listen on.')
|
||||
|
||||
def register_rabbit_opts(conf):
|
||||
conf.register_group(rabbit_group)
|
||||
# options can be registered under a group in either of these ways:
|
||||
conf.register_opt(rabbit_host_opt, group=rabbit_group)
|
||||
conf.register_opt(rabbit_port_opt, group='rabbit')
|
||||
|
||||
If no group attributes are required other than the group name, the group
|
||||
need not be explicitly registered for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def register_rabbit_opts(conf):
|
||||
# The group will automatically be created, equivalent calling:
|
||||
# conf.register_group(OptGroup(name='rabbit'))
|
||||
conf.register_opt(rabbit_port_opt, group='rabbit')
|
||||
|
||||
If no group is specified, options belong to the 'DEFAULT' section of config
|
||||
files:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
bind_port = 9292
|
||||
...
|
||||
|
||||
[rabbit]
|
||||
host = localhost
|
||||
port = 5672
|
||||
use_ssl = False
|
||||
userid = guest
|
||||
password = guest
|
||||
virtual_host = /
|
||||
|
||||
Command-line options in a group are automatically prefixed with the
|
||||
group name:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
--rabbit-host localhost --rabbit-port 9999
|
||||
|
||||
Dynamic Groups
|
||||
--------------
|
||||
|
||||
Groups can be registered dynamically by application code. This
|
||||
introduces a challenge for the sample generator, discovery mechanisms,
|
||||
and validation tools, since they do not know in advance the names of
|
||||
all of the groups. The ``dynamic_group_owner`` parameter to the
|
||||
constructor specifies the full name of an option registered in another
|
||||
group that controls repeated instances of a dynamic group. This option
|
||||
is usually a MultiStrOpt.
|
||||
|
||||
For example, Cinder supports multiple storage backend devices and
|
||||
services. To configure Cinder to communicate with multiple backends,
|
||||
the ``enabled_backends`` option is set to the list of names of
|
||||
backends. Each backend group includes the options for communicating
|
||||
with that device or service.
|
||||
|
||||
Driver Groups
|
||||
-------------
|
||||
|
||||
Groups can have dynamic sets of options, usually based on a driver
|
||||
that has unique requirements. This works at runtime because the code
|
||||
registers options before it uses them, but it introduces a challenge
|
||||
for the sample generator, discovery mechanisms, and validation tools
|
||||
because they do not know in advance the correct options for a group.
|
||||
|
||||
To address this issue, the driver option for a group can be named
|
||||
using the ``driver_option`` parameter. Each driver option should
|
||||
define its own discovery entry point namespace to return the set of
|
||||
options for that driver, named using the prefix
|
||||
``"oslo.config.opts."`` followed by the driver option name.
|
||||
|
||||
In the Cinder case described above, a ``volume_backend_name`` option
|
||||
is part of the static definition of the group, so ``driver_option``
|
||||
should be set to ``"volume_backend_name"``. And plugins should be
|
||||
registered under ``"oslo.config.opts.volume_backend_name"`` using the
|
||||
same names as the main plugin registered with
|
||||
``"oslo.config.opts"``. The drivers residing within the Cinder code
|
||||
base have an entry point named ``"cinder"`` registered.
|
||||
|
||||
Special Handling Instructions
|
||||
-----------------------------
|
||||
|
||||
Options may be declared as required so that an error is raised if the user
|
||||
does not supply a value for the option:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('service_name', required=True),
|
||||
cfg.StrOpt('image_id', required=True),
|
||||
...
|
||||
]
|
||||
|
||||
Options may be declared as secret so that their values are not leaked into
|
||||
log files:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('s3_store_access_key', secret=True),
|
||||
cfg.StrOpt('s3_store_secret_key', secret=True),
|
||||
...
|
||||
]
|
||||
|
||||
Dictionary Options
|
||||
------------------
|
||||
|
||||
If you need end users to specify a dictionary of key/value pairs, then you can
|
||||
use the DictOpt:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
opts = [
|
||||
cfg.DictOpt('foo',
|
||||
default={})
|
||||
]
|
||||
|
||||
The end users can then specify the option foo in their configuration file
|
||||
as shown below:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[DEFAULT]
|
||||
foo = k1:v1,k2:v2
|
||||
|
||||
Advanced Option
|
||||
---------------
|
||||
|
||||
Use if you need to label an option as advanced in sample files, indicating the
|
||||
option is not normally used by the majority of users and might have a
|
||||
significant effect on stability and/or performance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('option1', default='default_value',
|
||||
advanced=True, help='This is help '
|
||||
'text.'),
|
||||
cfg.PortOpt('option2', default='default_value',
|
||||
help='This is help text.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
This will result in the option being pushed to the bottom of the
|
||||
namespace and labeled as advanced in the sample files, with a notation
|
||||
about possible effects:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[DEFAULT]
|
||||
...
|
||||
# This is help text. (string value)
|
||||
# option2 = default_value
|
||||
...
|
||||
<pushed to bottom of section>
|
||||
...
|
||||
# This is help text. (string value)
|
||||
# Advanced Option: intended for advanced users and not used
|
||||
# by the majority of users, and might have a significant
|
||||
# effect on stability and/or performance.
|
||||
# option1 = default_value
|
47
doc/source/reference/deprecating.rst
Normal file
47
doc/source/reference/deprecating.rst
Normal file
@ -0,0 +1,47 @@
|
||||
====================
|
||||
Option Deprecation
|
||||
====================
|
||||
|
||||
If you want to rename some options, move them to another group or remove
|
||||
completely, you may change their declarations using `deprecated_name`,
|
||||
`deprecated_group` and `deprecated_for_removal` parameters to the :class:`Opt`
|
||||
constructor:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
conf = cfg.ConfigOpts()
|
||||
|
||||
opt_1 = cfg.StrOpt('opt_1', default='foo', deprecated_name='opt1')
|
||||
opt_2 = cfg.StrOpt('opt_2', default='spam', deprecated_group='DEFAULT')
|
||||
opt_3 = cfg.BoolOpt('opt_3', default=False, deprecated_for_removal=True)
|
||||
|
||||
conf.register_opt(opt_1, group='group_1')
|
||||
conf.register_opt(opt_2, group='group_2')
|
||||
conf.register_opt(opt_3)
|
||||
|
||||
conf(['--config-file', 'config.conf'])
|
||||
|
||||
assert conf.group_1.opt_1 == 'bar'
|
||||
assert conf.group_2.opt_2 == 'eggs'
|
||||
assert conf.opt_3
|
||||
|
||||
Assuming that the file config.conf has the following content:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[group_1]
|
||||
opt1 = bar
|
||||
|
||||
[DEFAULT]
|
||||
opt_2 = eggs
|
||||
opt_3 = True
|
||||
|
||||
the script will succeed, but will log three respective warnings about the
|
||||
given deprecated options.
|
||||
|
||||
There are also `deprecated_reason` and `deprecated_since` parameters for
|
||||
specifying some additional information about a deprecation.
|
||||
|
||||
All the mentioned parameters can be mixed together in any combinations.
|
21
doc/source/reference/globals.rst
Normal file
21
doc/source/reference/globals.rst
Normal file
@ -0,0 +1,21 @@
|
||||
===================
|
||||
Global ConfigOpts
|
||||
===================
|
||||
|
||||
This module also contains a global instance of the ConfigOpts class
|
||||
in order to support a common usage pattern in OpenStack:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('bind_host', default='0.0.0.0'),
|
||||
cfg.PortOpt('bind_port', default=9292),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
def start(server, app):
|
||||
server.start(app, CONF.bind_port, CONF.bind_host)
|
@ -1,11 +1,17 @@
|
||||
===================
|
||||
Using oslo.config
|
||||
===================
|
||||
=============================
|
||||
oslo.config Reference Guide
|
||||
=============================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
cfg
|
||||
defining
|
||||
naming
|
||||
accessing
|
||||
configuration-files
|
||||
command-line
|
||||
deprecating
|
||||
globals
|
||||
opts
|
||||
types
|
||||
configopts
|
||||
@ -14,7 +20,6 @@
|
||||
fixture
|
||||
parser
|
||||
exceptions
|
||||
namespaces
|
||||
styleguide
|
||||
mutable
|
||||
locations
|
||||
|
@ -1,8 +1,8 @@
|
||||
.. _option-definitions:
|
||||
|
||||
------------------
|
||||
Option Definitions
|
||||
------------------
|
||||
====================
|
||||
Opt and Subclasses
|
||||
====================
|
||||
|
||||
.. currentmodule:: oslo_config.cfg
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---------------------------
|
||||
Option Types and Validation
|
||||
---------------------------
|
||||
=============================
|
||||
Option Types and Validation
|
||||
=============================
|
||||
|
||||
.. automodule:: oslo_config.types
|
||||
:members:
|
||||
|
@ -12,475 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
r"""
|
||||
Configuration options may be set on the command line or in config files.
|
||||
|
||||
The schema for each option is defined using the
|
||||
:class:`Opt` class or its sub-classes, for example:
|
||||
|
||||
::
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_config import types
|
||||
|
||||
PortType = types.Integer(1, 65535)
|
||||
|
||||
common_opts = [
|
||||
cfg.StrOpt('bind_host',
|
||||
default='0.0.0.0',
|
||||
help='IP address to listen on.'),
|
||||
cfg.Opt('bind_port',
|
||||
type=PortType,
|
||||
default=9292,
|
||||
help='Port number to listen on.')
|
||||
]
|
||||
|
||||
Option Types
|
||||
------------
|
||||
|
||||
Options can have arbitrary types via the `type` parameter to the :class:`Opt`
|
||||
constructor. The `type` parameter is a callable object that takes a string and
|
||||
either returns a value of that particular type or raises :class:`ValueError` if
|
||||
the value can not be converted.
|
||||
|
||||
For convenience, there are predefined option subclasses in
|
||||
:mod:`oslo_config.cfg` that set the option `type` as in the following table:
|
||||
|
||||
====================================== ======
|
||||
Type Option
|
||||
====================================== ======
|
||||
:class:`oslo_config.types.String` :class:`oslo_config.cfg.StrOpt`
|
||||
:class:`oslo_config.types.String` :class:`oslo_config.cfg.SubCommandOpt`
|
||||
:class:`oslo_config.types.Boolean` :class:`oslo_config.cfg.BoolOpt`
|
||||
:class:`oslo_config.types.Integer` :class:`oslo_config.cfg.IntOpt`
|
||||
:class:`oslo_config.types.Float` :class:`oslo_config.cfg.FloatOpt`
|
||||
:class:`oslo_config.types.Port` :class:`oslo_config.cfg.PortOpt`
|
||||
:class:`oslo_config.types.List` :class:`oslo_config.cfg.ListOpt`
|
||||
:class:`oslo_config.types.Dict` :class:`oslo_config.cfg.DictOpt`
|
||||
:class:`oslo_config.types.IPAddress` :class:`oslo_config.cfg.IPOpt`
|
||||
:class:`oslo_config.types.Hostname` :class:`oslo_config.cfg.HostnameOpt`
|
||||
:class:`oslo_config.types.HostAddress` :class:`oslo_config.cfg.HostAddressOpt`
|
||||
:class:`oslo_config.types.URI` :class:`oslo_config.cfg.URIOpt`
|
||||
====================================== ======
|
||||
|
||||
For :class:`oslo_config.cfg.MultiOpt` the `item_type` parameter defines
|
||||
the type of the values. For convenience, :class:`oslo_config.cfg.MultiStrOpt`
|
||||
is :class:`~oslo_config.cfg.MultiOpt` with the `item_type` parameter set to
|
||||
:class:`oslo_config.types.MultiString`.
|
||||
|
||||
The following example defines options using the convenience classes::
|
||||
|
||||
enabled_apis_opt = cfg.ListOpt('enabled_apis',
|
||||
default=['ec2', 'osapi_compute'],
|
||||
help='List of APIs to enable by default.')
|
||||
|
||||
DEFAULT_EXTENSIONS = [
|
||||
'nova.api.openstack.compute.contrib.standard_extensions'
|
||||
]
|
||||
osapi_compute_extension_opt = cfg.MultiStrOpt('osapi_compute_extension',
|
||||
default=DEFAULT_EXTENSIONS)
|
||||
|
||||
Registering Options
|
||||
-------------------
|
||||
|
||||
Option schemas are registered with the config manager at runtime, but before
|
||||
the option is referenced::
|
||||
|
||||
class ExtensionManager(object):
|
||||
|
||||
enabled_apis_opt = cfg.ListOpt(...)
|
||||
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.conf.register_opt(enabled_apis_opt)
|
||||
...
|
||||
|
||||
def _load_extensions(self):
|
||||
for ext_factory in self.conf.osapi_compute_extension:
|
||||
....
|
||||
|
||||
A common usage pattern is for each option schema to be defined in the module or
|
||||
class which uses the option::
|
||||
|
||||
opts = ...
|
||||
|
||||
def add_common_opts(conf):
|
||||
conf.register_opts(opts)
|
||||
|
||||
def get_bind_host(conf):
|
||||
return conf.bind_host
|
||||
|
||||
def get_bind_port(conf):
|
||||
return conf.bind_port
|
||||
|
||||
An option may optionally be made available via the command line. Such options
|
||||
must be registered with the config manager before the command line is parsed
|
||||
(for the purposes of --help and CLI arg validation)::
|
||||
|
||||
cli_opts = [
|
||||
cfg.BoolOpt('verbose',
|
||||
short='v',
|
||||
default=False,
|
||||
help='Print more verbose output.'),
|
||||
cfg.BoolOpt('debug',
|
||||
short='d',
|
||||
default=False,
|
||||
help='Print debugging output.'),
|
||||
]
|
||||
|
||||
def add_common_opts(conf):
|
||||
conf.register_cli_opts(cli_opts)
|
||||
|
||||
Loading Config Files
|
||||
--------------------
|
||||
|
||||
The config manager has two CLI options defined by default, --config-file
|
||||
and --config-dir::
|
||||
|
||||
class ConfigOpts(object):
|
||||
|
||||
def __call__(self, ...):
|
||||
|
||||
opts = [
|
||||
MultiStrOpt('config-file',
|
||||
...),
|
||||
StrOpt('config-dir',
|
||||
...),
|
||||
]
|
||||
|
||||
self.register_cli_opts(opts)
|
||||
|
||||
Option values are parsed from any supplied config files using
|
||||
oslo_config.iniparser. If none are specified, a default set is used
|
||||
for example glance-api.conf and glance-common.conf::
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
bind_port = 9292
|
||||
|
||||
glance-common.conf:
|
||||
[DEFAULT]
|
||||
bind_host = 0.0.0.0
|
||||
|
||||
Lines in a configuration file should not start with whitespace. A
|
||||
configuration file also supports comments, which must start with '#' or ';'.
|
||||
Option values in config files and those on the command line are parsed
|
||||
in order. The same option (includes deprecated option name and current
|
||||
option name) can appear many times, in config files or on the command line.
|
||||
Later values always override earlier ones.
|
||||
|
||||
The order of configuration files inside the same configuration directory is
|
||||
defined by the alphabetic sorting order of their file names.
|
||||
|
||||
The parsing of CLI args and config files is initiated by invoking the config
|
||||
manager for example::
|
||||
|
||||
conf = cfg.ConfigOpts()
|
||||
conf.register_opt(cfg.BoolOpt('verbose', ...))
|
||||
conf(sys.argv[1:])
|
||||
if conf.verbose:
|
||||
...
|
||||
|
||||
Option Groups
|
||||
-------------
|
||||
|
||||
Options can be registered as belonging to a group::
|
||||
|
||||
rabbit_group = cfg.OptGroup(name='rabbit',
|
||||
title='RabbitMQ options')
|
||||
|
||||
rabbit_host_opt = cfg.StrOpt('host',
|
||||
default='localhost',
|
||||
help='IP/hostname to listen on.'),
|
||||
rabbit_port_opt = cfg.PortOpt('port',
|
||||
default=5672,
|
||||
help='Port number to listen on.')
|
||||
|
||||
def register_rabbit_opts(conf):
|
||||
conf.register_group(rabbit_group)
|
||||
# options can be registered under a group in either of these ways:
|
||||
conf.register_opt(rabbit_host_opt, group=rabbit_group)
|
||||
conf.register_opt(rabbit_port_opt, group='rabbit')
|
||||
|
||||
If no group attributes are required other than the group name, the group
|
||||
need not be explicitly registered for example::
|
||||
|
||||
def register_rabbit_opts(conf):
|
||||
# The group will automatically be created, equivalent calling::
|
||||
# conf.register_group(OptGroup(name='rabbit'))
|
||||
conf.register_opt(rabbit_port_opt, group='rabbit')
|
||||
|
||||
If no group is specified, options belong to the 'DEFAULT' section of config
|
||||
files::
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
bind_port = 9292
|
||||
...
|
||||
|
||||
[rabbit]
|
||||
host = localhost
|
||||
port = 5672
|
||||
use_ssl = False
|
||||
userid = guest
|
||||
password = guest
|
||||
virtual_host = /
|
||||
|
||||
Command-line options in a group are automatically prefixed with the
|
||||
group name::
|
||||
|
||||
--rabbit-host localhost --rabbit-port 9999
|
||||
|
||||
Dynamic Groups
|
||||
--------------
|
||||
|
||||
Groups can be registered dynamically by application code. This
|
||||
introduces a challenge for the sample generator, discovery mechanisms,
|
||||
and validation tools, since they do not know in advance the names of
|
||||
all of the groups. The ``dynamic_group_owner`` parameter to the
|
||||
constructor specifies the full name of an option registered in another
|
||||
group that controls repeated instances of a dynamic group. This option
|
||||
is usually a MultiStrOpt.
|
||||
|
||||
For example, Cinder supports multiple storage backend devices and
|
||||
services. To configure Cinder to communicate with multiple backends,
|
||||
the ``enabled_backends`` option is set to the list of names of
|
||||
backends. Each backend group includes the options for communicating
|
||||
with that device or service.
|
||||
|
||||
Driver Groups
|
||||
-------------
|
||||
|
||||
Groups can have dynamic sets of options, usually based on a driver
|
||||
that has unique requirements. This works at runtime because the code
|
||||
registers options before it uses them, but it introduces a challenge
|
||||
for the sample generator, discovery mechanisms, and validation tools
|
||||
because they do not know in advance the correct options for a group.
|
||||
|
||||
To address this issue, the driver option for a group can be named
|
||||
using the ``driver_option`` parameter. Each driver option should
|
||||
define its own discovery entry point namespace to return the set of
|
||||
options for that driver, named using the prefix
|
||||
``"oslo.config.opts."`` followed by the driver option name.
|
||||
|
||||
In the Cinder case described above, a ``volume_backend_name`` option
|
||||
is part of the static definition of the group, so ``driver_option``
|
||||
should be set to ``"volume_backend_name"``. And plugins should be
|
||||
registered under ``"oslo.config.opts.volume_backend_name"`` using the
|
||||
same names as the main plugin registered with
|
||||
``"oslo.config.opts"``. The drivers residing within the Cinder code
|
||||
base have an entry point named ``"cinder"`` registered.
|
||||
|
||||
Accessing Option Values In Your Code
|
||||
------------------------------------
|
||||
|
||||
Option values in the default group are referenced as attributes/properties on
|
||||
the config manager; groups are also attributes on the config manager, with
|
||||
attributes for each of the options associated with the group::
|
||||
|
||||
server.start(app, conf.bind_port, conf.bind_host, conf)
|
||||
|
||||
self.connection = kombu.connection.BrokerConnection(
|
||||
hostname=conf.rabbit.host,
|
||||
port=conf.rabbit.port,
|
||||
...)
|
||||
|
||||
Option Value Interpolation
|
||||
--------------------------
|
||||
|
||||
Option values may reference other values using PEP 292 string substitution::
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('state_path',
|
||||
default=os.path.join(os.path.dirname(__file__), '../'),
|
||||
help='Top-level directory for maintaining nova state.'),
|
||||
cfg.StrOpt('sqlite_db',
|
||||
default='nova.sqlite',
|
||||
help='File name for SQLite.'),
|
||||
cfg.StrOpt('sql_connection',
|
||||
default='sqlite:///$state_path/$sqlite_db',
|
||||
help='Connection string for SQL database.'),
|
||||
]
|
||||
|
||||
.. note::
|
||||
|
||||
Interpolation can be avoided by using `$$`.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use `.` to delimit option from other groups, e.g.
|
||||
${mygroup.myoption}.
|
||||
|
||||
Special Handling Instructions
|
||||
-----------------------------
|
||||
|
||||
Options may be declared as required so that an error is raised if the user
|
||||
does not supply a value for the option::
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('service_name', required=True),
|
||||
cfg.StrOpt('image_id', required=True),
|
||||
...
|
||||
]
|
||||
|
||||
Options may be declared as secret so that their values are not leaked into
|
||||
log files::
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('s3_store_access_key', secret=True),
|
||||
cfg.StrOpt('s3_store_secret_key', secret=True),
|
||||
...
|
||||
]
|
||||
|
||||
Dictionary Options
|
||||
------------------
|
||||
|
||||
If you need end users to specify a dictionary of key/value pairs, then you can
|
||||
use the DictOpt::
|
||||
|
||||
opts = [
|
||||
cfg.DictOpt('foo',
|
||||
default={})
|
||||
]
|
||||
|
||||
The end users can then specify the option foo in their configuration file
|
||||
as shown below:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[DEFAULT]
|
||||
foo = k1:v1,k2:v2
|
||||
|
||||
|
||||
Global ConfigOpts
|
||||
-----------------
|
||||
|
||||
This module also contains a global instance of the ConfigOpts class
|
||||
in order to support a common usage pattern in OpenStack::
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('bind_host', default='0.0.0.0'),
|
||||
cfg.PortOpt('bind_port', default=9292),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
def start(server, app):
|
||||
server.start(app, CONF.bind_port, CONF.bind_host)
|
||||
|
||||
Positional Command Line Arguments
|
||||
---------------------------------
|
||||
|
||||
Positional command line arguments are supported via a 'positional' Opt
|
||||
constructor argument::
|
||||
|
||||
>>> conf = cfg.ConfigOpts()
|
||||
>>> conf.register_cli_opt(cfg.MultiStrOpt('bar', positional=True))
|
||||
True
|
||||
>>> conf(['a', 'b'])
|
||||
>>> conf.bar
|
||||
['a', 'b']
|
||||
|
||||
Sub-Parsers
|
||||
-----------
|
||||
|
||||
It is also possible to use argparse "sub-parsers" to parse additional
|
||||
command line arguments using the SubCommandOpt class:
|
||||
|
||||
>>> def add_parsers(subparsers):
|
||||
... list_action = subparsers.add_parser('list')
|
||||
... list_action.add_argument('id')
|
||||
...
|
||||
>>> conf = cfg.ConfigOpts()
|
||||
>>> conf.register_cli_opt(cfg.SubCommandOpt('action', handler=add_parsers))
|
||||
True
|
||||
>>> conf(args=['list', '10'])
|
||||
>>> conf.action.name, conf.action.id
|
||||
('list', '10')
|
||||
|
||||
Advanced Option
|
||||
---------------
|
||||
|
||||
Use if you need to label an option as advanced in sample files, indicating the
|
||||
option is not normally used by the majority of users and might have a
|
||||
significant effect on stability and/or performance::
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('option1', default='default_value',
|
||||
advanced=True, help='This is help '
|
||||
'text.'),
|
||||
cfg.PortOpt('option2', default='default_value',
|
||||
help='This is help text.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
This will result in the option being pushed to the bottom of the
|
||||
namespace and labeled as advanced in the sample files, with a notation
|
||||
about possible effects::
|
||||
|
||||
[DEFAULT]
|
||||
...
|
||||
# This is help text. (string value)
|
||||
# option2 = default_value
|
||||
...
|
||||
<pushed to bottom of section>
|
||||
...
|
||||
# This is help text. (string value)
|
||||
# Advanced Option: intended for advanced users and not used
|
||||
# by the majority of users, and might have a significant
|
||||
# effect on stability and/or performance.
|
||||
# option1 = default_value
|
||||
|
||||
Option Deprecation
|
||||
------------------
|
||||
|
||||
If you want to rename some options, move them to another group or remove
|
||||
completely, you may change their declarations using `deprecated_name`,
|
||||
`deprecated_group` and `deprecated_for_removal` parameters to the :class:`Opt`
|
||||
constructor::
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
conf = cfg.ConfigOpts()
|
||||
|
||||
opt_1 = cfg.StrOpt('opt_1', default='foo', deprecated_name='opt1')
|
||||
opt_2 = cfg.StrOpt('opt_2', default='spam', deprecated_group='DEFAULT')
|
||||
opt_3 = cfg.BoolOpt('opt_3', default=False, deprecated_for_removal=True)
|
||||
|
||||
conf.register_opt(opt_1, group='group_1')
|
||||
conf.register_opt(opt_2, group='group_2')
|
||||
conf.register_opt(opt_3)
|
||||
|
||||
conf(['--config-file', 'config.conf'])
|
||||
|
||||
assert conf.group_1.opt_1 == 'bar'
|
||||
assert conf.group_2.opt_2 == 'eggs'
|
||||
assert conf.opt_3
|
||||
|
||||
Assuming that the file config.conf has the following content::
|
||||
|
||||
[group_1]
|
||||
opt1 = bar
|
||||
|
||||
[DEFAULT]
|
||||
opt_2 = eggs
|
||||
opt_3 = True
|
||||
|
||||
the script will succeed, but will log three respective warnings about the
|
||||
given deprecated options.
|
||||
|
||||
There are also `deprecated_reason` and `deprecated_since` parameters for
|
||||
specifying some additional information about a deprecation.
|
||||
|
||||
All the mentioned parameters can be mixed together in any combinations.
|
||||
|
||||
"""Primary module in oslo_config.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@ -1983,7 +1515,7 @@ class ParseError(iniparser.ParseError):
|
||||
|
||||
|
||||
class ConfigParser(iniparser.BaseParser):
|
||||
"""Parses a single config file, populating 'sections' to look like:
|
||||
"""Parses a single config file, populating 'sections' to look like::
|
||||
|
||||
{'DEFAULT': {'key': [value, ...], ...},
|
||||
...}
|
||||
|
Loading…
Reference in New Issue
Block a user