NAME¶
Config::Model - Create tools to validate, migrate and edit configuration files
VERSION¶
version 2.061
SYNOPSIS¶
Perl program¶
use Config::Model;
use Log::Log4perl qw(:easy) ;
Log::Log4perl->easy_init($WARN);
# create new Model object
my $model = Config::Model->new() ; # Config::Model object
# create config model. Most users will want to store the model
# in lib/Config/Model/models and run "config-edit -model MiniModel"
# See below for details
$model ->create_config_class (
name => "MiniModel",
element => [ [qw/foo bar baz/ ] => { type => 'leaf', value_type => 'uniline' }, ],
read_config => { backend => 'IniFile', auto_create => 1,
config_dir => '.', file => 'mini.ini',
}
) ;
# create instance (Config::Model::Instance object)
my $instance = $model->instance (root_class_name => 'MiniModel');
# get configuration tree root
my $cfg_root = $instance -> config_root ; # C::M:Node object
# load some dummy data
$cfg_root -> load("bar=BARV foo=FOOV baz=BAZV") ;
# write new ini file
$instance -> write_back;
# now look for new mini.ini file un current directory
More convenient¶
$ mkdir -p lib/Config/Model/models/
$ echo "[ { name => 'MiniModel',
element => [ [qw/foo bar baz/ ] => { type => 'leaf', value_type => 'uniline' }, ],
read_config => { backend => 'IniFile', auto_create => 1,
config_dir => '.', file => 'mini.ini',
}
}
] ; " > lib/Config/Model/models/MiniModel.pl
$ config-edit -model MiniModel -model_dir lib/Config/Model/models/ -ui none bar=BARV foo=FOOV baz=BAZV
$ cat mini.ini
Look Ma, no Perl¶
$ echo "Make sure that Config::Model::Itself is installed"
$ mkdir -p lib/Config/Model/models/
$ config-model-edit -model MiniModel -save \
class:MiniModel element:foo type=leaf value_type=uniline - \
element:bar type=leaf value_type=uniline - \
element:baz type=leaf value_type=uniline - \
read_config:0 backend=IniFile file=mini.ini config_dir=. auto_create=1 - - -
$ config-edit -model MiniModel -model_dir lib/Config/Model/models/ -ui none bar=BARV foo=FOOV baz=BAZV
$ cat mini.ini
DESCRIPTION¶
Config::Model enables a project developer to provide an interactive
configuration editor (graphical, curses based or plain terminal) to his users.
For this he must:
- •
- Describe the structure and constraints of his project's configuration
(fear not, a GUI is available)
- •
- Find a way to read and write configuration data using read/write backend
provided by Config::Model or other Perl modules.
With the elements above, Config::Model will generate interactive configuration
editors (with integrated help and data validation). These editors can be
graphical (with Config::Model::TkUI), curses based (with
Config::Model::CursesUI) or based on ReadLine.
Smaller models targeted for configuration upgrades can also be created:
- •
- only upgrade and migration specifications are required
- •
- unknown parameters can be accepted
A command line is provided to perform configuration upgrade with a single
command.
How does this work ?¶
Using this project, a typical configuration editor/validator/upgrader will be
made of 3 parts :
GUI <--------> |---------------|
CursesUI <---> | |---------| |
| | Model | |
ShellUI <----> | |---------| |<-----read-backend------- |-------------|
| |----write-backend-------> | config file |
FuseUI <-----> | Config::Model | |-------------|
|---------------|
- 1.
- A reader and writer that will parse the configuration file and transform
in a tree representation within Config::Model. The values contained in
this configuration tree can be written back in the configuration
file(s).
- 2.
- A validation engine which is in charge of validating the content and
structure of configuration stored in the configuration tree. This
validation engine will follow the structure and constraint declared in a
configuration model. This model is a kind of schema for the configuration
tree.
- 3.
- A user interface to modify the content of the configuration tree. A
modification will be validated instantly by the validation engine.
The important part is the configuration model used by the validation engine.
This model can be created or modified with a graphical editor
(Config::Model::Iself).
Question you may ask yourself¶
You're probably thinking of tools like webmin. Yes, these tools exist and work
fine, but they have their set of drawbacks.
Usually, the validation of configuration data is done with a script which
performs semantic validation and often ends up being quite complex (e.g. 2500
lines for Debian's xserver-xorg.config script which handles
"xorg.conf" file).
In most cases, the configuration model is expressed in instructions (whatever
programming language is used) and interspersed with a lot of processing to
handle the actual configuration data.
What's the advantage of this project ?¶
Config::Model projects provide a way to get a validation engine where the
configuration model is completely separated from the actual processing
instructions.
A configuration model can be created and modified with the graphical interface
provide by Config::Model::Itself. The model is saved in a declarative form
(currently, a Perl data structure). Such a model is easier to maintain than a
lot of code.
The model specifies:
- •
- The structure of the configuration data (which can be queried by generic
user interfaces)
- •
- The properties of each element (boundaries check, integer or string, enum
like type, default value ...)
- •
- The targeted audience (beginner, advanced, master)
- •
- The on-line help
So, in the end:
- •
- Maintenance and evolution of the configuration content is easier
- •
- User will see a *common* interface for *all* programs using this
project.
- •
- Beginners will not see advanced parameters (advanced and master parameters
are hidden from beginners)
- •
- Upgrade of configuration data is easier and sanity check is performed
during the upgrade.
- •
- Audit of configuration is possible to check what was modified by the user
compared to default values
What about the user interface ?¶
Config::Model interface can be:
- •
- a shell-like interface (plain or based on Term::ReadLine).
- •
- Graphical with Config::Model::TkUI (Perl/Tk interface).
- •
- based on curses with Config::Model::CursesUI. This interface can be handy
if your X server is down.
- •
- Through a virtual file system where every configuration parameter is
mapped to a file. (Linux only)
All these interfaces are generated from the configuration model.
And configuration model can be created or modified with a graphical user
interface (with Config::Model::Itself)
What about configuration data storage ?¶
Since the syntax of configuration files vary wildly form one application to
another, people who want to use this framework may have to provide a dedicated
parser/writer.
To help with this task, this project provides writer/parsers for common format:
INI style file and perl file. With the additional
Config::Model::Backend::Augeas, Augeas library can be used to read and write
some configuration files. See
http://augeas.net for more details.
Is there an example of a configuration model ?¶
The "example" directory contains a configuration model example for
"/etc/fstab" file. This example includes a small program that use
this model to show some ways to extract configuration information.
Mailing lists¶
For more question, please send a mail to:
config-model-users at lists.sourceforge.net
Suggested reads to start¶
Beginners¶
- •
- Config::Model::Manual::ModelCreationIntroduction
- •
- Config::Model::Cookbook::CreateModelFromDoc
Advanced¶
- •
- Config::Model::Manual::ModelCreationAdvanced
Masters¶
use the source, Luke
STOP¶
The documentation below is quite detailed and is more a reference doc regarding
"Config::Model" class.
For an introduction to model creation, please check:
Config::Model::Manual::ModelCreationIntroduction
Dedicated Config::Model::Manual pages will follow soon.
Storage backend, configuration reader and writer¶
See Config::Model::BackendMgr for details
Validation engine¶
"Config::Model" provides a way to get a validation engine from a set
of rules. This set of rules is called the configuration model.
User interface¶
The user interface will use some parts of the API to set and get configuration
values. More importantly, a generic user interface will need to explore the
configuration model to be able to generate at run-time relevant configuration
screens.
Simple text interface if provided in this module. Curses and Tk interfaces are
provided by Config::Model::CursesUI and Config::Model::TkUI.
Constructor¶
Simply call new without parameters:
my $model = Config::Model -> new ;
This will create an empty shell for your model.
Configuration Model¶
To validate a configuration tree, we must create a configuration model that will
set all the properties of the validation engine you want to create.
The configuration model is expressed in a declarative form (i.e. a Perl data
structure which is always easier to maintain than a lot of code)
Each configuration class contains a set of:
- •
- node element that will refer to another configuration class
- •
- value element that will contains actual configuration data
- •
- List or hash of node or value elements
By declaring a set of configuration classes and referring them in node element,
you will shape the structure of your configuration tree.
The structure of the configuration data must be based on a tree structure. This
structure has several advantages:
- •
- Unique path to get to a node or a leaf.
- •
- Simpler exploration and query
- •
- Simple hierarchy. Deletion of configuration items is simpler to grasp:
when you cut a branch, all the leaves attaches to that branch go
down.
But using a tree has also some drawbacks:
- •
- A complex configuration cannot be mapped on a simple tree. Some more
relation between nodes and leaves must be added.
- •
- Some configuration part are actually graph instead of a tree (for
instance, any configuration that will map a service to a resource). The
graph relation must be decomposed in a tree with special reference
relation. See "Value Reference" in Config::Model::Value
Note: a configuration tree is a tree of objects. The model is declared with
classes. The classes themselves have relations that closely match the relation
of the object of the configuration tree. But the class need not to be declared
in a tree structure (always better to reuse classes). But they must be
declared as a DAG (directed acyclic graph).
Each configuration class declaration specifies:
- •
- The "name" of the class (mandatory)
- •
- A "class_description" used in user interfaces (optional)
- •
- Optional include specification to avoid duplicate declaration of
elements.
- •
- The class elements
Each element will specify:
- •
- Most importantly, the type of the element (mostly "leaf", or
"node")
- •
- The properties of each element (boundaries, check, integer or string, enum
like type ...)
- •
- The default values of parameters (if any)
- •
- Whether the parameter is mandatory
- •
- Targeted audience (beginner, advance, master), i.e. the level of expertise
required to tinker a parameter (to hide expert parameters from newbie
eyes)
- •
- On-line help (for each parameter or value of parameter)
See Config::Model::Node for details on how to declare a configuration class.
Example:
$ cat lib/Config/Model/models/Xorg.pl
[
{
name => 'Xorg',
class_description => 'Top level Xorg configuration.',
include => [ 'Xorg::ConfigDir'],
element => [
Files => {
type => 'node',
description => 'File pathnames',
config_class_name => 'Xorg::Files'
},
# snip
]
},
{
name => 'Xorg::DRI',
element => [
Mode => {
type => 'leaf',
value_type => 'uniline',
description => 'DRI mode, usually set to 0666'
}
]
}
];
Configuration instance¶
A configuration instance if the staring point of a configuration tree. When
creating a model instance, you must specify the root class name, I.e. the
configuration class that is used by the root node of the tree.
my $model = Config::Model->new() ;
$model ->create_config_class
(
name => "SomeRootClass",
element => [ ... ]
) ;
# instance name is 'default'
my $inst = $model->instance (root_class_name => 'SomeRootClass');
You can create several separated instances from a model using "name"
option:
# instance name is 'default'
my $inst = $model->instance (root_class_name => 'SomeRootClass',
name => 'test1');
Usually, model files will be loaded automatically depending on
"root_class_name". But you can choose to specify the file containing
the model with "model_file" parameter. This is mostly useful for
tests.
Configuration class¶
A configuration class is made of series of elements which are detailed in
Config::Model::Node.
Whatever its type (node, leaf,... ), each element of a node has several other
properties:
- level
- Level is "important", "normal" or "hidden".
The level is used to set how configuration data is presented to the user in
browsing mode. "Important" elements will be shown to the user no
matter what. "hidden" elements will be explained with the
warp notion.
- status
- Status is "obsolete", "deprecated" or
"standard" (default).
Using a deprecated element will issue a warning. Using an obsolete element
will raise an exception.
- description
- Description of the element. This description will be used when generating
user interfaces.
- summary
- Summary of the element. This description will be used when generating user
interfaces and may be used in comments when writing the configuration
file.
- class_description
- Description of the configuration class. This description will be used when
generating user interfaces.
- generated_by
- Mention with a descriptive string if this class was generated by a
program. This parameter is currently reserved for Config::Model::Itself
model editor.
- include
- Include element description from another class.
include => 'AnotherClass' ,
or
include => [qw/ClassOne ClassTwo/]
In a configuration class, the order of the element is important. For
instance if "foo" is warped by "bar", you must declare
"bar" element before "foo".
When including another class, you may wish to insert the included elements
after a specific element of your including class:
# say AnotherClass contains element xyz
include => 'AnotherClass' ,
include_after => "foo" ,
element => [ bar => ... , foo => ... , baz => ... ]
Now the element of your class will be:
( bar , foo , xyz , baz )
create_config_class¶
This method creates configuration classes. The parameters are described above
and are forwarded to Config::Model::Node constructor. See "Configuration
class declaration" in Config::Model::Node for more details on
configuration class parameters.
Example:
my $model = Config::Model -> new ;
$model->create_config_class
(
config_class_name => 'SomeRootClass',
description => [ X => 'X-ray' ],
level => [ 'tree_macro' => 'important' ] ,
class_description => "SomeRootClass description",
element => [ ... ]
) ;
For convenience, "level" and "description" parameters can
also be declared within the element declaration:
$model->create_config_class
(
config_class_name => 'SomeRootClass',
class_description => "SomeRootClass description",
'element'
=> [
tree_macro => { level => 'important'},
X => { description => 'X-ray', } ,
]
) ;
Load predeclared model¶
You can also load predeclared model.
load( <model_name> )¶
This method will open the model directory and execute a ".pl" file
containing the model declaration,
This perl file must return an array ref to declare models. E.g.:
[
[
name => 'Class_1',
element => [ ... ]
],
[
name => 'Class_2',
element => [ ... ]
]
];
do not put "1;" at the end or "load" will not work
If a model name contain a "::" (e.g "Foo::Bar"),
"load" will look for a file named "Foo/Bar.pl".
This method will also look in "Foo/Bar.d" directory for additional
model information. Model snippet found there will be loaded with
augment_config_class.
Returns a list containing the names of the loaded classes. For instance, if
"Foo/Bar.pl" contains a model for "Foo::Bar" and
"Foo::Bar2", "load" will return "( 'Foo::Bar' ,
'Foo::Bar2' )".
augment_config_class (name => '...', class_data )¶
Enhance the feature of a configuration class. This method uses the same
parameters as create_config_class. See "Model Plugin" in
Config::Model::Manual::ModelCreationAdvanced for more details on creating
model plugins.
Model query¶
get_model( config_class_name )¶
Return a hash containing the model declaration (in a deep clone copy of the
hash). You may modify the hash at leisure.
get_model_doc¶
Generate POD document for configuration class.
generate_doc ( top_class_name , [ directory ] )¶
Generate POD document for configuration class top_class_name and write them on
STDOUT or in specified directory.
Returns a list of written file names.
get_element_model( config_class_name , element)¶
Return a hash containing the model declaration for the specified class and
element.
get_element_name( class => Foo )¶
Get all names of the elements of class "Foo".
get_element_property¶
Returns the property of an element from the model.
Parameters are:
- class
- element
- property
list_class_element¶
Returns a string listing all the class and elements. Useful for debugging your
configuration model.
Error handling¶
Errors are handled with an exception mechanism (See Exception::Class).
When a strongly typed Value object gets an authorized value, it raises an
exception. If this exception is not caught, the programs exits.
See Config::Model::Exception for details on the various exception classes
provided with "Config::Model".
Logging¶
See "Logging" in config-edit
BUGS¶
Given Murphy's law, the author is fairly confident that you will find bugs or
miss some features. Please report them to config-model at rt.cpan.org, or
through the web interface at
https://rt.cpan.org/Public/Bug/Report.html?Queue=config-model . The author
will be notified, and then you'll automatically be notified of progress on
your bug.
FEEDBACK¶
Feedback from users are highly desired. If you find this module useful, please
share your use cases, success stories with the author or with the
config-model- users mailing list.
AUTHOR¶
Dominique Dumont, (ddumont at cpan dot org)
LICENSE¶
Copyright (c) 2005-2012 Dominique Dumont.
This file is part of Config-Model.
Config-Model is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Config-Model is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Config-Model; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA
SEE ALSO¶
Config::Model::Instance,
<
https://github.com/dod38fr/config-model/wiki>
<
https://github.com/dod38fr/config-model/wiki/Creating-models>
Model elements¶
The arrow shows the inheritance of the classes
- •
- Config::Model::Node <- Config::Model::AnyThing
- •
- Config::Model::HashId <- Config::Model::AnyId <-
Config::Model::AnyThing
- •
- Config::Model::ListId <- Config::Model::AnyId <-
Config::Model::AnyThing
- •
- Config::Model::Value <- Config::Model::AnyThing
- •
- Config::Model::CheckList <- Config::Model::AnyThing
- •
- Config::Model::WarpedNode <- Config::Model::AnyThing
command line¶
cme. config-edit is now deprecated.
Read and write backends¶
- •
- Config::Model::Backend::Fstab <- Config::Model::Backend::Any
- •
- Config::Model::Backend::IniFile <- Config::Model::Backend::Any
- •
- Config::Model::Backend::PlainFile <- Config::Model::Backend::Any
- •
- Config::Model::Backend::ShellVar <- Config::Model::Backend::Any
- •
- Config::Model::Backend::Yaml <- Config::Model::Backend::Any
Model utilities¶
- •
- Config::Model::Annotation
- •
- Config::Model::BackendMgr: Used by "Config::Model::Node"
object
- •
- Config::Model::Describe
- •
- Config::Model::Dumper
- •
- Config::Model::DumpAsData
- •
- Config::Model::IdElementReference
- •
- Config::Model::Iterator
- •
- Config::Model::Loader
- •
- Config::Model::ObjTreeScanner
- •
- Config::Model::Report
- •
- Config::Model::Searcher: Search element in configuration model.
- •
- Config::Model::SimpleUI
- •
- Config::Model::TreeSearcher: Search string or regexp in configuration
tree.
- •
- Config::Model::TermUI
- •
- Config::Model::Iterator
- •
- Config::Model::ValueComputer
- •
- Config::Model::Warper
Test framework¶
- •
- Config::Model::Tester
AUTHOR¶
Dominique Dumont
COPYRIGHT AND LICENSE¶
This software is Copyright (c) 2014 by Dominique Dumont.
This is free software, licensed under:
The GNU Lesser General Public License, Version 2.1, February 1999
SUPPORT¶
Websites¶
The following websites have more information about this module, and may be of
help to you. As always, in addition to those websites please use your favorite
search engine to discover more resources.
- •
- MetaCPAN
A modern, open-source CPAN search engine, useful to view POD in HTML format.
<http://metacpan.org/release/Config-Model>
- •
- Search CPAN
The default CPAN search engine, useful to view POD in HTML format.
<http://search.cpan.org/dist/Config-Model>
- •
- RT: CPAN's Bug Tracker
The RT ( Request Tracker ) website is the default bug/issue tracking system
for CPAN.
<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Config-Model>
- •
- AnnoCPAN
The AnnoCPAN is a website that allows community annotations of Perl module
documentation.
<http://annocpan.org/dist/Config-Model>
- •
- CPAN Ratings
The CPAN Ratings is a website that allows community ratings and reviews of
Perl modules.
<http://cpanratings.perl.org/d/Config-Model>
- •
- CPAN Forum
The CPAN Forum is a web forum for discussing Perl modules.
<http://cpanforum.com/dist/Config-Model>
- •
- CPANTS
The CPANTS is a website that analyzes the Kwalitee ( code metrics ) of a
distribution.
<http://cpants.perl.org/dist/overview/Config-Model>
- •
- CPAN Testers
The CPAN Testers is a network of smokers who run automated tests on uploaded
CPAN distributions.
<http://www.cpantesters.org/distro/C/Config-Model>
- •
- CPAN Testers Matrix
The CPAN Testers Matrix is a website that provides a visual overview of the
test results for a distribution on various Perls/platforms.
<http://matrix.cpantesters.org/?dist=Config-Model>
- •
- CPAN Testers Dependencies
The CPAN Testers Dependencies is a website that shows a chart of the test
results of all dependencies for a distribution.
<http://deps.cpantesters.org/?module=Config::Model>
Bugs / Feature Requests¶
Please report any bugs or feature requests by email to "bug-config-model at
rt.cpan.org", or through the web interface at
<
http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-Model>. You will
be automatically notified of any progress on the request by the system.
Source Code¶
The code is open to the world, and available for you to hack on. Please feel
free to browse it and play with it, or whatever. If you want to contribute
patches, please send me a diff or prod me to pull from your repository :)
<
http://github.com/dod38fr/config-model>
git clone git://github.com/dod38fr/config-model.git