summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorJoel Andres Granados <jgranado@redhat.com>2008-01-02 14:09:23 +0100
committerJoel Andres Granados <jgranado@redhat.com>2008-01-02 14:09:23 +0100
commit403519b478ffbe5b433b1fd2fb7babe12c693af2 (patch)
tree24fc9074d36dc3e63441ee54957bfe41ac721091 /doc
parent08ee3e0010cc712fde32054fe67a7befb9432193 (diff)
Add GPL file, move README and PLUGINS into docs. name the name script firstaidkit.
Diffstat (limited to 'doc')
-rw-r--r--doc/PLUGINS159
-rw-r--r--doc/README8
2 files changed, 167 insertions, 0 deletions
diff --git a/doc/PLUGINS b/doc/PLUGINS
new file mode 100644
index 0000000..46e6fd3
--- /dev/null
+++ b/doc/PLUGINS
@@ -0,0 +1,159 @@
+Description of plugin system
+----------------------------
+
+All plugins belong to configured plugin directory. Recognized suffixes are:
+
+- .py, .pyc, .pyo -- python modules
+- .so -- python compatible binary module
+
+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 independant 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
+structure.
+
+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 each
+function is executed. This order/flow is specified using the function
+names, their return codes and the flow structure. All this is contained
+within a dictionary. Lets ilustrate with an example:
+
+1. Consider the following flow:
+ start->fix->end
+2. The dictionary that expresses this flow:
+ dict = { start:fix, fix:end}
+
+Lets ilustrate a more complex example:
+1. Consider the following flow:
+ ,>end
+ start->diagnose
+ `>fix->end
+ 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.
+2. The dictionary that expresses this flow:
+ dict = {start:diagnose, diagnose:{"goodSys":end, "badSys":fix}, fix:end}
+ note that the next step in the diagnose case is defined buy whatever
+ diagnose returned.
+
+The idea is to define individual set of activities in the functions. And
+to put these activities together with the flows. As mentioned before
+the activities are just functions. The flow on the other hand is a dict
+that defines the next function to execute given the return value of the
+current function.
+
+Please take into account as you code your plugin to set the _result and
+the _state values in your main plugin class. These values are necesary
+to correclty execute the flow given by the flow dictionary.
+
+
+When coding the plugin
+----------------------
+These are some important things to consider once you are 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__ fucntion and cause lots of unnecesary
+ stuff to go into memory when we are querying for plugin basic information.
+
+ The class attributes are:
+
+ name : The name of the plugin
+ version : The version of the plugin.
+ author : The authors full name.
+
+ initial : is the initial state for all flows.
+ final : is the final state for all flows.
+
+ _defflows : The default flows defined by the Plugin abstract class.
+ default_flow: is the name of flow used when in automatic repair mode
+
+ The class methods are:
+ info() : returns the name, version and author in a tuple.
+ getFlows() : returns a list of possible flow names that the plugin
+ can execute.
+
+2. Default functions.
+ See section "Common stuff for plugins"
+
+3. 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._resutl variable must be changed to
+ a correct value. This value will define the next self._state value
+ inside the plugin. The self._state value is change using the flow
+ dictionary and the self._resutl value.
+
+4. 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 prety good idea of what to do when using a
+ module, file ...
+
+5. return values:
+ For each function you code in a plugin you must use predefined return
+ classes. It is necesarry 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 for plugins
+------------------------
+Each plugin exports some steps. The mandatory ones are:
+
+- prepare -- initialize plugin, get environment, ..
+- backup -- backup everything we could touch in this plugin
+- diagnose -- get info about the investigated system and determine where
+ the problems are
+- fix -- autofix 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 undeterministic state.
+
+Python modules
+--------------
+A plugin for the FirstAidKit must inherite from the tasker.Plugin class.
+It must also implement the mandatory plugin steps. The tasker.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 garantee that the function will return a valid return
+class (more on return class further on). In other words, the function
+must return one of the possible return classes included in the default
+flow.
+
+tasker.Plugin defines:
+nextstep() -- This is used to return the next function that should be
+ executed. __iter__() is not used because there is no
+ control over __iter__() in an iteration. nextstep()
+ allows us execution of the flow without the need for an
+ iteration. However the iteratior is present in the
+ class and can be used accordinly.
+
+__iter__() and next() -- iterator protocol, works in the same way as
+ nextstep() but end with StopIteration exception
+
+actions() -- returns list of available step names
+call(step) -- calls one specific step identified by name
+info() -- returns tuple of strings defined as (name of plugin, version, author)
+changeFlow() -- allows the caller to change to some other flow defined in the
+ plugin.
+getFlows() -- Returns all the possible flows that the plugin suports.
+
+
+And of course the steps itself. They are defined as methods with the same names
+as used in actions().
+
+Arbitrary executable modules
+----------------------------
+
+The current approach is to create a wrapper python plugin, which holds the metadata
+and calls the binaries as neccessary (see the examples).
+
diff --git a/doc/README b/doc/README
new file mode 100644
index 0000000..49a92a8
--- /dev/null
+++ b/doc/README
@@ -0,0 +1,8 @@
+firstaidkit
+
+A tool tool that automates simple and common recovery tasks.
+
+For more information on how to use this application or on how
+to develop plugins, refer to the documentation contained in
+this package or refer to http://fedorahosted.org/firstaidkit.
+