From b8ed5d1005a0b0407c45703e4758f9a8d26e4b03 Mon Sep 17 00:00:00 2001 From: Michel Albert Date: Thu, 5 Apr 2012 14:42:16 +0200 Subject: [PATCH] Initial commit of pypmmn A port of pmmn to python. * Currently only handles text from stdin (as with pmmn). * The location of the ``plugins_folder`` is currently hardcoded. * No command line arguments parsed yet. --- tools/pypmmn/README.rst | 33 +++++++++ tools/pypmmn/pypmmn/__init__.py | 0 tools/pypmmn/pypmmn/pypmmn.py | 126 ++++++++++++++++++++++++++++++++ tools/pypmmn/setup.py | 23 ++++++ 4 files changed, 182 insertions(+) create mode 100644 tools/pypmmn/README.rst create mode 100644 tools/pypmmn/pypmmn/__init__.py create mode 100644 tools/pypmmn/pypmmn/pypmmn.py create mode 100644 tools/pypmmn/setup.py diff --git a/tools/pypmmn/README.rst b/tools/pypmmn/README.rst new file mode 100644 index 00000000..493fc081 --- /dev/null +++ b/tools/pypmmn/README.rst @@ -0,0 +1,33 @@ +PyPMMN +====== + +PyPMMN is a pure python port of pmmn_. + +Requirements +============ + +PyPMMN does not have any requirements other than the python standard library. +For compatibility, it's targeted for Python 2.4 and up. + +Installation +============ + +The python way +-------------- + +Download the folder and run:: + + python setup.py install + +This will install ``pypmmn.py`` into your system's ``bin`` folder. Commonly, +this is ``/usr/local/bin``. + +Manually +-------- + +Download the folder and copy the file ``pypmmn/pypmmn.py`` to a location of +your choice and ensure it's executable. + + +.. _pmmn: http://blog.pwkf.org/post/2008/11/04/A-Poor-Man-s-Munin-Node-to-Monitor-Hostile-UNIX-Servers + diff --git a/tools/pypmmn/pypmmn/__init__.py b/tools/pypmmn/pypmmn/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tools/pypmmn/pypmmn/pypmmn.py b/tools/pypmmn/pypmmn/pypmmn.py new file mode 100644 index 00000000..086d4a59 --- /dev/null +++ b/tools/pypmmn/pypmmn/pypmmn.py @@ -0,0 +1,126 @@ +#!/usr/bin/python +from os.path import join, isdir +from subprocess import call +from os import listdir, access, X_OK +import sys + + +__version__ = '1.0dev1' + + +spoolfetch_dir = '' +plugin_dir = 'plugins' +host = 'hostname' + + +class CmdHandler(object): + + def __init__(self, out_stream): + self.out_stream = out_stream + + def do_version(self, arg): + """ + Prints the version of this instance. + """ + self.out_stream.write('pypmmn on %s version: %s' % (host, + __version__)) + + def do_nodes(self, arg): + """ + Prints this hostname + """ + self.out_stream.write('%s\n' % host) + self.out_stream.write('.') + + def do_quit(self, arg): + """ + Stops this process + """ + sys.exit(0) + + def do_list(self, arg): + """ + Print a list of plugins + """ + try: + for filename in listdir(plugin_dir): + if not access(join(plugin_dir, filename), X_OK): + continue + self.out_stream.write("%s " % filename) + except OSError, exc: + sys.stdout.writte("# ERROR: %s" % exc) + + def _caf(self, arg, cmd): + """ + handler for ``config``, ``alert`` and ``fetch`` + Calls the plugin with ``cmd`` as only argument. + """ + plugin_filename = join(plugin_dir, arg) + if isdir(plugin_filename) or not access(plugin_filename, X_OK): + self.out_stream.write("# Unknown plugin [%s] for %s" % (arg, cmd)) + return + + if cmd == 'fetch': + arg_plugin = '' + else: + arg_plugin = cmd + + try: + call([plugin_filename, arg_plugin]) + except OSError, exc: + self.out_stream.write("# ERROR: %s" % exc) + return + self.out_stream.write('.') + + def do_alert(self, arg): + self._caf(arg, 'alert') + + def do_fetch(self, arg): + self._caf(arg, 'fetch') + + def do_config(self, arg): + self._caf(arg, 'config') + + def do_cap(self, arg): + self.out_stream.write("cap ") + if spoolfetch_dir: + self.out_stream.write("spool ") + + def do_spoolfetch(self, arg): + call(['%s/spoolfetch_%s' % (spoolfetch_dir, host), arg]) + self.out_stream.write('.') + + # aliases + do_exit = do_quit + + +def handle_input(in_stream, handler, out_stream): + for line in in_stream: + line = line.strip() + line = line.split(' ') + cmd = line[0] + if len(line) == 1: + arg = '' + elif len(line) == 2: + arg = line[1] + else: + raise ValueError('Invalid input: %s' % line) + + if not cmd: + continue + + func = getattr(handler, 'do_%s' % cmd, None) + if not func: + commands = [_[3:] for _ in dir(handler) if _.startswith('do_')] + print "# Unknown command. Supported commands: %s" % commands + sys.exit(1) + + func(arg) + out_stream.write('\n') + + +def main(): + handle_input(sys.stdin, CmdHandler(sys.stdout), sys.stdout) + +if __name__ == '__main__': + main() diff --git a/tools/pypmmn/setup.py b/tools/pypmmn/setup.py new file mode 100644 index 00000000..c07951c7 --- /dev/null +++ b/tools/pypmmn/setup.py @@ -0,0 +1,23 @@ +from distutils.core import setup +from pypmmn.pypmmn import __version__ + +PACKAGE = "pypmmn" +NAME = "pypmmn" +DESCRIPTION = "Python port of the 'Poor man's munin-node'" +AUTHOR = "Michel Albert" +AUTHOR_EMAIL = "michel@albert.lu" + +setup( + name=NAME, + version=__version__, + description=DESCRIPTION, + long_description=open("README.rst").read(), + author=AUTHOR, + author_email=AUTHOR_EMAIL, + license="BSD", + include_package_data=True, + packages=['pypmmn'], + scripts=['pypmmn/pypmmn.py'], + zip_safe=False, +) +