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
===============================
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
=========================================
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
`test_config.test_base_config_and_groups()`.
Accessing the configuration `Option`'s
-----------------------------------------
@ -134,23 +110,3 @@ the value owner is the default `glossary#valueowner`
::
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 ?
@ -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
options to where they are actually used and even more annoying to add
new options. To circumvent these problems the configuration management
was introduced.
was introduced...
What is Tiramisu ?
===================
Tiramisu is yet another configuration handler, wich aims at producing
flexible and fast configuration options access. The main advantages are
its access rules and the fact that the configuration 's
consistency is preserved at any time, see :doc:`consistency`.
There are type and structures's validations for configuration options,
and validations towards the whole configuration.
Tiramisu is yet another configuration handler, wich aims at producing flexible
and fast configuration options access. The main advantages are its access rules
and the fact that the configuration's consistency is preserved at any time, see
:doc:`consistency`. There is of course type and structure validations, but also
validations towards the whole configuration.
Last but not least, configuration options can be reached and changed
according to the access rules from nearly everywhere in the OS boxes,
e.g. the containers via the `http/json` server.
according to the access rules from nearly everywhere in your appliance.
Just the facts
==============
@ -34,33 +31,45 @@ Just the facts
Download
---------
To obtain a copy of the sources, check it out from the repository using
`git`. We suggest using `git` if one wants to access the current development.
To obtain a copy of the sources, check it out from the repository using `git`.
We suggest using `git` if one wants to access the current developments.
::
git clone git://git.labs.libre-entreprise.org/tiramisu.git
This will get you a fresh checkout of the code repository in a local
directory named ``tiramisu``.
This will get you a fresh checkout of the code repository in a local directory
named ``tiramisu``.
Understanding Tiramisu's architecture
--------------------------------------
Getting started
-------------------
The `schema` is loaded from an XML file, and the values of
the configuration options are recovered from a `.ini` like file.
Configuration option objects can be created in different ways. Let's perform
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
that serves configuration datas as `json` strings.
>>> from tiramisu.config import Config
>>> 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.
Once loaded, http server serves the `config.Config()` object, that is,
the configuration options and the configuration groups.
So by now, we have
- 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
option description
see `option.OptionDescription`, see `optionapi#schema`
see `option.OptionDescription`, see `option#schema`
The schema of a configuration :

View file

@ -33,7 +33,7 @@ configuration handler.
getting-started
config
configapi
optionapi
option
status
consistency
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
# ____________________________________________________________
#ValueError if function's parameter not correct
# 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___________
# Exceptions for an Option
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):
self.proptype = proptype
super(PropertiesOptionError, self).__init__(msg)
#____________config___________
#____________________________________________________________
# Exceptions for a Config
class ConfigError(StandardError):
"""try to change owner for an option without value
or if _cfgimpl_descr is None
or if error in calculation"""
"""attempt to change an option's owner without a value
or in case of `_cfgimpl_descr` is None
or if a calculation cannot be carried out"""
pass
class ConflictError(StandardError):
"duplicate config"
"duplicate options are present in a single config"
pass
#____________other___________
#____________________________________________________________
# miscellaneous exceptions
class RequirementRecursionError(StandardError):
"recursive error"
"a recursive loop occurs in the requirements tree"
pass
class SlaveError(StandardError):
"problem with slave's length"
"problem with a slave's value length"
pass

View file

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