diff --git a/hbd b/hbd index eefeec7..4221e5f 100755 --- a/hbd +++ b/hbd @@ -2,7 +2,7 @@ # $Id: hbd,v 1.38 2013/07/14 02:25:05 andreas Exp $ # Wait for heartbeat messages and act on them (or their absence) # -VER = 1.62 +VER = 2.00 import time import os @@ -12,6 +12,7 @@ import socket import atexit import select import SocketServer +import BaseHTTPServer import getopt import signal import cPickle @@ -19,6 +20,7 @@ import smtplib import traceback import urllib import httplib +import threading from subprocess import Popen, STDOUT, PIPE @@ -62,11 +64,8 @@ def handler(signum, frame): if verbose: sys.stderr.write("NOT runing signal: %s running: %d" % (sig, running)) sys.exit(2) -# signal.signal(sig, handler) if verbose: sys.stderr.write("signal: %s running: %s frame: %s" % (sig, running, frame)) - running = False -# sys.exit(0) def shortname(name): @@ -168,8 +167,7 @@ def email(s, msg): body = "To: %s\nFrom: %s\nSubject: %s\nDate: %s\n\n%s" % (toaddrs[0], fromaddr, subj, date, msg) try: server = smtplib.SMTP(SMTPSERVER) - if DEBUG > 0: - server.set_debuglevel(1) + if DEBUG > 0: server.set_debuglevel(1) server.sendmail(fromaddr, toaddrs, body) except smtplib.SMTPRecipientsRefused, errs: log("cannot send email: %s\n" % (errs)) @@ -202,7 +200,7 @@ def pushover(msg): # nsupdate: set the DNS A record for a fqdn # return: None if ok, else error text def nsupdate(hostname, newip): - D = {} + u = {} D['domain'] = 'dy.wapanafa.org' D['fqdn'] = '%s.dy.wapanafa.org' % hostname D['dnsttl'] = '5' @@ -278,9 +276,11 @@ def addhost(name, addr): # def on_exit(): - if DEBUG > 0: - sys.stderr.write("on_exit\n") - logf.close() + if DEBUG > 0: sys.stderr.write("on_exit\n") + try: + logf.close() + except: + pass print "exit" @@ -367,11 +367,9 @@ def fromaddr(name, addr, boot, interval, acks): # def readsock(sock): global htab - if DEBUG > 3: - sys.stderr.write("readsock recfrom start") + if DEBUG > 3: sys.stderr.write("readsock recfrom start") data, addr = sock.recvfrom(1024) - if DEBUG > 2: - sys.stderr.write("readsock = %s, %s\n" % (data,addr)) + if DEBUG > 2: sys.stderr.write("readsock = %s, %s\n" % (data,addr)) pairs = string.split(data, ';') boot = 0 shutdown = 0 @@ -455,20 +453,32 @@ def readsock(sock): log("%s command initiated" % name) try: ss=sock.sendto(rmsg, addr) - if DEBUG > 2: - print "msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss) + if DEBUG > 2: print "msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss) except: pass # # -class HtmlServer(SocketServer.TCPServer): - allow_reuse_address = True -# -# -class HtmlHandler(SocketServer.BaseRequestHandler): +#class HttpServer(BaseHTTPServer.HTTPServer): +class HttpServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): + allow_reuse_address = True + def threaded(): + pass +# +# +class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler): + + + def do_HEAD(self): + self.send_response(200) + self.send_header("Last-Modified", time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(now))) +# self.send_header("Accept-Ranges","bytes") +# self.send_header("Connection","close") + self.send_header("Content-Type","text/html; charset = ISO-8859-1") + self.end_headers() + def buildhead(self, title="Heartbeat", refresh=None): res=[] @@ -508,41 +518,26 @@ class HtmlHandler(SocketServer.BaseRequestHandler): res.append('

%s

' % (cause)) res.append('

%s

' % lcause) res.append('
') - res.append('
hbd (Unix) Server at %s Port %s
' % (hbd_host, hbd_port)) + res.append('
hbd (Unix) Server at %s:%s
' % (hbd_host, hbd_port)) res.append('') return res - def handle(self): - global sig, running - headers=[] - headers.append("Date: %s" % time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(now))) - headers.append("Server: hbd") - headers.append("Last-Modified: %s" % time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(now))) - headers.append("Accept-Ranges: bytes") - headers.append("Connection: close") - headers.append("Content-Type: text/html; charset = ISO-8859-1") - uri = '/unknown' - f = self.request.makefile() - while 1: - try: - line = string.strip(f.readline()) - except: - line = '' - if len(line) == 0: - break - r = line.split() - if r[0] == "GET": - uri = r[1] - html = r[2] + def do_GET(self): + global sig + xsig = 0 + self.do_HEAD() + headers=[] + + if DEBUG > 2: sys.stderr.write("handle\n") + uri = self.path upar=string.split(uri,"?") if len(upar) == 1: uarg=[] else: uarg=string.split(upar[1],"&") - if DEBUG > 2: - sys.stderr.write("handle = %s\n" % (uri)) + if DEBUG > 2: sys.stderr.write("handle = %s\n" % (uri)) code = 200 cause = "OK" if uri == "/": @@ -599,8 +594,7 @@ class HtmlHandler(SocketServer.BaseRequestHandler): elif upar[0] == "/r": # restart res=self.buildhead() res.append("restart request") - sig=signal.SIGHUP - running=False + xsig=signal.SIGHUP log("restart request") else: @@ -609,7 +603,7 @@ class HtmlHandler(SocketServer.BaseRequestHandler): res=self.builderror(code, cause, "The requested URL was not found on this server.") - tosend = ["HTTP/1.0 %s %s\r" % (code, cause)] + tosend = [] for h in headers: tosend.append("%s\r" % h) tosend.append("\r") @@ -619,13 +613,19 @@ class HtmlHandler(SocketServer.BaseRequestHandler): # self.request.send("\r\n") tosend += res - try: - self.request.send(string.join(tosend, "\n")) - except: - pass + self.wfile.write(string.join(tosend, "\n")) + + if xsig: + sig = xsig + +def setrunning(new): + global running + if DEBUG > 0: sys.stderr.write("running is now = %s\n" % (new)) + running = new -def saveandrestart(): +def closeup(): + setrunning(False) try: sock.close() except: @@ -634,16 +634,36 @@ def saveandrestart(): sock6.close() except: pass + if DEBUG > 0: sys.stderr.write("asking http server to stop\n") + + try: + serv.shutdown() + if DEBUG > 0: sys.stderr.write("http server stopped\n") + except Exception as e: + if DEBUG > 0: sys.stderr.write("http server did NOT stop: %s\n" % str(e)) try: serv.server_close() except: pass + log("restarting") try: logf.close() except: pass + + signal.signal(signal.SIGTERM, 0) + signal.signal(signal.SIGHUP, 0) + + +def restart(): + print "execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs) os.execv(sys.argv[0], [sys.argv[0]]+cmdargs) + print "should not be here" + +def saveandrestart(): + closeup() + restart() def pickleit(): @@ -686,8 +706,8 @@ for o, a in optlist: verbose = True cmdargs += [o] elif o == '-x': - DEBUG = True - + DEBUG += 1 + cmdargs += [o] if helpflag: print "hbc HeartBeatDaemon" @@ -698,7 +718,7 @@ if helpflag: print " -f run in foreground" print " -h this help" print " -v verbose" - print " -x debug" + print " -x increase debug lvl" print print """ config file can contain logfile = /var/log/heartbeat.log @@ -731,7 +751,7 @@ try: if verbose: print "notice: using config file %s" % configfile except: - print "warning: running without conifig file: %s" % configfile + print "warning: running without config file: %s" % configfile f = None if f: @@ -814,8 +834,11 @@ sock6.bind(("", hb_port)) ilist.append(sock6) -serv = HtmlServer((hbd_host, hbd_port), HtmlHandler) -ilist.append(serv.fileno()) +serv = HttpServer((hbd_host, hbd_port), HttpHandler) +servthread = threading.Thread(target=serv.serve_forever) +servthread.start() + +#ilist.append(serv.fileno()) if not forground: pid = os.fork() @@ -840,35 +863,39 @@ sig = 0 signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGHUP, handler) -next = int(now)+15 # 15 seconds time to settle after (re-)start -sleep = next - now -while running: +next = int(now)+15 # 15 seconds time to settle after (re-)start +sleep = 1 +firstcheck = int(now) + 15 +while running: sr = None - if DEBUG > 2: - sys.stderr.write("about to sleep = %s\n" % (sleep)) + if DEBUG > 2: sys.stderr.write("about to sleep = %s\n" % (sleep)) try: sr = select.select(ilist, [], [], sleep) now = time.time() except KeyboardInterrupt: - sys.exit(0) + sys.stderr.write("Keyboard Interrupt!\n") + running = False + closeup() + continue except select.error, value: if value[0] != 4: # interrupted system call - print select.error, value + sys.stderr.write("select err %s %s" % (select.error, value)) #raise os.error, value continue continue - except: + except Exception as e: + if DEBUG > 2: sys.stderr.write("select exception %s\n" % (str(e))) sys.exit(1) - if DEBUG > 2: - sys.stderr.write("woke from sleep = %s (%s)\n" % (str(sr), str(ilist))) + if DEBUG > 2: sys.stderr.write("woke from sleep = %s (%s)\n" % (str(sr), str(ilist))) for fh in sr[0]: if fh in [sock, sock6]: readsock(fh) - elif fh == serv.fileno(): - serv.handle_request() +# elif fh == serv.fileno(): +# serv.handle_request() else: - print("what happend just now") + sys.stderr.write("what happend just now?\n") + if DEBUG > 2: sys.stderr.write("done handling, running is %s, sig is %s\n" % (running, sig)) # check hour/day/week for v in xrange(3): @@ -879,19 +906,21 @@ while running: for h in hosts.keys(): hosts[h].hdwcounts[v] = [hosts[h].doesack, hosts[h].upcount] - if now >= next: + if now >= next and now >= firstcheck: next = now+1 checkoverdue() sleep = next-now if sleep < 0: - sys.stderr.write("sleep is negaitive! %s next = %s\n" % (sleep, next)) + sys.stderr.write("sleep is negative! %s next = %s\n" % (sleep, next)) sleep = 0 - if DEBUG > 2: - sys.stderr.write("sleep = %s next = %s\n" % (sleep, next)) + if DEBUG > 2: sys.stderr.write("sleep = %s next = %s\n" % (sleep, next)) + + if sig != 0: + setrunning(False) + if sig == signal.SIGHUP: - if DEBUG > 0: - sys.stderr.write("signal 1 saveandrestart\n") + if DEBUG > 0: sys.stderr.write("signal 1 saveandrestart\n") saveandrestart()