#!/usr/bin/env python3 import os, setuptools, socketserver, sys, syslog, threading SYSLOG = 0 STDOUT = 1 STDDEB = 2 # STDOUT + Debug exec("logging = %s or STDOUT" % setuptools.getSetting("Log", "sink")) def logger(message, prio=syslog.LOG_INFO, sink=logging): if sink in (STDOUT, STDDEB): if prio not in (syslog.LOG_NOTICE, syslog.LOG_INFO, syslog.LOG_DEBUG): print(message) sys.stderr.write(message) elif prio != syslog.LOG_DEBUG or sink == STDDEB: print(message) elif sink == SYSLOG: syslog.openlog("KumiStatusServer", syslog.LOG_PID) syslog.syslog(prio, message) else: try: sys.stderr.write("Unknown logging level %s, assuming STDOUT from now on." % str(sink)) except: pass logging = STDOUT logger(message, prio, logging) def worker(message): command = message.split() if command[0].lower() in ("heartbeat", "hb", "ping"): return "HB: Still here? Wow." class TCPHandler(socketserver.StreamRequestHandler): def readString(self): return self.rfile.readline().strip() def sendString(self, string): self.request.sendall((string + "\n").encode('utf8')) def handle(self): remote = self.client_address[0] + ":" + str(self.client_address[1]) logger("New connection from %s." % remote, syslog.LOG_INFO) self.sendString("HI: Kumi Status v0.8.15") while True: message = self.readString().decode('utf8') if not message: logger("Connection from %s closed." % remote, syslog.LOG_DEBUG) break logger("%s said: %s" % (remote, message)) response = worker(message) if response: self.sendString(response) logger("Sent to %s: %s" % (remote, response), syslog.LOG_DEBUG) class TCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass def shutdown(reboot = False, status = 0): if reboot: args = sys.argv[:] args.insert(0, sys.executable) try: os.execv(sys.executable, args) except: logger("Restart failed. Shutting down.") exit(2) else: exit(status) if __name__ == "__main__": socketserver.TCPServer.allow_reuse_address = True try: server = TCPServer((setuptools.getSetting("Server", "bind"), int(setuptools.getSetting("Server", "port"))), TCPHandler) except: logger("Unable to bind on %s:%s. Make sure the port is not in use or use a different port.") shutdown(status=1) logger("Kumi Status server running on %s:%s." % (setuptools.getSetting("Server", "bind"), setuptools.getSetting("Server", "port"))) try: thread = threading.Thread(target=server.serve_forever(), daemon=True) except KeyboardInterrupt: logger("Caught KeyboardInterrupt. Shutting down.") shutdown() except EOFError: logger("Caught EOF. Shutting down.") shutdown() except BaseException as e: logger(str(e), syslog.LOG_CRIT) logger("Caught some bad exception. Trying to reload...", syslog.LOG_CRIT) shutdown(reboot=True)