Dominique Dumont > Config-Model-2.054 > Config::Model

Download:
Config-Model-2.054.tar.gz

Dependencies

Annotate this POD

Website

CPAN RT

Open  0
View/Report Bugs
Module Version: 2.054   Source   Latest Release: Config-Model-2.059

NAME ^

Config::Model - Create tools to validate, migrate and edit configuration files

VERSION ^

version 2.054

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:

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:

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 ^

Don't we already have some configuration validation tools ?

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:

So, in the end:

What about the user interface ?

Config::Model interface can be:

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

Advanced

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:

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:

But using a tree has also some drawbacks:

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).

More on DAGs

Each configuration class declaration specifies:

Each element will specify:

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:

experience

By using the experience parameter, you can change the experience level of each element. Possible experience levels are master, advanced and beginner (default).

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',
   experience        => [ [ qw/tree_macro warp/ ] => 'advanced'] ,
   description       => [ X => 'X-ray' ],
   level             => [ 'tree_macro' => 'important' ] ,
   class_description => "SomeRootClass description",
   element           => [ ... ]
  ) ;

For convenience, experience, 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',
                        experience => 'advanced',
                      },
        warp       => { experience => 'advanced', } ,
        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, for => advanced )

Get all names of the elements of class Foo that are accessible for experience level advanced.

Level can be master (default), advanced or beginner.

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

command line

cme. config-edit is now deprecated.

Read and write backends

Model utilities

Test framework

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.

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
syntax highlighting: