Plugins
Contents
Warning
This page is a part of work in progress, it documents a feature that is not yet in RackTables source code.
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.
Note that this guide details features that may or may not be included in a future release.
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.
A new plugin architecture was introduced in version 0.20.11. It 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 contains 'name', 'longname', 'version' & '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
There 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); } } }