Add FAQ entry for why we do not treat config options as API
Change-Id: I546adac6c1516a765c37101bcea3d713d528ee65
This commit is contained in:
parent
56073f066d
commit
b89f5810d7
@ -28,3 +28,71 @@ projects.
|
||||
This debate will probably never completely go away, though. See `this
|
||||
latest discussion in August, 2014
|
||||
<http://lists.openstack.org/pipermail/openstack-dev/2014-August/044050.html>`__
|
||||
|
||||
Why are configuration options not part of a library's API?
|
||||
==========================================================
|
||||
|
||||
Configuration options are a way for deployers to change the behavior
|
||||
of OpenStack. Applications are not supposed to be aware of the
|
||||
configuration options defined and used within libraries, because the
|
||||
library API is supposed to work transparently no matter which backend
|
||||
is configured.
|
||||
|
||||
Configuration options in libraries can be renamed, moved, and
|
||||
deprecated just like configuration options in applications. However,
|
||||
if applications are allowed to read or write the configuration options
|
||||
directly, treating them as an API, the option cannot be renamed
|
||||
without breaking the application. Instead, libraries should provide a
|
||||
programmatic API (usually a :func:`set_defaults` function) for setting
|
||||
the defaults for configuration options. For example, this function
|
||||
from ``oslo.log`` lets the caller change the format string and default
|
||||
logging levels:
|
||||
|
||||
::
|
||||
|
||||
def set_defaults(logging_context_format_string=None,
|
||||
default_log_levels=None):
|
||||
"""Set default values for the configuration options used by oslo.log."""
|
||||
# Just in case the caller is not setting the
|
||||
# default_log_level. This is insurance because
|
||||
# we introduced the default_log_level parameter
|
||||
# later in a backwards in-compatible change
|
||||
if default_log_levels is not None:
|
||||
cfg.set_defaults(
|
||||
_options.log_opts,
|
||||
default_log_levels=default_log_levels)
|
||||
if logging_context_format_string is not None:
|
||||
cfg.set_defaults(
|
||||
_options.log_opts,
|
||||
logging_context_format_string=logging_context_format_string)
|
||||
|
||||
If the name of either option changes, the API of :func:`set_defaults`
|
||||
can be updated to allow both names, and warn if the old one is
|
||||
provided. Using a supported API like this is better than having an
|
||||
application call :func:`set_default` on the configuration object
|
||||
directly, such as:
|
||||
|
||||
::
|
||||
|
||||
cfg.CONF.set_default('default_log_levels', default_log_levels)
|
||||
|
||||
This form will trigger an error if the logging options are moved out
|
||||
of the default option group into their own section of the
|
||||
configuration file. It will also fail if the ``default_log_levels``
|
||||
option is not yet registered, or if it is renamed. All of those cases
|
||||
can be protected against with a :func:`set_defaults` function in the
|
||||
library that owns the options.
|
||||
|
||||
Similarly, code that does not *own* the configuration option
|
||||
definition should not read the option value. An application should
|
||||
never, for example, do something like:
|
||||
|
||||
::
|
||||
|
||||
log_file = cfg.CONF.log_file
|
||||
|
||||
The type, name, and existence of the ``log_file`` configuration option
|
||||
is subject to change. ``oslo.config`` makes it easy to communicate
|
||||
that change to a deployer in a way that allows their old configuration
|
||||
files to continue to work. It has no mechanism for doing that in
|
||||
application code, however.
|
||||
|
Loading…
x
Reference in New Issue
Block a user