mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-05 16:58:59 +00:00
150 lines
5 KiB
Python
Executable file
150 lines
5 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
import os
|
|
import socket
|
|
import socketserver
|
|
import sys
|
|
import threading
|
|
import time
|
|
from subprocess import Popen, PIPE
|
|
|
|
PLUGIN_PATH = "/etc/munin/plugins"
|
|
|
|
def parse_args():
|
|
from optparse import OptionParser
|
|
parser = OptionParser()
|
|
parser.add_option("-p", "--pluginpath", dest="plugin_path",
|
|
help="path to plugins", default=PLUGIN_PATH)
|
|
(options, args) = parser.parse_args()
|
|
return options, args
|
|
|
|
|
|
def execute_plugin(path, cmd=""):
|
|
args = [path]
|
|
if cmd:
|
|
args.append(cmd)
|
|
p = Popen(args, stdout=PIPE)
|
|
output = p.communicate()[0]
|
|
return output
|
|
|
|
if os.name == 'posix':
|
|
def become_daemon(our_home_dir='.', out_log='/dev/null',
|
|
err_log='/dev/null', umask=0o22):
|
|
"Robustly turn into a UNIX daemon, running in our_home_dir."
|
|
# First fork
|
|
try:
|
|
if os.fork() > 0:
|
|
sys.exit(0) # kill off parent
|
|
except OSError as e:
|
|
sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
|
|
sys.exit(1)
|
|
os.setsid()
|
|
os.chdir(our_home_dir)
|
|
os.umask(umask)
|
|
|
|
# Second fork
|
|
try:
|
|
if os.fork() > 0:
|
|
os._exit(0)
|
|
except OSError as e:
|
|
sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
|
|
os._exit(1)
|
|
|
|
si = open('/dev/null', 'r')
|
|
so = open(out_log, 'a+', 0)
|
|
se = open(err_log, 'a+', 0)
|
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
|
# Set custom file descriptors so that they get proper buffering.
|
|
sys.stdout, sys.stderr = so, se
|
|
else:
|
|
def become_daemon(our_home_dir='.', out_log=None, err_log=None, umask=0o22):
|
|
"""
|
|
If we're not running under a POSIX system, just simulate the daemon
|
|
mode by doing redirections and directory changing.
|
|
"""
|
|
os.chdir(our_home_dir)
|
|
os.umask(umask)
|
|
sys.stdin.close()
|
|
sys.stdout.close()
|
|
sys.stderr.close()
|
|
if err_log:
|
|
sys.stderr = open(err_log, 'a', 0)
|
|
else:
|
|
sys.stderr = NullDevice()
|
|
if out_log:
|
|
sys.stdout = open(out_log, 'a', 0)
|
|
else:
|
|
sys.stdout = NullDevice()
|
|
|
|
class NullDevice:
|
|
"A writeable object that writes to nowhere -- like /dev/null."
|
|
def write(self, s):
|
|
pass
|
|
|
|
class MuninRequestHandler(socketserver.StreamRequestHandler):
|
|
def handle(self):
|
|
# self.rfile is a file-like object created by the handler;
|
|
# we can now use e.g. readline() instead of raw recv() calls
|
|
plugins = []
|
|
for x in os.listdir(self.server.options.plugin_path):
|
|
if x.startswith('.'):
|
|
continue
|
|
fullpath = os.path.join(self.server.options.plugin_path, x)
|
|
if not os.path.isfile(fullpath):
|
|
continue
|
|
plugins.append(x)
|
|
|
|
node_name = socket.gethostname().split('.')[0]
|
|
self.wfile.write("# munin node at %s\n" % node_name)
|
|
while True:
|
|
line = self.rfile.readline()
|
|
if not line:
|
|
break
|
|
line = line.strip()
|
|
|
|
cmd = line.split(' ', 1)
|
|
plugin = (len(cmd) > 1) and cmd[1] or None
|
|
|
|
if cmd[0] == "list":
|
|
self.wfile.write("%s\n" % " ".join(plugins))
|
|
elif cmd[0] == "nodes":
|
|
self.wfile.write("nodes\n%s\n.\n" % (node_name))
|
|
elif cmd[0] == "version":
|
|
self.wfile.write("munins node on chatter1 version: 1.2.6\n")
|
|
elif cmd[0] in ("fetch", "config"):
|
|
if plugin not in plugins:
|
|
self.wfile.write("# Unknown service\n.\n")
|
|
continue
|
|
c = (cmd[0] == "config") and "config" or ""
|
|
out = execute_plugin(os.path.join(self.server.options.plugin_path, plugin), c)
|
|
self.wfile.write(out)
|
|
if out and out[-1] != "\n":
|
|
self.wfile.write("\n")
|
|
self.wfile.write(".\n")
|
|
elif cmd[0] == "quit":
|
|
break
|
|
else:
|
|
self.wfile.write("# Unknown command. Try list, nodes, config, fetch, version or quit\n")
|
|
|
|
|
|
class MuninServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
HOST, PORT = "0.0.0.0", 4949
|
|
if sys.version_info[:3] >= (2, 6, 0):
|
|
server = MuninServer((HOST, PORT), MuninRequestHandler, bind_and_activate=False)
|
|
server.allow_reuse_address = True
|
|
server.server_bind()
|
|
server.server_activate()
|
|
else:
|
|
server = MuninServer((HOST, PORT), MuninRequestHandler)
|
|
ip, port = server.server_address
|
|
options, args = parse_args()
|
|
options.plugin_path = os.path.abspath(options.plugin_path)
|
|
server.options = options
|
|
|
|
become_daemon()
|
|
server.serve_forever()
|