The typical eBox module handles the configuration of a daemon, possibly integrated with other eBox modules. The developer decides in what ways should the user be able to configure the daemon, this ways do not necessarily map directly to the daemon configuration options on a one-to-one relationship. The developer may pick a sane default value for most of the options and hide them from the user, showing him just the ones that he feels are important. Even further, an option changed by the user through the web interface may cause configuration changes in several real configuration options or even on several eBox modules. The main goal is to have an user interface as simple, easy to use, and integrated as possible, while providing the user with a rich set of features.
However, there may be modules that do not handle the configuration of a network service. An example is the 'sysinfo' module in the base system, it just gathers system information to be shown in the Summary page and provides a few menu entries for features that do not belong to any module in particular. The module parent class defines several abstract methods that real modules are free to leave unimplemented. Thus, a module may just provide info in the Summary, add new menu items, handle a network service or all of the above.
The normal, and most interesting, case is the module described in the first paragraph. Such a module has three parts.
It defines and implements an API that will let the GUI, other modules or plain perl scripts configure the daemon it is going to handle.
The second is the GUI, which is a set of CGIs that show the current configuration to the user and let him change it, these CGIs use the API defined earlier to fetch the configuration info and make changes to it.
The third part of the module is usually quite small, it translates all the configuration information stored in GConf into firewall rules, configuration files and commands that make the network service behave as the user expects. It also takes care of starting, stopping and restarting the service when needed.
This separation between the GUI and the backend opens the possibility for other means of changing the configuration. One such means is through perl scripts, these is useful when making packages for a distribution, the package maintainer can write a simple script to import the current system configuration into eBox, or set up some default values. Another use of the API is for other modules, the firewall module is the most used case, almost all modules need tell the firewall to open some port for them. In the future a wrapper may be written around these APIs to publish them through web-services, this would make eBox configurable programmatically over the network.
Besides these three parts, the module has some other minor parts, like its piece of the summary page in the web interface, menu entries, dependency declarations, backups of configuration pieces not stored in GConf, etc.
That's all there is to it, creating a module is as simple as following these steps:
Decide what daemon your module is going to handle and learn how it works and how to set it up.
Plan what options you are going to expose to the user through the web interface, and how they may interact with other eBox modules
Define and implement the API that will let the GUI manipulate
the necessary configuration options. The main class in your module
should inherit from EBox::GConfModule
, this
class wraps the GConf API and transparently implements some useful
features that all eBox modules need to have.
Create the CGIs and HTML templates that will let the
user interact with the module. CGIs should inherit from the
EBox::CGI::Base
class which, again, provides
some features transparently to all its children.
Write the code needed to make the daemon work, possibly
generating a configuration file and setting up a firewall rule using the
EBox::Firewall
class. Configuration files are
generated almost trivially with mason, which is the template system
also used to generate the HTML pages for the GUI.
The size and complexity of a module depends directly on the complexity of the service involved and the amount of configuration items exposed to the user. The necessary work to make a small eBox module is minimal, take the DNSCache module as an example, its CGIs add up to 49 lines of code and the module itself is 134 lines long.
The directory structure of an eBox module may look quite complex for a newcomer. A usual eBox module directory should look like this:
AUTHORS configure.ac INSTALL Makefile.am README stubs/ autogen.sh COPYING NEWS schemas/ tools/ ChangeLog debian/ m4/ po/ src/ www/ migration/
The more important directories are src/
,
schemas/
, www/
,
stubs/
and migration/
.
The src/
directory contains the source
code for the module. Inside this directory two directories can be
found: EBox
and templates
.
The EBox
directory contains the Perl source code
files, including a CGI
subdirectory with the web
frontend for the module. The templates
directory
is used to store the Mason templates, which will be used to generate
the HTML output.
The schemas/
directory contains gconf
schemas, used to define the configuration schemas for modules, and
optionally provide default values for some options.
The www/
directory contains images and
stylesheets that will be used in the web frontend.
The stubs/
is used to store Mason templates
to generate configuration files for the module services.
The migration/
stores the
migration perl scripts
to upgrade from an eBox module version to a newer one.