firstaidkit-plugin (1) - Linux Manuals
NAME firstaidkit-plugins
.SHDESCRIPTION This man page tries to describe the inner workings of the plugin system for FirstAidKit. It also contains useful information to develop a plugin for firstaidkit.Plugin Suffixes
All plugins belong to configured plugin directory. Recognized suffixes are: .py, .pyc, placed in a default location (/usr/{lib,lib64}/firstaidkit-plugins).Plugin Model
The building blocks of the plugins are functions and flows. A function is a certain action that is taken inside the plugin. This action is more or less independent from the rest of the plugin actions. Things like fix, backup, restore... qualify as actions/functions. This does not mean that functions do not relate to each other. They are related by using the flow data structure (The data structure used for the flows is a dictionary).A flow is the organization of functions in a directional graph that defines the "flow" of functions. Understand flow here as the order in which functions are executed when the plugin is used. This order/flow is specified using the function names, their return codes and the flow data structure. All this is contained within a dictionary (The Examples Sections shows how this is done.)
Coding a Plugin
- 1. Class methods and class attributes:
-
The main plugin class has some class methods and some class attributes. These elements are
used to describe the plugin and are used without actually using a instance of the plugin.
This is important because we do not want to execute the __init__ function and cause lots of
unnecessary stuff to go into memory when we are querying for plugin basic information.
The class attributes are: name, version, author and the defined flows. For the information to be displayed correctly to the user the plugin developer must include at least name, version and author as class attributes. The flows attribute is not necesarry if custom flows aren't present. If the plugin developer is planning to create a custom flows he must declare the flows dictionary for your plugin. More information of the class attributes in the "Class Attribute" section.
The class methods are: info() (returns the name, version and author in a tuple), getDeps() (returns list of required flags for automated mode) and getFlows() (returns a list of possible flow names that the plugin can execute). The plugin developer doesn't really have to worry about the methods as they are defined in the father class Plugin. Section "Class Methods" gives more infor on each one.
- 2. Plugin dependencies
-
You can also specify flags, which are required to be satisfied before the automated mode can
use this plugin. The requirements should be returned as python set of strings by the getDeps()
class method. Setting flags is also easy. Just use the provide() method common to all plugins.
There is also getConflicts() method, with the very same behaviour as getDeps(), but with the opposite meaning. Meaning, it is a set of flags, which have to NOT be satisfied for the plugin to be processed.
- 3. Default functions:
-
See section "Common stuff for plugins"
- 4. Flows:
-
There are two basic flows hardcoded into the system. These flows may *not* be used by plugin
developers. The first flow is called diagnose: the intention with this flow is to give the
user information of the state of the system that the plugin is analysing. This flow is
intended to give general information and needs to be very fast. If the plugin needs to do
some more detailed diagnose analysis, we suggest to create another flow called 'detailedAnalysis'.
When coding the diagnose flow, remember that it will be executed when the user asks for the
information of *all* the plugins. The diagnose flow calls only the prepare, diagnose and clean tasks.
The second flow is called fix: the intention with this flow is to actually fix whatever
is wrong with the system. We suggest this flow to be as thorough as it needs to be. If there
is more than one way to fix the problem, this flow would be the easiest one (the plugin
developer can create other flow for the more complex ones). For this flow to be successfull
the prepare, diagnose, backup, fix, restore and clean tasks must be present in the plugin.
for more info see section "Common stuff for plugins". Finally, to add a custom flow the
plugin developer must initialize a dictionary named flows using flows = Flow.init(parent class)
and fill it with the custom flows. For more info on adding flows see the "Examples" section.
- 5. self._result and self._state
-
These are the two variables that define the location of the plugin inside the flow dictionary.
In each function, after it has done its intended action, the self._result variable must be
changed to a correct value. Think of the self._result as the return value of each task. Before
any task is executed, the self._result is set to None, so we can handle exceptions as special
direction in flows. The self._result usually takes a firstaidkit return value (classes that
define the return value).
Firstaidkit comes with predifined return value classes but the plugin developer may define his own return classes. One reason to define a custom return class is to have actual values be passed between tasks (this is not yet implemented as the tasks are in the same class and can interchange values using the class variable). The self._state is the name of the task where the plugin is at a certain moment. The self._state variable is of no real use to the plugin developer as he must know in what task the plugin is in.
- 6. get_plugin()
-
Each plugin must define a get_plugin function. This function must return the main class of the
plugin. This is used to take out info from the plugin, and to instantiate it. If in doubt, take a
look at the sample plugins that come with the man FirstAidKit code base. They can give you a pretty
good idea of what to do when using a module, file ...
- 7. return values:
-
For each function you code in a plugin you must use predefined return classes. It is necessary to
have the extra wrapper because the python native types can get messy (1==True). Just use the ones
provided by the plugin system, or create your own.
Common stuff
Each plugin, by default, should exports some steps. The mandatory ones are:- prepare
- Initialize plugin, get environment.
- backup
- Backup everything we could touch in this plugin. (Also see the firstaidkit-backup manpage)
- diagnose
- Get info about the investigated system and determine where the problems are.
- fix
- Auto fix the errors from diagnose step.
- restore
- Restore system from backup.
- clean
- Destroy the plugin, cleanup.
The plugin should ensure that the calling order is correct and the system cannot end in some indeterminate state.
Python Modules:
A plugin for the FirstAidKit must inherit from the pyfirstaidkit.Plugin class. It must also implement the mandatory plugin steps. The pyfirstaidkit.Plugin parent will provide a default flow that will use the functions defined by the plugin developer. Moreover, for the mandatory steps, the plugin developer must guarantee that the function will return a valid return class (see "Return Values section"). In other words, the function must return one of the possible return classes included in the default flow. Each plugin must have the get_plugin method in order to actually be seen by the firstaidkit backend.Class Attributes:
This is how the diagnose and fix flows are coded in the backend plugin system.initial
"prepare"
"diagnose"
"clean"
}, description="The default, fully automated, diagnose sequence")
Other important class attributes are: name, version, author and description. They are selfexplanatory.
This flow has a conditional after the diagnose function. If diagnose results in a corrupt
state of the system, then the plugin proceeds with fix. If all is good in the system, then
the flow end. Note that the next step in the diagnose case is defined buy whatever diagnose
returned.
initial
"prepare"
"diagnose"
"backup"
"fix"
"restore"
"clean"
}, description="The default, fully automated, fixing sequence")
Class Methods:
pyfirstaidkit.Plugin defines:
Arbitrary Executable Modules
The current approach is to create a wrapper python plugin, which holds the meta data
and calls the binaries as necessary (see the examples).
Examples
AUTHORS
Martin Sivak <msivak [at] redhat.com>
Joel Granados <jgranado [at] redhat.com>
BUGS
Please search/report bugs at http://fedorahosted.org/firstaidkit/newticket
SEE ALSO
firstaidkit-reporting manpage
firstaidkit-backup manpage
http://fedorahosted.org/firstaidkit