import gzip
import shutil
import time
+import locale
from subprocess import Popen, PIPE
from .cfg_app import PpCfgAppError, PpConfigApplication
-__version__ = '0.5.1'
+__version__ = '0.5.2'
LOG = logging.getLogger(__name__)
UTC = datetime.timezone.utc
# -------------------------------------------------------------------------
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)
'gecos': dir_owner,
}
check['data'][home_rel] = result
- if i > 10:
- break
end_ts = datetime.datetime.now(UTC)
duration = end_ts - self.now
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)
self.status_data['last_check'] = self.now
self.write_status_data()
+
# =============================================================================
if __name__ == "__main__":