use threading for the webserver
This commit is contained in:
@@ -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('<h1>%s</h1>' % (cause))
|
||||
res.append('<p>%s</p>' % lcause)
|
||||
res.append('<hr>')
|
||||
res.append('<address>hbd (Unix) Server at %s Port %s</address>' % (hbd_host, hbd_port))
|
||||
res.append('<address>hbd (Unix) Server at %s:%s</address>' % (hbd_host, hbd_port))
|
||||
res.append('</body></html>')
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user