Plugins
Contents
Overview
Plugins provide the ability to add functionality to RackTables and, in some cases, override existing behavior. See the racktables-contribs repository for user-submitted plugins.
States
A plugin may be in one of three states.
- Not installed — it exists in the plugins directory, but hasn't been installed yet
- Enabled — it has been installed and is active
- Disabled — it has been installed and was subsequently disabled
Administration
To install a plugin, first copy it to the plugins
directory. Then visit the Configuration → Plugins page and click the Edit tab. The new plugin should be listed with a state of "Not installed". Click the Install icon.
To upgrade a plugin, first backup the appropriate plugins
sub-directory. To be safe, it's also a good idea to backup your entire database. Afterwards, copy over the new version into the plugins
directory. When you visit the Edit tab of the Configuration → Plugins page, you should see a variance in the Code Version and DB Version columns. Click the Upgrade icon.
Writing a Plugin
The old procedure involves placing a PHP file in the plugins
directory of your RackTables installation. That method has limited functionality and may be deprecated at a later date.
RackTables release 0.21.0 had introduced a new plugin architecture, which includes the ability to install, uninstall, enable and disable plugins from the web interface. It is assumed that each plugin resides in its own directory within the main plugins
directory, and that each plugin contains a plugin.php
file which includes certain functions. The design was inspired by Cacti's plugin architecture.
Files
Each plugin is expected to contain certain files. While the only required file is plugin.php
, it is recommended that you include all mentioned files, especially if you intend to publish it for others.
README
— Provide a general description. If you expect the plugin to be accepted into the racktables-contribs repo, use the Markdown format.ChangeLog
— Document changes made to each revision.LICENSE
Functions
Name | Returns | Description |
---|---|---|
plugin_PLUGINNAME_info()
|
array | Array keys are name , longname , version and home_url .
|
plugin_PLUGINNAME_init()
|
void | Initialize the plugin. Register pages, tabs, triggers, handlers, etc. |
plugin_PLUGINNAME_install()
|
boolean | Make any necessary modifications (create tables, create Config settings, etc.) |
plugin_PLUGINNAME_uninstall()
|
boolean | Make any necessary modifications (drop tables, delete Config settings, etc.) |
plugin_PLUGINNAME_upgrade()
|
boolean | Make any necessary modifications (alter tables, modify Config settings, etc.) |
plugin_PLUGINNAME_HOOKNAME()
|
varies | Run when called by a system-level function (described below in the Hooks section) |
Hooks
These are used in cases where custom functions defined by a plugin should be called at specific times.
Examples:
- When resetting or deleting an object
- Resetting the Config settings (Configuration → User interface)
- Viewing the Data Integrity report
Hooks are already supported in some functions, such as commitResetObject()
. If you need it supported by another function, create a GitHub pull request and it will probably be accepted.
Upgrades
The plugin_PLUGINNAME_upgrade()
function is mandatory. If this is the first version, or if no upgrade steps are required, simply have the function return TRUE
.
There are many cases where upgrades involve adding/modifying/deleting tables, Config settings or other pieces of information. These transitions should be handled by the upgrade function.
Example modeled after the core RackTables upgrader:
function plugin_myplugin_upgrade () { $db_info = getPlugin ('myplugin'); $v1 = $db_info['db_version']; $code_info = plugin_plugin_info (); $v2 = $code_info['version']; if ($v1 == $v2) throw new RackTablesError ('Versions are identical', RackTablesError::INTERNAL); // find the upgrade path to be taken $versionhistory = array ( '1.0', '2.0', '3.0' ); $skip = TRUE; $path = NULL; foreach ($versionhistory as $v) { if ($skip and $v == $v1) { $skip = FALSE; $path = array(); continue; } if ($skip) continue; $path[] = $v; if ($v == $v2) break; } if ($path === NULL or ! count ($path)) throw new RackTablesError ('Unable to determine upgrade path', RackTablesError::INTERNAL); // build the list of queries to execute $queries = array (); foreach ($path as $batchid) { switch ($batchid) { case '2.0': // perform some upgrade step here $queries[] = "UPDATE Plugin SET version = '2.0' WHERE name = 'myplugin'"; break; case '3.0': // perform some upgrade step here $queries[] = "UPDATE Plugin SET version = '3.0' WHERE name = 'myplugin'"; break; default: throw new RackTablesError ("Preparing to upgrade to $batchid failed", RackTablesError::INTERNAL); } } // execute the queries global $dbxlink; foreach ($queries as $q) { try { $result = $dbxlink->query ($q); } catch (PDOException $e) { $errorInfo = $dbxlink->errorInfo(); throw new RackTablesError ("Query: ${errorInfo[2]}", RackTablesError::INTERNAL); } } }