summaryrefslogtreecommitdiffstats
path: root/tasker/plugins.py
diff options
context:
space:
mode:
authorJoel Andres Granados <jgranado@redhat.com>2008-01-02 14:33:03 +0100
committerJoel Andres Granados <jgranado@redhat.com>2008-01-02 14:33:03 +0100
commitc6986ebc5f3b8f1eec2e615859bb759fe34c6511 (patch)
tree6b5e9ed1dc8c1125b591053cc7e9697e7e7af87f /tasker/plugins.py
parent26da06a02b8cbeea5aea9eccc2de55d33ade23bf (diff)
downloadfirstaidkit-c6986ebc5f3b8f1eec2e615859bb759fe34c6511.tar.gz
firstaidkit-c6986ebc5f3b8f1eec2e615859bb759fe34c6511.tar.xz
firstaidkit-c6986ebc5f3b8f1eec2e615859bb759fe34c6511.zip
Actually remove the tasker stuff.
Diffstat (limited to 'tasker/plugins.py')
-rw-r--r--tasker/plugins.py352
1 files changed, 0 insertions, 352 deletions
diff --git a/tasker/plugins.py b/tasker/plugins.py
deleted file mode 100644
index 8d892c8..0000000
--- a/tasker/plugins.py
+++ /dev/null
@@ -1,352 +0,0 @@
-# First Aid Kit - diagnostic and repair tool for Linux
-# Copyright (C) 2007 Martin Sivak <msivak@redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-from configuration import Config
-from returns import *
-from errors import *
-
-import FirstAidKit
-from log import Logger
-
-import imp
-import os
-import subprocess
-from cStringIO import StringIO
-
-class Flow(dict):
- def __init__(self, rules, description="", *args, **kwargs):
- self.description = description
- dict.__init__(self, rules, *args, **kwargs)
-
-class Plugin(object):
- #
- # Some information vars.
- #
- name = "Plugin"
- version = "0.0.0"
- author = "nobody"
- #
- # Dictionary that holds all the flows. The keys for each flow is its
- # name. The flow will be addressed by this name. The plugin developer
- # Can add as many flows as he wants. The developer must use the instance.
- # obj._flows["name"] = SomeFlow. Be aware that you can overwirhte
- # previously added flows. This class attribute has to be overriden by
- # each plugin.
- #
- flows = {}
-
- #
- # The initial and final states are here to give more flexibilty to the
- # Development process. All flows will start and end with these two
- # Variables.
- #
- initial = 0
- final = 1
-
- #
- # The flow to use with the automated repair mode
- #
-
- default_flow = "defflow"
-
- #
- # This is the default flow that all classes deriving from plugin must
- # have. As the initial state has no return value it will be indexed
- # with the parent of all ReturnValue classes.
- #
- _defflows = {}
- _defflows["defflow"] = Flow({
- initial : {ReturnValue: "prepare"},
- "prepare" : {ReturnValueTrue: "diagnose"},
- "diagnose" : {ReturnValueTrue: "clean", ReturnValueFalse: "backup"},
- "backup" : {ReturnValueTrue: "fix", ReturnValueFalse: "clean"},
- "fix" : {ReturnValueTrue: "clean", ReturnValueFalse: "restore"},
- "restore" : {ReturnValueTrue: "clean", ReturnValueFalse: "clean"},
- "clean" : {ReturnValueTrue: final}
- }, description="The default, fully automated, fixing sequence")
-
- def __init__(self, flow, reporting, dependencies):
- """ Initialize the instance.
-
- flow -- Name of the flow to be used with this instance.
- reporting -- object used to report information to the user
- dependencies -- object encapsulating the inter-plugin dependency API (require, provide)
-
- The flow is defined in the __init__ so we don't have to worry about changing it.
- """
- self._reporting = reporting
- self._dependencies = dependencies
-
- self.provide = dependencies.provide
- self.require = dependencies.require
-
- #
- # state we are in.
- #
- self._state = Plugin.initial
-
- #
- # Used to hold the return value of the functions in the class.
- #
- self._result = None #edge from the state we are in
-
- #
- # Choose the flow for the instance.
- #
- self.defineFlow(flow)
-
- def call(self, step):
- """call one step from plugin"""
- self._result = None #mark new unfinished step
- self._state = step
- return getattr(self, step)()
-
- @classmethod
- def info(cls):
- """Returns tuple (Plugin name, Plugin version, Plugin author)"""
- return (cls.name, cls.version, cls.author)
-
- #
- # The flow functions.
- #
- def defineFlow(self, flow):
- """Defines the current flow to name.
-
- flow -- Name of the flow
- This function is to be called from the __init__ only. There will be the flows defined by the
- Plugin class and the flows defined by the actual plugin. We will first search the Plugin
- class and then the plugin itself for the name.
- """
- #
- # The flow that will be used for the instance.
- #
- if flow in Plugin._defflows.keys():
- self.cflow = Plugin._defflows[flow]
- elif flow in self.__class__.flows.keys():
- self.cflow = self.__class__.flows[flow]
- else:
- raise InvalidFlowNameException(flow)
-
- @classmethod
- def getFlows(cls):
- """Return a set with the names of all possible flows."""
- fatherf = Plugin._defflows.keys()
- pluginf = cls.flows.keys()
- return set(fatherf+pluginf)
-
- @classmethod
- def getFlow(cls, name):
- """Return a Flow object associated with provided name"""
- if cls.flows.has_key(name):
- return cls.flows[name]
- else:
- return Plugin._defflows[name]
-
- #dependency stuff
- @classmethod
- def getDeps(cls):
- """Return list of conditions required to be set before automated run can be done"""
- return set()
-
- #methods available only for instance, see interpreter.py and dependency stuff there
- #def require(self, id)
- #def provide(self, id)
-
- #list of all actions provided
- def actions(self):
- """Returns list of available actions"""
- return set(["prepare", "backup", "diagnose", "describe", "fix", "restore", "clean"])
-
- def nextstate(self, state=None, result=None):
- """Returns next state when analizing self._state, self._result and the self.cflow in automode.
-
- state -- Name of hte function.
- result -- The return value of the previous function
- We do not check for validity of the key in the self.cflow. If key is invalid, function will
- Traceback. When self._state = self.final the function will traceback. This situation must
- be handled outside this function. If an automatica iteration is needed that avoids the
- necesity to address the self.final state, use __iter__ and next.
- """
- # If any of the vals are missing, we default to the current ones.
- if state is None or result is None:
- state=self._state
- result=self._result
- # The self.initial state does not have any return code.
- # It will only work with the ReturnValue.
- try:
- if state == self.initial:
- self._state = self.cflow[self.initial][ReturnValue]
- else:
- self._state = self.cflow[state][result]
- return self._state
- except KeyError:
- raise InvalidFlowStateException(self.cflow)
-
- #
- #iterate protocol allows us to use loops
- #
- def __iter__(self):
- self._state = self.initial
- self._result = None
- return self
-
- def next(self):
- """Iteration function.
-
- Will return (self._state, self._result). The function that was executed and the return value.
- """
- func = self.nextstate()
- if func == self.final:
- raise StopIteration()
- else:
- # Execute the function.
- getattr(self, func)()
- return (self._state, self._result)
-
- #
- #default (mandatory) plugin actions
- #
- def prepare(self):
- """Initial actions.
-
- All the actions that must be done before the execution of any plugin function.
- This function generaly addresses things that are global to the plugin.
- """
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
- def clean(self):
- """Final actions.
-
- All the actions that must be done after the exection of all plugin functions.
- This function generaly addresses things that are global and need to be closed
- off, like file descriptos, or mounted partitions....
- """
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
- def backup(self):
- """Gather important information needed for restore."""
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
- def restore(self):
- """Try to restore the previous state described in backup."""
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
- def diagnose(self):
- """Diagnose the situation."""
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
- def fix(self):
- """Try to fix whatever is wrong in the system."""
- #We want these functions to be overridden by the plugin developer.
- if self.__class__ is Plugin:
- Logger.warning("Clean is an abstract method, it should be used as such.")
-
-class PluginSystem(object):
- """Encapsulate all plugin detection and import stuff"""
-
- def __init__(self, reporting, dependencies, config = Config):
- self._path = Config.plugin.path
- self._reporting = reporting
- self._deps = dependencies
- self._plugins = {}
-
- #create list of potential modules in the path
- importlist = set()
- for f in os.listdir(self._path):
- fullpath = os.path.join(self._path, f)
- Logger.debug("Processing file: %s", f)
- if os.path.isdir(fullpath) and os.path.isfile(os.path.join(self._path, f, "__init__.py")):
- importlist.add(f)
- Logger.debug("Adding python module (directory): %s", f)
- elif os.path.isfile(fullpath) and (f[-3:]==".so" or f[-3:]==".py"):
- importlist.add(f[:-3])
- Logger.debug("Adding python module (file): %s", f)
- elif os.path.isfile(fullpath) and (f[-4:]==".pyc" or f[-4:]==".pyo"):
- importlist.add(f[:-4])
- Logger.debug("Adding python module (compiled): %s", f)
-
- #try to import the modules as FirstAidKit.plugins.modulename
- for m in importlist:
- if m in Config.plugin._list("disabled"):
- continue
-
- imp.acquire_lock()
- try:
- Logger.debug("Importing module %s from %s", m, self._path)
- moduleinfo = imp.find_module(m, [self._path])
- module = imp.load_module(".".join([FirstAidKit.__name__, m]), *moduleinfo)
- Logger.debug("... OK")
- finally:
- imp.release_lock()
-
- self._plugins[m] = module
-
- def list(self):
- """Return the list of imported plugins"""
- return self._plugins.keys()
-
- def autorun(self, plugin, flow = None, dependencies = True):
- """Perform automated run of plugin with condition checking
-returns - True if conditions are fully satisfied
- False if there is something missing
- exception when some other error happens"""
-
- pklass = self._plugins[plugin].get_plugin() #get top level class of plugin
- Logger.info("Plugin information...")
- Logger.info("name:%s , version:%s , author:%s " % pklass.info())
-
- flows = pklass.getFlows()
- Logger.info("Provided flows : %s " % flows)
- if flow==None:
- flowName = pklass.default_flow
- else:
- flowName = flow
-
- Logger.info("Using %s flow" % flowName)
- if flowName not in flows:
- Logger.error("Flow %s does not exist in plugin %s", flowName, plugin)
- raise InvalidFlowNameException(d)
-
- if dependencies:
- deps = pklass.getDeps()
- Logger.info("depends on: %s" % (", ".join(deps),))
- for d in deps:
- if not self._deps.require(d):
- Logger.info("depends on usatisfied condition: %s" % (d,))
- return False
-
- p = pklass(flowName, reporting = self._reporting, dependencies = self._deps)
- for (step, rv) in p: #autorun all the needed steps
- Logger.info("Running step %s in plugin %s ...", step, plugin)
- Logger.info("%s is current step and %s is result of that step." % (step, rv))
-
- return True
-
- def getplugin(self, plugin):
- """Get instance of plugin, so we can call the steps manually"""
- return self._plugins[plugin].get_plugin()
-