From ca9987f399217e6d163a0aaf4b80fb08329e441c Mon Sep 17 00:00:00 2001 From: "Rob Kendrick (humdrum)" Date: Thu, 13 Feb 2014 09:40:56 +0000 Subject: Trove Overseer initial work, and plugins --- overseerlib/__init__.py | 24 --------- overseerlib/app.py | 99 ---------------------------------- overseerlib/mailnotify.py | 44 --------------- overseerlib/parseyaml.py | 34 ------------ overseerlib/plugins/__init__.py | 0 overseerlib/plugins/diskfree_plugin.py | 48 ----------------- overseerlib/plugins/ramfree_plugin.py | 53 ------------------ tests/diskfree | 8 +++ tests/git | 7 +++ tests/http | 3 ++ tests/loadavg | 9 ++++ tests/memfree | 3 ++ tests/morphcache | 31 +++++++++++ 13 files changed, 61 insertions(+), 302 deletions(-) delete mode 100644 overseerlib/__init__.py delete mode 100644 overseerlib/app.py delete mode 100644 overseerlib/mailnotify.py delete mode 100644 overseerlib/parseyaml.py delete mode 100644 overseerlib/plugins/__init__.py delete mode 100644 overseerlib/plugins/diskfree_plugin.py delete mode 100644 overseerlib/plugins/ramfree_plugin.py create mode 100755 tests/diskfree create mode 100755 tests/git create mode 100755 tests/http create mode 100755 tests/loadavg create mode 100755 tests/memfree create mode 100755 tests/morphcache diff --git a/overseerlib/__init__.py b/overseerlib/__init__.py deleted file mode 100644 index 49d9ad0..0000000 --- a/overseerlib/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import cliapp - -import parseyaml -import mailnotify - -import app diff --git a/overseerlib/app.py b/overseerlib/app.py deleted file mode 100644 index dc3e811..0000000 --- a/overseerlib/app.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import os -import smtplib -import getpass - -import cliapp - -import overseerlib - - -defaults = { - 'work-area': '/home/trove-overseer', - 'config-name': 'monitoring.conf', -} - - -class TroveOverseer(cliapp.Application): - - def add_settings(self): - self.settings.string(['work-area'], - 'path to the area for the controller to work in', - metavar='PATH', - default=defaults['work-area']) - self.settings.string(['config-name'], 'configuration file name. ' - 'Defaults to monitoring.conf', - metavar='FILENAME', - default=defaults['config-name']) - - def process_args(self, args): - self.rungit(['remote', 'update', 'origin']) - self.rungit(['reset', '--hard', 'origin/master']) - self.rungit(['clean', '-fdx']) - config = os.path.join(self.settings['work-area'], 'git', - self.settings['config-name'])) - overseerlib.parseyaml.ParseYAML.load_config(config) - - cliapp.Application.process_args(self, args) - - def human_to_bytes(self, threshold): - symbols = ('B', 'K', 'M', 'G', 'T') - s = threshold - letter = s[-1:].strip().upper() - num = s[:-1] - if letter not in symbols: - raise cliapp.AppException('Valid symbols: B, K, M, G, T') - num = float(num) - prefix = {symbols[0]:1} - for i, s in enumerate(symbols[1:]): - prefix[s] = 1 << (i+1)*10 - return int(num * prefix[letter]) - - def rungit(self, args): - self.runcmd(['git']+args, cwd=os.path.join(self.settings['work-area'], - 'git')) - - def write_to_html(self, html_file): - if html_file: - try: - with open(html_file + '.new', 'w') as ofh: - ofh.write('\n') - ofh.write(self.gen_html()) - ofh.write('\n') - target = filename - os.rename(filename + '.new', target) - except: - os.unlink(filename + '.new') - raise - - def gen_footer(self): - curtime = format_time(time.time()) - return self.tag('div', Class='footer', content= - 'Generated by Trove Monitoring at ' + curtime) - - def tag(self, tagname, content=None, gap=False, **kwargs): - tagval = ' '.join([tagname] + - ['%s=%r' % (k.lower(), v) - for k, v in kwargs.iteritems()]) - gap = '\n' if gap else '' - if content is None: - return '<%s />' % tagval - else: - return '<%s>%s%s%s' % (tagval, gap, content, gap, tagname) diff --git a/overseerlib/mailnotify.py b/overseerlib/mailnotify.py deleted file mode 100644 index 1be0132..0000000 --- a/overseerlib/mailnotify.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import smtplib -import getpass - -import cliapp - - -class MailNotify(object): - - def send_mail(self, content): - sender = 'ben.brown@codethink.co.uk' - username = 'benbrown' - password = getpass.getpass() - recipients = ['ben.brown@codethink.co.uk'] - composed_message = '''\ -From: %s -To: %s -Subject: Test - -%s - ''' % (sender, ', '.join(recipients), content) - server = smtplib.SMTP_SSL('imap.codethink.co.uk') - server.login(username, password) - try: - server.sendmail(sender, recipients, composed_message) - finally: - server.close diff --git a/overseerlib/parseyaml.py b/overseerlib/parseyaml.py deleted file mode 100644 index 8aacfa7..0000000 --- a/overseerlib/parseyaml.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import yaml - -import cliapp - - -class ParseYAML(object): - - def load_config(self, config): - with open(config) as f: - text = f.read() - try: - obj = yaml.safe_load(text) - except yaml.error.YAMLError as e: - raise cliapp.AppException('Could not load configuration file') - - return obj diff --git a/overseerlib/plugins/__init__.py b/overseerlib/plugins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/overseerlib/plugins/diskfree_plugin.py b/overseerlib/plugins/diskfree_plugin.py deleted file mode 100644 index d0de752..0000000 --- a/overseerlib/plugins/diskfree_plugin.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import os - -import cliapp - -import overseerlib - - -class DiskFreePlugin(cliapp.Plugin): - - def enable(self): - self.app.add_subcommand('diskfree', self.diskfree, - arg_synopsis='PARTITION THRESHOLD') - - def disable(self): - pass - - def diskfree(self, args): - if len(args) < 2: - raise cliapp.AppException('diskfree needs a partition and a ' - 'threshold to be specified') - partition = args[0] - threshold = args[1] - threshold_type = args[2] if len(args) == 3 else 'high' - - if threshold.isdigit() == False: - threshold = self.app.human_to_bytes(threshold) - - st = os.statvfs(partition) - free = st.f_bavail * st.f_frsize - print free diff --git a/overseerlib/plugins/ramfree_plugin.py b/overseerlib/plugins/ramfree_plugin.py deleted file mode 100644 index b1161ee..0000000 --- a/overseerlib/plugins/ramfree_plugin.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2014 Codethink Limited -# -# 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; version 2 of the License. -# -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import cliapp - -import overseerlib - - -class RamFreePlugin(cliapp.Plugin): - - def enable(self): - self.app.add_subcommand('ramfree', self.ramfree, - arg_synopsis='THRESHOLD') - - def disable(self): - pass - - def ramfree(self, args): - if len(args) < 1: - raise cliapp.AppException('ramfree requires a threshold to be ' - 'specified') - threshold = args[0] - threshold_type = args[1] if len(args) == 2 else 'high' - - if threshold.isdigit() == False: - threshold = overseerlib.app.human_to_bytes(threshold) - - with open('/proc/meminfo') as f: - for line in f: - if line.startswith('MemFree'): - free = line.split()[1] - free = int(free) * 1024 - - message = '' - if free >= threshold: - message+=('%s bytes of memory free\n' % free) - if message != '': - print message diff --git a/tests/diskfree b/tests/diskfree new file mode 100755 index 0000000..d6d29b5 --- /dev/null +++ b/tests/diskfree @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "x$1" = "x" ]; then + echo expected partition as first argument + exit 1 +fi + +df -P $1 | tail -n1 | awk '{ print $4 * 1024 }' diff --git a/tests/git b/tests/git new file mode 100755 index 0000000..adcecd8 --- /dev/null +++ b/tests/git @@ -0,0 +1,7 @@ +#!/bin/sh + +TEMPDIR=$(mktemp -d) || exit 1 + +git clone --quiet --no-checkout $1 $TEMPDIR || exit 2 + +rm -rf $TEMPDIR diff --git a/tests/http b/tests/http new file mode 100755 index 0000000..a9b2f1d --- /dev/null +++ b/tests/http @@ -0,0 +1,3 @@ +#!/bin/sh + +exec wget --quiet -O /dev/null $1 diff --git a/tests/loadavg b/tests/loadavg new file mode 100755 index 0000000..ad99506 --- /dev/null +++ b/tests/loadavg @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ "x$1" = "x" ]; then + POS=1 +else + POS=$1 +fi + +cut -d' ' -f$POS /proc/loadavg diff --git a/tests/memfree b/tests/memfree new file mode 100755 index 0000000..21bc619 --- /dev/null +++ b/tests/memfree @@ -0,0 +1,3 @@ +#!/bin/sh + +grep "^MemFree:" /proc/meminfo | awk ' { print $2 * 1024 } ' diff --git a/tests/morphcache b/tests/morphcache new file mode 100755 index 0000000..1b355b0 --- /dev/null +++ b/tests/morphcache @@ -0,0 +1,31 @@ +#!/bin/bash + +if [ "$#" -ne 4 ]; then + echo usage: $0 CACHE_SERVER_IP REPO REF FILENAME + exit 1 +fi + +rawurlencode() { + local string="${1}" + local strlen=${#string} + local encoded="" + + for (( pos=0 ; pos