diff options
-rw-r--r-- | firstaidkit.spec | 1 | ||||
-rwxr-xr-x | firstaidkitrevert | 188 | ||||
-rw-r--r-- | plugins/grub/grub.py | 11 | ||||
-rw-r--r-- | plugins/grub/grubUtils.py | 8 | ||||
-rw-r--r-- | pyfirstaidkit/configuration.py | 2 | ||||
-rw-r--r-- | setup.py | 2 |
6 files changed, 204 insertions, 8 deletions
diff --git a/firstaidkit.spec b/firstaidkit.spec index 0848f43..7836608 100644 --- a/firstaidkit.spec +++ b/firstaidkit.spec @@ -192,6 +192,7 @@ desktop-file-install --vendor="fedora" --dir=${RPM_BUILD_ROOT}%{_datadir}/applic %{python_sitelib}/pyfirstaidkit %{python_sitelib}/%{name}-%{version}-py2.5.egg-info %{_bindir}/firstaidkit +%{_bindir}/firstaidkitrevert %config(noreplace) %{_sysconfdir}/firstaidkit/firstaidkit.conf %{_sysconfdir}/firstaidkit/about %attr(0644,root,root) %{_mandir}/man1/firstaidkit.1.gz 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) diff --git a/plugins/grub/grub.py b/plugins/grub/grub.py index feafaf5..7fcb586 100644 --- a/plugins/grub/grub.py +++ b/plugins/grub/grub.py @@ -39,6 +39,10 @@ class Grub(Plugin): def getDeps(cls): return set(["root", "experimental", "filesystem"]) + @classmethod + def revert(cls, backup, report): + report.info("Executing revert", origin = Grub) + def __init__(self, *args, **kwargs): Plugin.__init__(self, *args, **kwargs) @@ -61,10 +65,11 @@ class Grub(Plugin): self.issue_grub_image = SimpleIssue(self.name, "Bad grub stage1 image.") # Initialize the backup space. - self.backupSpace = self._backups.getBackup(str(self), persistent = True) + self.backupSpace = self._backups.getBackup( \ + self.__module__.split('.')[-1:][0], persistent = True) # Parce the parameters passed to the plugin. - self.args = gurbUtils.get_grub_opts(self._args) + self.args = grubUtils.get_grub_opts(self._args) def prepare(self): self._reporting.info("Initializing the search for all the grub " \ @@ -146,7 +151,7 @@ class Grub(Plugin): # Now we see if we can install in the partitions. for part in parts: if grubUtils.other_bootloader_present(Dname(part)): - self._reporting.info("Found no other bootloader in " \ + self._reporting.info("Found no other bootloader in " \ "%s partition." % Dname.asPath(part), \ origin = self) self.install_grub_parts.append(Dname(part)) diff --git a/plugins/grub/grubUtils.py b/plugins/grub/grubUtils.py index 949730f..1519d72 100644 --- a/plugins/grub/grubUtils.py +++ b/plugins/grub/grubUtils.py @@ -252,7 +252,7 @@ def other_bootloader_present(dev): return False # We will have the list of all the tests in the tests variable. - tests = {none_grub} + tests = [none_grub] for test in tests: if test(dev): @@ -357,13 +357,13 @@ def get_grub_opts(args): # Create the object with the argument decision. class grub_args: - install_all = Flase + install_all = False install_to = [] retval = grub_args() # Parse the args string optsstr = "" - longotps = ["install-all", "install-to="] + longopts = ["install-all", "install-to="] try: (opts, vals) = getopt.getopt( args.split(), optsstr, longopts ) except: @@ -477,7 +477,7 @@ class Dname: openpar = "" closepar = "" - # Create the gurb device string. + # Create the grub device string. if partnum == None: return "%shd%s%s"%(openpar, devnum, closepar) else: diff --git a/pyfirstaidkit/configuration.py b/pyfirstaidkit/configuration.py index b25bf1b..01f4ac7 100644 --- a/pyfirstaidkit/configuration.py +++ b/pyfirstaidkit/configuration.py @@ -46,6 +46,8 @@ def createDefaultConfig(config): config.backup.method = "file" config.backup.rootpath = "/tmp/fakbackup" config.backup.fullpath = "" + config.revert.all = "False" + config.revert.dir = "" # Setup a sane default root directory. if os.path.isdir("/mnt/sysimage"): @@ -8,6 +8,6 @@ setup(name='firstaidkit', url='http://fedorahosted.org/firstaidkit', license='GPLv2+', packages = ['pyfirstaidkit', 'pyfirstaidkit/utils'], - scripts = ['firstaidkit'] + scripts = ['firstaidkit', 'firstaidkitrevert'] ) |