summaryrefslogtreecommitdiffstats
path: root/firstaidkitrevert
diff options
context:
space:
mode:
authorJoel Andres Granados <jgranado@redhat.com>2008-10-22 18:50:13 +0200
committerJoel Andres Granados <jgranado@redhat.com>2008-10-24 15:01:04 +0200
commit1615b70e2fdd6e36d4050ee9c55aaf15a0501a6f (patch)
treea3279e24a0caf46016a724bac033befc37fa54c1 /firstaidkitrevert
parentac73d062f903c69b7475b124ee1549d6062aab25 (diff)
downloadfirstaidkit-1615b70e2fdd6e36d4050ee9c55aaf15a0501a6f.tar.gz
firstaidkit-1615b70e2fdd6e36d4050ee9c55aaf15a0501a6f.tar.xz
firstaidkit-1615b70e2fdd6e36d4050ee9c55aaf15a0501a6f.zip
Add the revert functionality to firstaidkit.
This introduces new requirements to the plugins. 1. If a plugin wants to be revertable it must implement the revert function. This function will be accessible from the plugins top most namespace. The same place where get_plugin is. 2. For the plugin's backend directory to be easily found, the plugin must give the backend its module name as an id. In this way when the user specifies in the revert command line plugin 'x', the revert class will go to the backup directory in search for a directory called the same way as the module of 'x'. 3. If the plugin developer does not want to use the system of backup dir naming, there is a second way how to specify the backup dir. The plugin must specify a function getBackupId(), that will return the id of the backup space that can be used for the backup dir search. Backup spaces that fail to comply with these directive will be ignored.
Diffstat (limited to 'firstaidkitrevert')
-rwxr-xr-xfirstaidkitrevert188
1 files changed, 188 insertions, 0 deletions
diff --git a/firstaidkitrevert b/firstaidkitrevert
new file mode 100755
index 0000000..f8b0ce4
--- /dev/null
+++ b/firstaidkitrevert
@@ -0,0 +1,188 @@
+#!/usr/bin/python -tt
+# First Aid Kit - diagnostic and repair tool for Linux
+# Copyright (C) 2007 Joel Granados <jgranado@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.
+
+import getopt, sys, os, os.path, pickle
+
+from pyfirstaidkit import Config
+from pyfirstaidkit import reporting
+from pyfirstaidkit import initLogger
+from pyfirstaidkit.plugins import PluginSystem
+from pyfirstaidkit.dependency import Dependencies
+
+import logging
+
+
+
+# backup object location inside the backup directory.
+# FIXME: Take this value from the Backup class.
+bolocation = "__meta.pickle"
+
+def usage(name):
+ print("""Usage:
+%s [opts] <plugins>
+ - Executes the revert function of the listed plugins.
+ If the plugin name has a space use quotation marks
+ ("")
+
+opts:
+ -P <path> - add different plugin path it can be used more than
+ once.
+ -c <config file> - location of the config file
+ --dir=BACK_UP_DIR - The directory where the backups are. The user
+ must specify this option.
+ --all - When "all" option is passed, revert ignores the
+ list of plugins and tries to revert everything
+ present in directory.
+""") % (name,)
+
+def revert(picklepath, plugin, report):
+ """ user the plugin revert function with the backup object stored in path.
+
+ path - Path to pickle file for backup object of plugin.
+ plugin - module that has the revert fuction.
+ """
+ # We recover the backup object from the pickle file.
+ try:
+ fd = open(picklepath, 'rb')
+ backup = pickle.load(fd)
+ fd.close()
+ except:
+ Logger.critical("FAK Revert: An error has occured while accessing the backup " \
+ "object for %s." % plugin)
+ sys.exit(1)
+
+ # We try to execute the plugin revert function.
+ try:
+ plugink = plugin.get_plugin()
+ plugink.revert(backup, report)
+ except:
+ Logger.warning("FAK Revert: An Erro has occured whle executing the revert " \
+ "function for plugin %s/" % plugin)
+
+
+def findPicklePath(plugin):
+ retval = os.path.join(Config.revert.dir, \
+ plugin.__name__.split('.')[-1:][0], bolocation)
+ if os.path.isfile(retval):
+ return retval
+ else:
+
+ # Ask the plugin for the directory name.
+ try:
+ retval = os.path.join(Config.revert.dir, plugin.getBackupId())
+ except:
+ Logger.warning("FAK Revert: No backup directory was found for %s." \
+ % plugin.__name__)
+ retval = ""
+
+ # FIXME: if there is a change of the namespace for the current
+ # plugin being different from the namespace of the same plugin
+ # but called from firstaidkit, we should include a check for this.
+
+ return retval
+
+
+if __name__ == "__main__":
+ try:
+ (opts, vars) = getopt.getopt(sys.argv[1:], "c:P", \
+ ["all", "dir=", "plugin-path=", "config="])
+ except Exception, e:
+ print("\nError parsing the argument line: ",e,"\n")
+ usage(sys.argv[0])
+ sys.exit(1)
+
+ for (o, val) in opts:
+ if o == "--dir":
+ if os.path.isdir(val):
+ Config.revert.dir = val
+ else:
+ print("%s is not a valid directory." % val)
+ usage(sys.argv[0])
+ sys.exit(1)
+ elif o == "--all":
+ Config.revert.all = "True"
+
+ elif o in ("-P", "--plugin-path"):
+ if not os.path.isdir(val):
+ print("%s is not a valid directory."% val)
+ usage(sys.argv[0])
+ sys.exit(1)
+ Config.set("paths", val.strip("/"), val)
+
+ elif o in ("-c", "--config"):
+ Config.read(val)
+
+
+
+ # FIXME: implement the use of quotation marks.
+ plugins = vars
+
+ if len(plugins) == 0 and Config.revert.all == "False":
+ print("You must give a list of plugins after the optiosn. Or " \
+ "the --all options so the plugin list gets ignored.")
+ usage(sys.argv[0])
+ sys.exit(1)
+
+ if len(Config.revert.dir) == 0:
+ print("You must specify a directory.")
+ usage(sys.argv[0])
+ sys.exit(1)
+
+
+
+ # Modify the logging a little
+ Config.log.filename = "/var/log/firstaidkitrevert.log"
+ Config.log.fallbacks = \
+ "firstaidkitrevert.log,/tmp/firstaidkitrevert.log,/dev/null"
+ Config.log.method = "stdout"
+
+ # initialize log for plugin system.
+ fallbacks = Config.log.fallbacks.split(",")
+ for lfile in fallbacks:
+ try:
+ initLogger(Config)
+ break
+ except Exception, e:
+ if lfile != fallbacks[len(fallbacks)-1]:
+ Config.log.filename = lfile
+ continue
+ else:
+ print(e)
+ usage(sys.argv[0])
+ sys.exit(1)
+ Logger = logging.getLogger("firstaidkit")
+ report = reporting.Reports(maxsize = 1, round = True)
+
+ # initialize the plugin system.
+ try:
+ ps = PluginSystem(report, Dependencies())
+ except:
+ Logger.critical("FAK Revert: An error has occured while creating the Plugin " \
+ "system.")
+ sys.exit(1)
+
+ if Config.revert.all == "True":
+ plugins = ps.list()
+
+ # we execute the revert for all plugins passed by the user.
+ for plugin in plugins:
+ picklepath = findPicklePath(ps._plugins[plugin])
+ if picklepath == "":
+ Logger.warning("FAK Revert: Revert found no backup object for %s" % plugin)
+ else:
+ revert(picklepath, ps._plugins[plugin], report)