From: Frank Brehm Date: Fri, 24 Mar 2017 15:54:00 +0000 (+0100) Subject: Completing pp_lib/quota_check.py X-Git-Tag: 0.1.2~216 X-Git-Url: https://git.uhu-banane.de/?a=commitdiff_plain;h=809ce2559b49a358c453384dd9dfdbf79cb5daa5;p=pixelpark%2Fadmin-tools.git Completing pp_lib/quota_check.py --- diff --git a/etc/test-home.ini.default b/etc/test-home.ini.default index 46b40e9..bb82a6f 100644 --- a/etc/test-home.ini.default +++ b/etc/test-home.ini.default @@ -18,6 +18,11 @@ # Must be valid Mail addresses #reply_to = frank.brehm@pixelpark.com +# A single complete mail address to use for the +# sender address, if not given, will be generated by the complete username +# of the executing user (gecos) and the FQDN of the current host +#mail_from = Root + # The method to send the mail. Valid values are: # * smtp - the mail is sent via SMTP to a given MTA #mail_method = smtp | sendmail diff --git a/pp_lib/global_version.py b/pp_lib/global_version.py index 9b2b2b2..40df3d4 100644 --- a/pp_lib/global_version.py +++ b/pp_lib/global_version.py @@ -9,7 +9,7 @@ __author__ = 'Frank Brehm ' __contact__ = 'frank.brehm@pixelpark.com' -__version__ = '0.4.1' +__version__ = '0.4.2' __license__ = 'LGPL3+' # vim: fileencoding=utf-8 filetype=python ts=4 diff --git a/pp_lib/quota_check.py b/pp_lib/quota_check.py index 7c9d2b1..24e8631 100644 --- a/pp_lib/quota_check.py +++ b/pp_lib/quota_check.py @@ -25,6 +25,7 @@ import pipes import gzip import shutil import time +import locale from subprocess import Popen, PIPE @@ -41,7 +42,7 @@ from .common import pp, terminal_can_colors, to_bytes, to_bool, to_str from .cfg_app import PpCfgAppError, PpConfigApplication -__version__ = '0.5.1' +__version__ = '0.5.2' LOG = logging.getLogger(__name__) UTC = datetime.timezone.utc @@ -75,6 +76,13 @@ class PpQuotaCheckApp(PpConfigApplication): # ------------------------------------------------------------------------- def __init__(self, appname=None, version=__version__): + self.default_mail_recipients = [ + 'admin.berlin@pixelpark.com' + ] + self.default_mail_cc = [] + + self.default_reply_to = 'noreply@pixelpark.com' + self.chroot_homedir = self.default_chroot_homedir self.home_root_abs = self.default_home_root self.home_root_rel = os.path.relpath(self.home_root_abs, os.sep) @@ -515,8 +523,6 @@ class PpQuotaCheckApp(PpConfigApplication): 'gecos': dir_owner, } check['data'][home_rel] = result - if i > 10: - break end_ts = datetime.datetime.now(UTC) duration = end_ts - self.now @@ -548,28 +554,99 @@ class PpQuotaCheckApp(PpConfigApplication): check['stats']['total_gb'] = float(total_kb) / 1024.0 / 1024.0 # ------------------------------------------------------------------------- - def send_results(self): - - if not self.unnecessary_dirs: - LOG.debug("No unnecessary home directories, nothing to inform.") - return - - subject = 'Nicht benötigte Home-Verzeichnisse' - body = textwrap.dedent('''\ - Die folgenden Home-Verzeichnisse befinden sich weder - in der lokalen passwd-Datei, im LDAP oder in der exclude-Liste. - Sie können damit archiviert und gelöscht werden.''') - body += '\n\n' - for home in self.unnecessary_dirs: - body += ' - ' + home + '\n' + def send_results(self, total_dirs_top): + + locale_conv = locale.localeconv() + dp = ',' + ts = '.' + if 'decimal_point' in locale_conv and locale_conv['decimal_point'] != '.': + dp = locale_conv['decimal_point'] + if 'thousands_sep' in locale_conv: + ts = locale_conv['thousands_sep'] + + subject = "Quota weekly summary (>= {:.0f} MB)".format(self.quota_kb / 1024) + + body = "Hallo Berlin dudes!\n\n" + + if total_dirs_top.keys(): + + max_len_home = 2 + max_len_size = 4 + for home in total_dirs_top.keys(): + if len(home) > max_len_home: + max_len_home = len(home) + size = total_dirs_top[home]['util_kb_avg'] / 1024 + size_out = "{:,.0f} MB".format(size) + size_out = size_out.replace('.', ';').replace(',', ts).replace(';', dp) + if len(size_out) > max_len_size: + max_len_size = len(size_out) + + for home in sorted( + total_dirs_top.keys(), + key=lambda x: total_dirs_top[x]['util_kb_avg'], + reverse=True): + size = total_dirs_top[home]['util_kb_avg'] / 1024 + user = total_dirs_top[home]['user'] + gecos = total_dirs_top[home]['gecos'] + size_out = "{:,.0f} MB".format(size) + size_out = size_out.replace('.', ';').replace(',', ts).replace(';', dp) + line = " * {h:<{wh}} - {s:>{ws}} ({u} -> {g})\n".format( + h=home, wh=max_len_home, s=size_out, ws=max_len_size, u=user, g=gecos) + body += line + + else: + + body += ("No home directory found with a recursive size " + "greater or equal than {:.f} MB.").format( + self.quota_kb / 1024) + + body += "\n\n" + self.mail_from + '\n' + + LOG.debug("Subject: {!r}".format(subject)) + LOG.debug("Body:\n{}".format(body)) self.send_mail(subject, body) # ------------------------------------------------------------------------- def perform_statistics(self): - - + if 'checks' in self.status_data and len(self.status_data['checks'].keys()): + total_dirs = {} + for check_date in self.status_data['checks'].keys(): + check = self.status_data['checks'][check_date] + if not 'data' in check or not check['data'].keys(): + continue + # Consolidating data ... + for home in check['data'].keys(): + pdata = check['data'][home] + old_kb = 0 + nr_checks = 0 + if home in total_dirs: + old_kb = total_dirs[home]['util_kb'] + nr_checks = total_dirs[home]['nr_checks'] + nr_checks += 1 + util_kb = old_kb + pdata['util_kb'] + total_dirs[home] = { + 'gecos': pdata['gecos'], + 'gid': pdata['gid'], + 'uid': pdata['uid'], + 'user': pdata['user'], + 'util_kb': util_kb, + 'nr_checks': nr_checks, + 'util_kb_avg': util_kb / nr_checks, + } + + total_dirs_top = {} + for home in total_dirs.keys(): + if total_dirs[home]['util_kb_avg'] < self.quota_kb: + continue + total_dirs_top[home] = total_dirs[home] + del total_dirs + + if self.verbose > 1: + LOG.debug("Got top home directories:\n{}".format(pp(total_dirs_top))) + + self.send_results(total_dirs_top) # Rotate status file and rewrite an empty status file self.rotate_status_file(self.now) @@ -577,6 +654,7 @@ class PpQuotaCheckApp(PpConfigApplication): self.status_data['last_check'] = self.now self.write_status_data() + # ============================================================================= if __name__ == "__main__": diff --git a/pp_lib/test_home_app.py b/pp_lib/test_home_app.py index 04021e3..1c89a69 100644 --- a/pp_lib/test_home_app.py +++ b/pp_lib/test_home_app.py @@ -32,7 +32,7 @@ from .common import pp, terminal_can_colors, to_bytes, to_bool from .cfg_app import PpCfgAppError, PpConfigApplication -__version__ = '0.4.3' +__version__ = '0.4.4' LOG = logging.getLogger(__name__) @@ -60,6 +60,13 @@ class PpTestHomeApp(PpConfigApplication): # ------------------------------------------------------------------------- def __init__(self, appname=None, version=__version__): + self.default_mail_recipients = [ + 'admin.berlin@pixelpark.com' + ] + self.default_mail_cc = [] + + self.default_reply_to = 'noreply@pixelpark.com' + self.chroot_homedir = self.default_chroot_homedir self.home_root_abs = self.default_home_root self.home_root_rel = os.path.relpath(self.home_root_abs, os.sep)