A Tour Through the Maintain Backend
Backend, what's that?
The backend is the term commonly used to refer to the part of Maintain (scripts, configs, etc) which does not take place on the web interface. Because of this, the backend functionality is mostly hidden from the average user and only apparent to the Admin. Thus, if you are just a Maintain user, you may – but needn't – read this document 
This guide assumes that you know at least to an extent how Maintain's module system works. If you don't, take a look at the module writing guide and the module system documentation.
What happens in the backend?
Maintain's backend mainly has the job to generate config files from the data that users entered into the web frontend. Depending on what other modules you enable though, it may do many different things such as backing up the database, cleaning up things or similar. A very common task is also "pushing" the config files (once they are generated) to the actual DHCP and DNS servers, so that these services actually use the freshly cooked config files instead of the ones they are currently working with.
The whole config file generation process in Maintain's backend is executed by a backend run, i.e. by executing a script, which in instanciates the necessary classes. These classes, in turn, do the actual work of querying the database and writing the config files.
A Little Tour
The Trigger Script
Let's take a tour through a Maintain backend run. The central "trigger script" for a backend run is maintain/bin/build/all -p. This script can be called on the command line by the admin. Most commonly though, it gets called by a cron job (see the FAQ).
By the way, the -p parameter stands for "production" and denotes a "regular" backend run. As an admin, you can also use the "-f" flag if necessary, to force the backend to run, even if it "thinks" it shouldn't.
Let's take a look inside this script (you might have guessed, it's simplified):
<?php
require_once(BACKEND.'/Backend.php');
// instantiate the main backend class. We will have it do everything for us.
$backend = new Backend();
// run backend services
$backend->run();
?>
That was easy, wasn't it? What does it do? It makes an instance of the Backend class and runs it.
The Backend Class
In Maintain's class/backend folder you can find the Backend class which coordinates the rest of the backend run.
Its watered-down code:
<?php
class Backend
{
function run()
{
// acquire lock if necessary
if (!$this->force && !$this->verifyBuildTimestamp()) {
raise_error(); // dummy function
return;
}
Module::do_action('backend_backup');
Module::do_action('backend_maintenance');
Module::do_action('backend_build');
Module::do_action('backend_push');
// we are done, wipe the lock
$this->_wipeLock();
}
function verifyBuildTimestamp()
{
acquire_a_lock(); // dummy function
}
function _wipeLock()
{
release_the_lock(); // dummy function
}
}
?>
What gets executed here (remember the "trigger script"?) is the run() function. This function first acquires a lock (unless you forced the backend operation!) so that no two backend runs get executed at the same time. Otherwise, a cron job and an admin could start two backend runs at almost the same time and run into broken config files, crashing scripts and all sorts of ugliness.
Then the magic happens. The backend class four predefined module action hooks, to which several modules registered themselves earlier (as we will see shortly). Config file generation, pushing, cleanup, it all happens in there.
Eventually, the lock we acquired above is wiped so that now a new backend run can be triggered, by the cron job or the admin, or your goblin of choice.
That's all for the backend class.
A Sample Backend Module
As mentioned before, backend modules are registered to these four backend action hooks, and they get called by the module system when the backend is run.
But how does that look like? Let's take a look at the build_dhcp module.
<?php
class Build_DHCP extends Module
{
function register_hooks()
{
/* part 1: registering hooks */
Module::add_action('backend_build', 'buildDHCP', null, NO_ACCESS);
Module::add_action('backend_push', 'pushDHCP', null, NO_ACCESS);
}
function buildDHCP()
{
/* part 2: building config files */
$fh = @fopen($this->buildfile, 'w');
// print global DHCP options
fwrite($fh, "\n# global DHCP options\n");
$globalopts = $this->_get_dhcp_options('global');
$this->_fwrite_dhcp_options($fh, $globalopts);
fwrite($fh, "# end global options\n\n");
// build dynamic IP ranges
$this->_print_dynamic_ranges($fh);
// build subnet declarations etc.
$this->_print_subnets($fh);
// build workgroup declarations
$this->_print_workgroups($fh);
// build declarations for workgroupless hosts
$this->_print_workgroupless_hosts($fh);
fclose($fh);
}
function pushDHCP()
{
/* part 3: pushing config files to servers */
foreach ($dhcp_servers as $server_id) {
exec('rsync -a '. $this->buildfile .' '.$server_id.' 2>&1', $output, $exitcode);
}
}
(...more functions...)
}
?>
There are three parts involved:
Part 1: Registering Hooks
The module registers itself to the aforementioned backend action hooks. Figuratively spoken, it tells Maintain that it wants to be called when the backend is run. Once in the build step, once in the push step.
Part 2 and 3: Building/Pushing Config Files
These steps are quite self-explanatory. They do the actual work, accessing the database, building config files and pushing them to the DHCP servers.
The End
That's all there is to the Maintain backend. If you have any more questions that were not answered here or in the FAQ, please feel free to post something to the forums, mailinglists or similar
. The Maintain team and other contributors will try to answer your question and update this guide accordingly.