diff options
author | Joel Andres Granados <jgranado@redhat.com> | 2008-10-22 18:50:13 +0200 |
---|---|---|
committer | Joel Andres Granados <jgranado@redhat.com> | 2008-10-24 15:01:04 +0200 |
commit | 1615b70e2fdd6e36d4050ee9c55aaf15a0501a6f (patch) | |
tree | a3279e24a0caf46016a724bac033befc37fa54c1 /firstaidkitrevert | |
parent | ac73d062f903c69b7475b124ee1549d6062aab25 (diff) | |
download | firstaidkit-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-x | firstaidkitrevert | 188 |
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) |