refactoring the doc for the 0.55 new API
This commit is contained in:
parent
89dca8d707
commit
988bd659b8
9 changed files with 184 additions and 236 deletions
Binary file not shown.
Before Width: | Height: | Size: 8.3 KiB |
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 :
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ configuration handler.
|
|||
getting-started
|
||||
config
|
||||
configapi
|
||||
optionapi
|
||||
option
|
||||
status
|
||||
consistency
|
||||
glossary
|
||||
|
|
115
doc/option.txt
Normal file
115
doc/option.txt
Normal 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__
|
||||
|
||||
|
||||
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
Loading…
Reference in a new issue