summaryrefslogtreecommitdiffstats
path: root/plugins/p_mdadm_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/p_mdadm_config.py')
-rw-r--r--plugins/p_mdadm_config.py192
1 files changed, 192 insertions, 0 deletions
diff --git a/plugins/p_mdadm_config.py b/plugins/p_mdadm_config.py
new file mode 100644
index 0000000..55bb6be
--- /dev/null
+++ b/plugins/p_mdadm_config.py
@@ -0,0 +1,192 @@
+# 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.backupSpace = self._backups.getBackup(str(self))
+ 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 = "mdadm", 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.scannedFile = 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
+ self._issue.set(checked=True, happened=False,
+ reporting=self._reporting, level=PLUGIN, origin=self)
+ return
+
+ # If nothing is detected the result is successfull.
+ self._result = ReturnSuccess
+
+ # 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 mdadm.conf is " \
+ "missing: %s."%value, level = PLUGIN, origin = self)
+ self._result = ReturnFailure
+
+ # 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
+
+ if self._result == ReturnSuccess:
+ self._reporting.info("There was no problem found with the " \
+ "current mdadm.conf file.", level = PLUGIN, origin = self)
+
+ self._issue.set(checked = True,
+ happened = (self._result == ReturnFailure),
+ reporting = self._reporting, level = PLUGIN, origin = self)
+
+ def backup(self):
+ if os.path.isfile(self.configFile):
+ self._reporting.info("Making a backup of %s."%
+ self.configFile, level = PLUGIN, origin = self)
+ self.backupSpace.backupPath(self.configFile)
+
+ 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._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("# File created by Firstaidkit.\n")
+ fd.write("# DEVICE partitions\n")
+ fd.write("# MAILADDR root\n")
+ 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,
+ self.configFile+".firstaidkit"), level=PLUGIN,
+ origin=self)
+ self.backupSpace.restoreName(self.configFile,
+ path = self.configFile+".firstaidkit")
+ 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 not self.backupSpace.exists(self.configFile):
+ # 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)
+ else:
+ self._reporting.info("Restoring original file.", level = PLUGIN ,
+ origin = self)
+ self.backupSpace.restoreName(self.configFile)
+ self._result = ReturnSuccess
+
+ def clean(self):
+ self._result = ReturnSuccess
+
+def get_plugin():
+ return MdadmConfig
+