refactoring the doc for the 0.55 new API

This commit is contained in:
gwen 2013-05-15 17:35:49 +02:00
parent 89dca8d707
commit 988bd659b8
9 changed files with 184 additions and 236 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -4,37 +4,13 @@
Configuration handling basics Configuration handling basics
=============================== ===============================
Main Assumption
===============
Configuration option objects `config.Config()` are produced at the
entry points and handed down to where they are actually used. This keeps
configuration local but available everywhere and consistent.
`Config` and `Option` objects `Config` and `Option` objects
========================================= =========================================
Configuration option objects can be created in different ways. Let's perform
very basic :class:`tiramisu.config.Config` object manipulations:
::
>>> from tiramisu.config import Config
>>> from tiramisu.option import OptionDescription, BoolOption
>>> descr = OptionDescription("optgroup", "", [
... BoolOption("bool", "", default=False)])
>>>
>>> config = Config(descr)
>>> config.bool
False
>>> config.bool = True
>>> config.bool
True
Take a look at `test_config.test_base_config()` or Take a look at `test_config.test_base_config()` or
`test_config.test_base_config_and_groups()`. `test_config.test_base_config_and_groups()`.
Accessing the configuration `Option`'s Accessing the configuration `Option`'s
----------------------------------------- -----------------------------------------
@ -134,23 +110,3 @@ the value owner is the default `glossary#valueowner`
:: ::
cfg.set(name=value) cfg.set(name=value)
The global `setoption()` method of the config objects can set a value with a specific owner
::
cfg.setoption('name', value, 'owner')
Finally, the local `setoption()` method directly in the `Option` object can be
used. While the `Option` object refers to his parent, the config knows that the
value has been changed and no bad side effect won't occur
::
>>> booloption = BoolOption('bool', 'Test boolean option', default=True)
>>> descr = OptionDescription('descr', '', [booloption])
>>> cfg = Config(descr)
>>> booloption.setoption(cfg, False, 'owner')
>>> cfg.bool
>>> False

View File

@ -1,5 +1,5 @@
================================== ==================================
`Tiramisu` - getting started Tiramisu - getting started
================================== ==================================
What is Configuration handling ? What is Configuration handling ?
@ -9,22 +9,19 @@ Due to more and more available configuration options required to set up
an operating system, it became quite annoying to hand the necessary an operating system, it became quite annoying to hand the necessary
options to where they are actually used and even more annoying to add options to where they are actually used and even more annoying to add
new options. To circumvent these problems the configuration management new options. To circumvent these problems the configuration management
was introduced. was introduced...
What is Tiramisu ? What is Tiramisu ?
=================== ===================
Tiramisu is yet another configuration handler, wich aims at producing Tiramisu is yet another configuration handler, wich aims at producing flexible
flexible and fast configuration options access. The main advantages are and fast configuration options access. The main advantages are its access rules
its access rules and the fact that the configuration 's and the fact that the configuration's consistency is preserved at any time, see
consistency is preserved at any time, see :doc:`consistency`. :doc:`consistency`. There is of course type and structure validations, but also
validations towards the whole configuration.
There are type and structures's validations for configuration options,
and validations towards the whole configuration.
Last but not least, configuration options can be reached and changed Last but not least, configuration options can be reached and changed
according to the access rules from nearly everywhere in the OS boxes, according to the access rules from nearly everywhere in your appliance.
e.g. the containers via the `http/json` server.
Just the facts Just the facts
============== ==============
@ -34,33 +31,45 @@ Just the facts
Download Download
--------- ---------
To obtain a copy of the sources, check it out from the repository using To obtain a copy of the sources, check it out from the repository using `git`.
`git`. We suggest using `git` if one wants to access the current development. We suggest using `git` if one wants to access the current developments.
:: ::
git clone git://git.labs.libre-entreprise.org/tiramisu.git git clone git://git.labs.libre-entreprise.org/tiramisu.git
This will get you a fresh checkout of the code repository in a local This will get you a fresh checkout of the code repository in a local directory
directory named ``tiramisu``. named ``tiramisu``.
Understanding Tiramisu's architecture Getting started
-------------------------------------- -------------------
The `schema` is loaded from an XML file, and the values of Configuration option objects can be created in different ways. Let's perform
the configuration options are recovered from a `.ini` like file. very basic :class:`tiramisu.config.Config` object manipulations:
By now, all the in-depth informations about the configuration are stored ::
in a **single** object, the `config.Config()` object, wich is
responsible of nearly everything. All the necessary options are stored
into a configuration object, which is available nearly everywhere, so
that adding new options becomes trivial.
This `Config()` is available from everywhere with the help of an http server >>> from tiramisu.config import Config
that serves configuration datas as `json` strings. >>> from tiramisu.option import OptionDescription, BoolOption
>>> descr = OptionDescription("optgroup", "", [
... BoolOption("bool", "", default=False)])
>>>
>>> config = Config(descr)
>>> # now we have a config, wich contains an option:
>>> config.bool
False
>>> config.bool = True
>>> config.bool
True
.. figure:: architecture.png
The basics of Tiramisu's architecture. So by now, we have
Once loaded, http server serves the `config.Config()` object, that is,
the configuration options and the configuration groups. - a namespace (which is `config` here)
- the access of an option's value by the
attribute access way (here `bool`, wich is a boolean option:
:class:`tiramisu.option.BoolOption()`.
Configuration option objects :class:`tiramisu.config.Config()` are produced at
the entry points and handed down to where they are actually used. This keeps
configuration local but available everywhere and consistent.

View File

@ -15,7 +15,7 @@ glossary
schema schema
option description option description
see `option.OptionDescription`, see `optionapi#schema` see `option.OptionDescription`, see `option#schema`
The schema of a configuration : The schema of a configuration :

View File

@ -33,7 +33,7 @@ configuration handler.
getting-started getting-started
config config
configapi configapi
optionapi option
status status
consistency consistency
glossary glossary

115
doc/option.txt Normal file
View File

@ -0,0 +1,115 @@
.. default-role:: literal
The `tiramisu.option.Option` options
======================================
Description of Options
----------------------
All the constructors take a ``name`` and a ``doc`` argument as first
arguments to give the option or option group a name and to document it.
Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value
is assumed to be ``None``.
.. _optdescr:
The `OptionDescription` class
-------------------------------
.. module:: tiramisu.option
.. autoclass: OptionDescription
.. automethod:: __init__
.. rubric:: Methods
.. autosummary::
~Config.__init__
~Config.set_group_type
.. automethod:: set_group_type
`Options description` objects lives in the :class:`tiramisu.config.Config` attribute.
If you need to access an option object, you can do it with the OptionDescription
object. Not only the value of the option by attribute access, but the option
object itself that lives behind the scene. It can always be accessed internally
with the `_cfgimpl_descr` attribute of the `config` objects. For example, with a
option named `name` in a `gc` group the `name` object can be accessed like
this::
conf._cfgimpl_descr.name
of sub configs with ::
conf.gc._cfgimpl_descr.name
This is a binding. The option objects are in the `_children` config's attribute.
Why accessing an option object ? It is possible for example freeze the
configuration option
::
conf.gc._cfgimpl_descr.dummy.freeze()
or to hide it, or disable it, or... anything.
The `Option` base class
-------------------------
It's the abstract base class for almost all options (except the symblink).
.. _optioninit:
.. autoclass:: Option
:special-members:
:members:
All option types
------------------
.. autoclass:: BoolOption
:private-members:
.. autoclass:: IntOption
:private-members:
.. autoclass:: FloatOption
:private-members:
.. autoclass:: StrOption
:private-members:
.. autoclass:: SymLinkOption
.. automethod:: __init__
``SymLinkOption`` redirects to another configuration option in the
configuration, that is :
- retrieves the value of the target,
- can set the value of the target too
.. autoclass:: IPOption
.. autoclass:: NetmaskOption
.. autoclass:: NetworkOption
.. autoclass:: DomainnameOption
.. autoclass:: ChoiceOption
.. automethod:: __init__

View File

@ -1,141 +0,0 @@
.. default-role:: literal
The `tiramisu.option.Option` options
======================================
Description of Options
----------------------
All the constructors take a ``name`` and a ``doc`` argument as first
arguments to give the option or option group a name and to document it.
Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value
is assumed to be ``None``.
.. _optdescr:
The `OptionDescription` class
-------------------------------
This class is used to group suboptions.
.. module:: tiramisu.option
.. autoclass: OptionDescription
.. automethod:: __init__
.. rubric:: Methods
.. autosummary::
~Config.__init__
~Config.set_group_type
.. automethod:: set_group_type
..
``__init__(self, name, doc, children)``
``children`` is a list of option descriptions (including
``OptionDescription`` instances for nested namespaces).
``set_group_type(self, group_name)``
Three available group_types : `default`, `family`, `group` and
`master` (for master~slave group type). Notice that for a
master~slave group, the name of the group and the name of the
master option are identical.
`Options description` objects lives in the `_cfgimpl_descr` config attribute.
If you need to access an option object, you can do it with the OptionDescription
object. Not only the value of the option by attribute access, but the option
object itself that lives behind the scene. It can always be accessed internally
with the `_cfgimpl_descr` attribute of the `config` objects. For example, with a
option named `name` in a `gc` group the `name` object can be accessed like
this::
conf._cfgimpl_descr.name
of sub configs with ::
conf.gc._cfgimpl_descr.name
This is a binding. The option objects are in the `_children` config's attribute.
Why accessing an option object ? It is possible for example freeze the
configuration option
::
conf.gc._cfgimpl_descr.dummy.freeze()
or to hide it, or disable it, or... anything.
The `Option` class
---------------------
It's an abstract base class for option wich are typed (int, string...)
.. _optioninit:
.. autoclass:: Option
:special-members:
:members:
generic option ``__init__`` method:
``__init__(name, doc, default=None, requires=None, multi=False, mandatory=False)``
``BoolOption``
++++++++++++++
Represents a choice between ``True`` and ``False``.
``IntOption``
+++++++++++++
Represents a choice of an integer.
``FloatOption``
+++++++++++++++
Represents a choice of a floating point number.
``StrOption``
+++++++++++++
Represents the choice of a string.
``SymLinkOption``
++++++++++++++++++
Redirects to another configuration option in the configuration, that is :
- retrieves the value of the tagert,
- can set the value of the target too.
``__init__(self, name, path)``
`path` is the path to the target, the option
``IPOption``
+++++++++++++
Represents the choice of an ip.
``NetmaskOption``
+++++++++++++++++++
Represents the choice of a netmask.
``ChoiceOption``
++++++++++++++++
Represents a choice out of several objects. The option can also have the value
``None``.
``__init__(self, name, doc, values, default=None, requires=None)``
``values`` is a list of values the option can possibly take.

View File

@ -20,42 +20,35 @@
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
#ValueError if function's parameter not correct # Exceptions for an Option
# or if not logical
# or if validation failled
# or multi must be a list
# or error in autolib
#TypeError if parameter has no good type
#AttributeError if no option or optiondescription in optiondescription (also when specified a path)
#____________option___________
class PropertiesOptionError(AttributeError): class PropertiesOptionError(AttributeError):
"try to access to opt with not allowed property" "attempt to access to an option with a property that is'nt allowed"
def __init__(self, msg, proptype): def __init__(self, msg, proptype):
self.proptype = proptype self.proptype = proptype
super(PropertiesOptionError, self).__init__(msg) super(PropertiesOptionError, self).__init__(msg)
#____________config___________ #____________________________________________________________
# Exceptions for a Config
class ConfigError(StandardError): class ConfigError(StandardError):
"""try to change owner for an option without value """attempt to change an option's owner without a value
or if _cfgimpl_descr is None or in case of `_cfgimpl_descr` is None
or if error in calculation""" or if a calculation cannot be carried out"""
pass pass
class ConflictError(StandardError): class ConflictError(StandardError):
"duplicate config" "duplicate options are present in a single config"
pass pass
#____________other___________ #____________________________________________________________
# miscellaneous exceptions
class RequirementRecursionError(StandardError): class RequirementRecursionError(StandardError):
"recursive error" "a recursive loop occurs in the requirements tree"
pass pass
class SlaveError(StandardError): class SlaveError(StandardError):
"problem with slave's length" "problem with a slave's value length"
pass pass

View File

@ -348,6 +348,11 @@ class Option(BaseInformation):
class ChoiceOption(Option): class ChoiceOption(Option):
"""Represents a choice out of several objects.
The option can also have the value ``None``
"""
__slots__ = ('_values', '_open_values', '_opt_type') __slots__ = ('_values', '_open_values', '_opt_type')
_opt_type = 'string' _opt_type = 'string'
@ -355,6 +360,9 @@ class ChoiceOption(Option):
requires=None, multi=False, callback=None, requires=None, multi=False, callback=None,
callback_params=None, open_values=False, validator=None, callback_params=None, open_values=False, validator=None,
validator_args=None, properties=()): validator_args=None, properties=()):
"""
:param values: is a list of values the option can possibly take
"""
if not isinstance(values, tuple): if not isinstance(values, tuple):
raise TypeError(_('values must be a tuple for {0}').format(name)) raise TypeError(_('values must be a tuple for {0}').format(name))
self._values = values self._values = values
@ -386,6 +394,7 @@ class ChoiceOption(Option):
class BoolOption(Option): class BoolOption(Option):
"Represents a choice between ``True`` and ``False``"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'bool' _opt_type = 'bool'
@ -394,6 +403,7 @@ class BoolOption(Option):
class IntOption(Option): class IntOption(Option):
"Represents a choice of an integer"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'int' _opt_type = 'int'
@ -402,6 +412,7 @@ class IntOption(Option):
class FloatOption(Option): class FloatOption(Option):
"Represents a choice of a floating point number"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'float' _opt_type = 'float'
@ -410,6 +421,7 @@ class FloatOption(Option):
class StrOption(Option): class StrOption(Option):
"Represents the choice of a string"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'string' _opt_type = 'string'
@ -418,6 +430,7 @@ class StrOption(Option):
class UnicodeOption(Option): class UnicodeOption(Option):
"Represents the choice of a unicode string"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'unicode' _opt_type = 'unicode'
_empty = u'' _empty = u''
@ -446,6 +459,7 @@ class SymLinkOption(object):
class IPOption(Option): class IPOption(Option):
"Represents the choice of an ip"
__slots__ = ('_opt_type', '_only_private') __slots__ = ('_opt_type', '_only_private')
_opt_type = 'ip' _opt_type = 'ip'
@ -475,6 +489,7 @@ class IPOption(Option):
class NetworkOption(Option): class NetworkOption(Option):
"Represents the choice of a network"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'network' _opt_type = 'network'
@ -487,6 +502,7 @@ class NetworkOption(Option):
class NetmaskOption(Option): class NetmaskOption(Option):
"Represents the choice of a netmask"
__slots__ = ('_opt_type',) __slots__ = ('_opt_type',)
_opt_type = 'netmask' _opt_type = 'netmask'