diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-07-08 23:46:12 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-07-08 23:46:12 +0000 |
commit | 4318a1d6b0f278f3243cc29eb5dbd26200794514 (patch) | |
tree | 76995e86c0b764139d9c99a7feb4b2592a96c9cc | |
parent | 2576dd3eb139fe500567c8022429744903726a21 (diff) | |
parent | b89f5810d757ca2acb2f35e99b7432ff9ce49c1c (diff) | |
download | oslo-config-4318a1d6b0f278f3243cc29eb5dbd26200794514.tar.gz |
Merge "Add FAQ entry for why we do not treat config options as API"
-rw-r--r-- | doc/source/faq.rst | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/doc/source/faq.rst b/doc/source/faq.rst index 3325e40..2171d13 100644 --- a/doc/source/faq.rst +++ b/doc/source/faq.rst @@ -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. |