From bc86a4878025a507a3c4582befe87927b30e9862 Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Wed, 11 Aug 2010 14:00:14 +0200 Subject: Add FreeSpace plugin --- plugins/freespace.py | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 plugins/freespace.py diff --git a/plugins/freespace.py b/plugins/freespace.py new file mode 100644 index 0000000..1bcc0ed --- /dev/null +++ b/plugins/freespace.py @@ -0,0 +1,143 @@ +# First Aid Kit - diagnostic and repair tool for Linux +# Copyright (C) 2007 Martin Sivak +# +# 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 os +import shutil + +from pyfirstaidkit.plugins import Plugin,Flow +from pyfirstaidkit.reporting import PLUGIN +from pyfirstaidkit.returns import * +from pyfirstaidkit.issue import SimpleIssue + +class FreeSpacePlugin(Plugin): + """Plugin to detect insufficient free space in /var directory.""" + name = "Free Space" + version = "0.0.1" + author = "Tomas Mlcoch" + description = "Detects insufficient free space in /var directory." + + directory = '/var' + del_dirs = ['/var/tmp',] # All content of this files will be + # removed (deleted) in "fix" step. + + @classmethod + def getDeps(cls): + return set(["root", "filesystem"]) + + def __init__(self, *args, **kwargs): + Plugin.__init__(self, *args, **kwargs) + self._issue = SimpleIssue(self.name, self.description) + + def _reporter(self, msg): + self._reporting.info(msg, origin=self, level=PLUGIN) + + def prepare(self): + self._issue.set(reporting=self._reporting, origin=self, level=PLUGIN) + self._result=ReturnSuccess + + def diagnose(self): + + # statvfs stucture: + # ----------------- + # f_bsize File system block size. + # f_frsize Fundamental file system block size (fragment size). + # f_blocks Total number of blocks on the file system, in units of f_frsize. + # f_bfree Total number of free blocks. + # f_bavail Total number of free blocks available to non-privileged processes. + # f_files Total number of file nodes (inodes) on the file system. + # f_ffree Total number of free file nodes (inodes). + # f_favail Total number of free file nodes (inodes) available to non-privileged processes. + # f_flag File system ID number. + # f_namemax Maximum length of a file name (path element). + + # stat structure: + # --------------- + # st_dev device + # st_ino inode + # st_mode protection + # st_nlink number of hard links + # st_uid user ID of owner + # st_gid group ID of owner + # st_rdev device type (if inode device) + # st_size total size, in bytes + # st_blksize blocksize for filesystem I/O + # st_blocks number of blocks allocated + # st_atime time of last access + # st_mtime time of last modification + # st_ctime time of last change + + # Get freespace + stats = os.statvfs(self.directory) + freespace = stats.f_bavail * stats.f_frsize / 1048576 # Freespace in Mb + + # Get freeable space + self.freeable = 0 + for dir in self.del_dirs: + stats_fa = os.statvfs(dir) + for root, dirs, files in os.walk(dir): + for d in dirs: + self.freeable += os.stat(os.path.join(root, d)).st_size + for f in files: + self.freeable += os.stat(os.path.join(root, f)).st_size + self.freeable /= 1024 + + # Analyse results + if freespace < 1: + lhappened = True + self._reporter("Free space seems to be insufficient.") + self._reporter("Freeable space: %s Kb" % self.freeable) + self._result=ReturnFailure + else: + lhappened = False + self._reporter("Free space seems to be sufficient.") + self._result=ReturnSuccess + + self._issue.set(checked=True, happened=lhappened, + reporting=self._reporting, origin=self, level=PLUGIN) + + def backup(self): + self._result=ReturnSuccess + + def restore(self): + self._result=ReturnSuccess + + def fix(self): + try: + for dir in self.del_dirs: + self._reporter("Deleting content of: %s" % dir) + for root, dirs, files in os.walk(dir): + for d in dirs: + shutil.rmtree(os.path.join(root, d)) + for f in files: + os.unlink(os.path.join(root, f)) + except (Exception) as e: + self._reporter("Exception: %s" % e) + self._result=ReturnFailure + else: + self._result=ReturnSuccess + self._reporter("Fix successfully complete! (Freed space: %s Kb)" \ + % self.freeable) + + self._issue.set(fixed=(self._result == ReturnSuccess), + reporting=self._reporting, origin=self, level=PLUGIN) + + def clean(self): + self._result=ReturnSuccess + +def get_plugin(): + return FreeSpacePlugin + -- cgit