diff options
| author | Martin Sivak <msivak@redhat.com> | 2008-03-14 13:54:03 +0100 |
|---|---|---|
| committer | Martin Sivak <msivak@redhat.com> | 2008-03-14 13:54:03 +0100 |
| commit | 020ed3044c04ef342f0ab9fb536b0d940eaca319 (patch) | |
| tree | a6af85304b641021593ea2dab5a7e95640fb7719 | |
| parent | a4c5705a47007f1f5db2c171bfe9f35916c8761d (diff) | |
| download | firstaidkit-020ed3044c04ef342f0ab9fb536b0d940eaca319.tar.gz firstaidkit-020ed3044c04ef342f0ab9fb536b0d940eaca319.tar.xz firstaidkit-020ed3044c04ef342f0ab9fb536b0d940eaca319.zip | |
Add IssuesPlugin class and basic rpm plugin, which uses the issues approach
| -rw-r--r-- | plugins/plugin_rpm/__init__.py | 67 | ||||
| -rw-r--r-- | plugins/plugin_rpm/issue_packages.py | 64 | ||||
| -rw-r--r-- | pyfirstaidkit/issue.py | 98 | ||||
| -rw-r--r-- | pyfirstaidkit/plugins.py | 45 |
4 files changed, 274 insertions, 0 deletions
diff --git a/plugins/plugin_rpm/__init__.py b/plugins/plugin_rpm/__init__.py new file mode 100644 index 0000000..71fea97 --- /dev/null +++ b/plugins/plugin_rpm/__init__.py @@ -0,0 +1,67 @@ +# 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 pyfirstaidkit.plugins import IssuesPlugin,Flow +from pyfirstaidkit.returns import * +from pyfirstaidkit.utils import * +from pyfirstaidkit.reporting import PLUGIN,TASK +from pyfirstaidkit import Config +import rpm + +from issue_packages import RequiredPackages + +class RPMPlugin(IssuesPlugin): + """This plugin provides checks for RPM database.""" + # + # Additional flow defprepareion. + # + flows = Flow.init(IssuesPlugin) + + name = "RPM plugin" + version = "0.0.1" + author = "Martin Sivak" + + issue_tests = [RequiredPackages] + + @classmethod + def getDeps(cls): + return set(["root", "experimental", "filesystem"]) + + def __init__(self, *args, **kwargs): + IssuesPlugin.__init__(self, *args, **kwargs) + self.rpm = None + + def prepare(self): + self._reporting.info(self.name+" in Prepare task", origin = self, level = PLUGIN) + self.rpm = rpm.ts(Config.system.root) + IssuesPlugin.prepare(self) + + def backup(self): + self._reporting.info(self.name+" in backup task", origin = self, level = PLUGIN) + self._result=ReturnSuccess + + def restore(self): + self._reporting.info(self.name+" in Restore task", origin = self, level = PLUGIN) + self._result=ReturnSuccess + + def clean(self): + self._reporting.info(self.name+" in Clean task", origin = self, level = PLUGIN) + del self.rpm + self._result=ReturnSuccess + +def get_plugin(): + return RPMPlugin diff --git a/plugins/plugin_rpm/issue_packages.py b/plugins/plugin_rpm/issue_packages.py new file mode 100644 index 0000000..46db8fe --- /dev/null +++ b/plugins/plugin_rpm/issue_packages.py @@ -0,0 +1,64 @@ +# File name: issue_filesystem.py +# Date: 2008/03/14 +# Author: Martin Sivak <msivak at redhat dot com> +# +# Copyright (C) Red Hat 2008 +# +# 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 +# in a file called COPYING along with this program; if not, write to +# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +# 02139, USA. + +from pyfirstaidkit.issue import Issue +from pyfirstaidkit.reporting import TASK + +class RequiredPackages(Issue): + name = "Required Packages" + description = "There are some very important packages missing. It is likely your instalation could be damaged." + + packages_list = ["filesystem", "initscripts"] + + def detect(self): + result = Issue.detect(self) + if result is not None: + return result + + architectures = {} + + for p in self.packages_list: + architectures[p] = set() + mi=self._plugin.rpm.dbMatch("name", p) + for hdr in mi: + self._plugin._reporting.debug(level = TASK, origin = self, message = "Found package %s with architecture %s" % (p, hdr["arch"])) + architectures[p].add(hdr["arch"]) + + #is there a common architecture for all the packages? + all = reduce(lambda acc,x: acc.union(x), architectures.values(), set()) + common = reduce(lambda acc,x: acc.intersection(x), architectures.values(), all) + self._plugin._reporting.debug(level = TASK, origin = self, message = "Common architecture for all packages is %s" % ("+".join(common),)) + + if len(common)==0: + self._happened = True + else: + self._happened = False + + self._detected = True + return True + + def fix(self): + result = Issue.fix(self) + if result is not None: + return result + + self._fixed = False + return True diff --git a/pyfirstaidkit/issue.py b/pyfirstaidkit/issue.py new file mode 100644 index 0000000..caf9822 --- /dev/null +++ b/pyfirstaidkit/issue.py @@ -0,0 +1,98 @@ +# File name: issue.py +# Date: 2008/03/14 +# Author: Martin Sivak <msivak at redhat dot com> +# +# Copyright (C) Red Hat 2008 +# +# 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 +# in a file called COPYING along with this program; if not, write to +# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +# 02139, USA. + +class Issue(object): + name = "Parent issue" + description = "This happens when you use the wrong object in the issues list" + + def __init__(self, plugin): + self._plugin = plugin + self.reset() + + def detect(self): + """Detect if this situation happened and store some information about it, so we can fix it +Return values: + True - detection OK + False - detection Failed + None - no result, please continue with the operation""" + + #if the issue was fixed. the detection is worthless + #if it was detected, no need to do the detection again + if self._detected or self._fixed: + return not self._fixed and self._detected + + return None #no error, please do the detection (so the child-class knows to actually do something) + + def fix(self): + """Fix the situation if needed +Return values: + True - fix OK + False - fix Failed + None - no result, please continue with the operation""" + + #if the issue was fixed. no need to do the fix again + #if it was not detected, the detection si needed too + if not self._detected or self._fixed: + return self._fixed and self._detected + + return None #no fix error, please do the fix (so the child-class knows to actually do something) + + def happened(self): + """Get the 'issue happened' flag. +Return values: + True - YES it happened + False - NO, it is OK + None - I don't know, there was an error""" + #if the issue was fixed or not detected, the detection si needed + if not self._detected or self._fixed: + return None + else: + return self._happened + + + def reset(self): + """Reset the object's state""" + self._detected = False + self._happened = False + self._fixed = False + + def __str__(self): + s = [] + if self._fixed: + s.append("Fixed") + elif self._happened and self._detected: + s.append("Detected") + elif self._detected: + s.append("No problem with") + else: + s.append("Waiting for check on") + + s.append(self.name) + + if self._happened and self._detected: + s.append("--") + s.append(self.description) + + return " ".join(s) + + def str(self): + return self.__str__() + diff --git a/pyfirstaidkit/plugins.py b/pyfirstaidkit/plugins.py index 7d6080f..07e4c50 100644 --- a/pyfirstaidkit/plugins.py +++ b/pyfirstaidkit/plugins.py @@ -20,6 +20,7 @@ from returns import * from errors import * from reporting import * from copy import copy,deepcopy +from issue import * import FirstAidKit import logging @@ -290,6 +291,50 @@ class Plugin(object): if self.__class__ is Plugin: Logger.warning("Fix is an abstract method, it should be used as such.") +class IssuesPlugin(Plugin): + """Simple plugin which uses Issue classes to test more small and INDEPENDENT issues in the system. +Just fill the issue_tests list with classes describing the tests and let it run.""" + + issue_tests = [] #List of Issue classes to check + + def __init__(self, flow, reporting, dependencies, path = None): + Plugin.__init__(self, flow, reporting, dependencies, path) + self.tests = [] + + def prepare(self): + """Prepare the issues list""" + for i in self.issue_tests: + self._reporting.info(level = TASK, origin = self, message = "Preparing tests for '%s'" % (i.name,)) + self.tests.append(i(plugin = self)) + self._result=ReturnSuccess + + def diagnose(self): + """Diagnose the situation.""" + + result = False + for i in self.tests: + self._reporting.info(level = TASK, origin = self, message = "Investigating '%s'" % (i.name,)) + result = result or i.detect() + + if result: + self._result=ReturnSuccess + else: + self._result=ReturnFailure + + def fix(self): + """Try to fix whatever is wrong in the system.""" + + result = False + for i in self.tests: + self._reporting.info(level = TASK, origin = self, message = "Fixing '%s'" % (i.name,)) + result = result or i.fix() + + if result: + self._result=ReturnSuccess + else: + self._result=ReturnFailure + + class FlagTrackerPlugin(Plugin): """This kind of plugin monitores all the flags in the system and when certain flags are set, provides some kind of higher level flag. |
