diff options
author | Joel Andres Granados <jgranado@redhat.com> | 2008-06-06 14:11:25 +0200 |
---|---|---|
committer | Joel Andres Granados <jgranado@redhat.com> | 2008-06-06 14:11:25 +0200 |
commit | 1ff467a036c75da807fff4f8924d7cbadc97e794 (patch) | |
tree | a9e1d684cb42d5ec3792fbd7ca1d44725373f5a2 | |
parent | 65f06cb0a0324dcbb1f238918f33f62ddbf4d69a (diff) | |
download | firstaidkit-1ff467a036c75da807fff4f8924d7cbadc97e794.tar.gz firstaidkit-1ff467a036c75da807fff4f8924d7cbadc97e794.tar.xz firstaidkit-1ff467a036c75da807fff4f8924d7cbadc97e794.zip |
New mdadm configuration plugin.
-rw-r--r-- | firstaidkit.spec | 15 | ||||
-rw-r--r-- | plugins/plugin_mdadmconf.py | 160 |
2 files changed, 175 insertions, 0 deletions
diff --git a/firstaidkit.spec b/firstaidkit.spec index 6043e4e..3a8d4fc 100644 --- a/firstaidkit.spec +++ b/firstaidkit.spec @@ -45,6 +45,7 @@ Requires: %{name}-plugin-xserver Requires: %{name}-plugin-grub Requires: %{name}-plugin-rpm Requires: %{name}-gui +Requires: %{name}-mdadmconf %description plugin-all @@ -99,6 +100,16 @@ Summary: FirstAidKit plugin to diagnose or repair the RPM packaging syste Requires: %{name} = %{version}-%{release} Requires: rpm, rpm-python +%package plugin-mdadmconf +Group: Applications/System +Summary: Firstaidkit plugin to diagnose software raid configuration file +Requires: %{name} = %{version}-%{release} +Requires: mdadm + +%description plugin-mdadmconf +This plugin will assess the validity and existence of the mdadm.conf file. +The file will get replaced if any inconsistencies are found. + %description plugin-rpm This FirstAidKit plugin automates the tasks related to RPM problems. For example: corrupted database or important system packages missing. @@ -159,6 +170,7 @@ echo "copying=%{_docdir}/%{name}-%{version}/COPYING" >> etc/firstaidkit/about %{__cp} -f plugins/plugin_rpm_lowlevel/*.py $RPM_BUILD_ROOT%{_libdir}/firstaidkit/plugins/plugin_rpm_lowlevel/ %{__cp} -f plugins/plugin_grub.py $RPM_BUILD_ROOT%{_libdir}/firstaidkit/plugins/ %{__install} -p etc/firstaidkit/firstaidkit-plugin-grub $RPM_BUILD_ROOT%{_sysconfdir}/firstaidkit +%{__cp} -f plugins/plugin_mdadmconf.py $RPM_BUILD_ROOT%{_libdir}/firstaidkit/plugins/ %clean @@ -202,3 +214,6 @@ echo "copying=%{_docdir}/%{name}-%{version}/COPYING" >> etc/firstaidkit/about %files plugin-grub %{_libdir}/firstaidkit/plugins/plugin_grub.py* %{_sysconfdir}/firstaidkit/firstaidkit-plugin-grub + +%files plugin-mdadmconf +%{_libdir}/firstaidkit/plugins/plugin_mdadmconf.py* diff --git a/plugins/plugin_mdadmconf.py b/plugins/plugin_mdadmconf.py new file mode 100644 index 0000000..8f101c7 --- /dev/null +++ b/plugins/plugin_mdadmconf.py @@ -0,0 +1,160 @@ +# First Aid Kit - diagnostic and repair tool for Linux +# Copyright (C) 2008 Joel Andres 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. + +from pyfirstaidkit.plugins import Plugin,Flow +from pyfirstaidkit.returns import * +from pyfirstaidkit.utils import * +from pyfirstaidkit.reporting import PLUGIN +from pyfirstaidkit.issue import SimpleIssue +from pyfirstaidkit import Config +from pyfirstaidkit.errors import * + +import os.path + +class MdadmConfig(Plugin): + """ Addresses the validity and presence of /etc/mdadm.conf """ + flows = Flow.init(Plugin) + name = "mdadm configuration" + version = "0.0.1" + author = "Joel Andres Granados" + + @classmethod + def getDeps(cls): + return set(["root", "experimental", "filesystem"]) + + def __init__(self, *args, **kwargs): + Plugin.__init__(self, *args, **kwargs) + self.currentFileDict = {} #what we read from /etc/mdadm.conf + self.scannedFileDict = {} #what `mdadm --misc --detail --scan` + self.scannedFile = None # what `mdadm --misc --detail --scan` returns + self.configFile = os.path.join(Config.system.root,"/etc/mdadm.conf") + self.backupName = None + self._issue = SimpleIssue(self.name, "mdadm.con misconfigured") + + def prepare(self): + # We read the configuration file if it exists + if os.path.exists(self.configFile): + self._reporting.info("Gathering information from %s."%self.configFile, level = PLUGIN, origin = self) + fd = open(self.configFile, "r") + for line in fd.readlines(): + splitline = line.strip("\n").split(" ") + if "ARRAY" in splitline: + self.currentFileDict[splitline[1]] = splitline + fd.close() + else: + self._reporting.info("File %s was not found."%self.configFile, level = PLUGIN, origin = self) + + # We execute the mdadm command + self._reporting.info("Scanning for software raid with mdadm.", level = PLUGIN, origin = self) + mdadmargs = ["--misc", "--detail", "--scan"] + proc = spawnvch(executable = "mdamd", args = mdadmargs, chroot = Config.system.root) + (out, err) = proc.communicate() + + if err == '': + # means that the command ran with no errors. + for line in out.__str__().split("\n"): + splitline = line.strip("\n").split(" ") + if "ARRAY" in splitline: + self.scannedFileDict[splitline[1]] = splitline + self.scannedFileDict = out + else: + # This should make the flow go to clean. If there is an error we should not trust what mdadm tells us. + self._reporting.info("The mdadm command had the following error:%s. The plugin will silently exit."%err, + level = PLUGIN, origin = self) + self._result = None + return + self._result = ReturnSuccess + self._issue.set(reporting = self._reporting, level = PLUGIN, origin = self) + + def diagnose(self): + # If nothing was returned by the mdadm command. we dont have software raid. + if len(self.scannedFileDict) == 0: + self._reporting.info("There was no sofware raid found by the mdadm command.... Nothing to do.", + level = PLUGIN, origin = self) + self._result = ReturnSuccess + return + + # If there is one difference between the configs, regarding the ARRAYS. We replace the config file. + # Lets check for missing arrays in the curren config file. + for key, value in self.scannedFileDict.iteritems(): + if not self.currentFileDict.has_key(key): + self._reporting.info("Found that the current mdamd.conf is missing %s."%value, level = PLUGIN, origin = self) + self._result = ReturnFailure + return + # Lets check for additional ARRAYS that should not be there. + for key, value in self.currentFileDict.iteritems(): + if not self.scannedFileDict.has_key(key): + self._reporting.info("The followint entry: %s, is in the config file but was not detected by mdadm."%value, + level = PLUGIN, origin = self) + self._result = ReturnFailure + return + + self._reporting.info("There was no problem found with the current mdadm.conf file.", level = PLUGIN, origin = self) + self._result = ReturnSuccess + + def backup(self): + if os.path.isfile(self.configFile): + self.backupName = "mdadmconf"+os.getpid() + self._reporting.info("Making a backup of %s."%self.configFile, level = PLUGIN, origin = self) + self._backups.backupPath(self.configFile, self.backupName) + else: + self._reporting.info("It appears that the file %s does not exist. No backup attempt will be made."%self.configFile, + level = PLUGIN, origin = self) + self._reporting.info("%s does not exist."%self.configFile, level = PLUGIN, origin = self) + self._result = ReturnSuccess + + def fix(self): + try: + self._reporting.info("Going to write configuration to %s."%self.configFile, level = PLUGIN, origin = self) + fd = open(self.configFile, "w") + fd.write(self.scannedFile) + fd.close() + self._reporting.info("Configuration file writen.", level = PLUGIN, origin = self) + # The original mdadm.conf will be restore to mdadm.conf.firstaidkit, just in case. + self._reporting.info("Will put the old mdadm.conf in %s."%os.path.join(Config.system.root,"etc/mdamd.conf"), + level = PLUGIN, origin = self) + self._backups.restoreName(self.backupName, os.path.join(Config.system.root,"/etc/mdamd.conf")) + self.result = ReturnSuccess + except IOError: + fd.close() + self._reporting.info("Error occurred while writing %s."%self.configFile, level = PLUGIN, origin = self) + self._result = ReturnFailure + self._issue.set(fixed = (self._result == ReturnSuccess), reporting = self._reporting, level = PLUGIN, origin = self) + + def restore(self): + if self.backupName is None: + # This is the case where there is no config file. + self._reporting.info("The backedup file was not present. Assuming that %s was ont present to begin with."% + self.configFile, level = PLUGIN, original = self) + self._result = ReturnSuccess + return + + try: + self._reporting.info("Restoring original file.", level = PLUGIN , origin = self) + self._backups.restoreName(self.backupName) + self._result = ReturnSuccess + except BackupException: + # This means that the backed up file was lost somewhere. + raise GeneralPluginException(self, "Very ugly inconsistency with the backup files.") + self._result = ReturnSuccess + + def clean(self): + self._result = ReturnSuccess + +def get_plugin(): + return MdadmConfig + |