move to python 3

This commit is contained in:
2019-12-16 12:03:32 -05:00
parent 656f9c0784
commit 778c874cee
+101 -99
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# $Id: hbd,v 1.38 2013/07/14 02:25:05 andreas Exp $
# Wait for heartbeat messages and act on them (or their absence)
#
@@ -11,19 +11,19 @@ import sys
import socket
import atexit
import select
import SocketServer
import BaseHTTPServer
import socketserver
import http.server
import getopt
import signal
import cPickle
import pickle
import smtplib
import traceback
import urllib
import urlparse
import httplib
import urllib.request, urllib.parse, urllib.error
import urllib.parse
import http.client
import threading
import Queue
import md5
import queue
from hashlib import md5
import json
import zlib
@@ -35,7 +35,7 @@ from hbdclass import *
SEND_EMAIL=False
SEND_PUSHOVER=True
DEBUG = 0
DEBUG = 3
MAXRECV = 32767
LOGFILE = "/home/andreas/public_html/messages/andreas"
@@ -105,7 +105,7 @@ def handler(signum, frame):
def shortname(name):
r = string.split(name, '.')
r = name.split('.')
return r[0]
@@ -132,22 +132,22 @@ def dicttos(ID, d, compress=False):
s.append("%s=%s" % (k, d[k]))
pk = ";".join(s)
if compress:
zpk = zlib.compress(pk, 6)
ID = "!"+ID
zpk = zlib.compress(pk.encode(), 6)
ID = "!" + ID + ":"
opk = ID.encode() + zpk
else:
zpk = pk
return ID + ":" + zpk
opk = ID + ":" + zpk
return opk
def stodict(msg):
d = {}
r0 = msg.split(':',1)
if len(r0) == 1:
return None
if r0[0][0] == '!': # compressed
pk = zlib.decompress(msg[len(r0[0])+1:])
d['ID'] = r0[0][1:]
if len(msg) > 0 and chr(msg[0]) == "!":
pk = zlib.decompress(msg[5:]).decode()
d['ID'] = msg[1:4].decode()
else:
r0 = msg.split(':',1)
pk = r0[1]
d['ID'] = r0[0]
r = pk.split(';')
@@ -181,11 +181,11 @@ def email(s, msg):
server = smtplib.SMTP(SMTPSERVER)
if DEBUG > 0: server.set_debuglevel(1)
server.sendmail(fromemail, toaddrs, body)
except smtplib.SMTPRecipientsRefused, errs:
except smtplib.SMTPRecipientsRefused as errs:
log(None, "cannot send email: %s\n" % (errs))
ret = "Fail"
except:
print("smtp error: "+traceback.format_exc())
print(("smtp error: "+traceback.format_exc()))
saveandrestart()
try:
server.quit()
@@ -197,10 +197,10 @@ def email(s, msg):
def pushover(msg):
if not SEND_PUSHOVER:
return
conn = httplib.HTTPSConnection("api.pushover.net:443")
conn = http.client.HTTPSConnection("api.pushover.net:443")
try:
conn.request("POST", "/1/messages.json",
urllib.urlencode({
urllib.parse.urlencode({
"token": "ac7NLX2rPjXFareeDgLpXNoDf4iFmf",
"user": "uDhH33UjQQDYtNzJb1ThRiWb9ingGK",
"message": msg, }), { "Content-type": "application/x-www-form-urlencoded" })
@@ -242,7 +242,7 @@ answer
if DEBUG > 0: log(None, "DBG: cmd %s" % cmd)
try:
p = Popen(cmd, shell=False, bufsize=1, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
except OSError, e:
except OSError as e:
return "nsupdate: execution failed: %s" % e
except:
return "nsupdate: some error occured"
@@ -256,9 +256,9 @@ answer
#
def dur(sec):
sec = int(sec)
h = sec / 3600
m = (sec - h * 3600) / 60
s = (sec - h * 3600) % 60
h = int(sec / 3600)
m = int((sec - h * 3600) / 60)
s = int((sec - h * 3600) % 60)
if h > 0:
return "%d:%02d:%02d" % (h, m, s)
if m > 0:
@@ -267,7 +267,7 @@ def dur(sec):
def fixsort():
s = Host.hosts.keys()
s = list(Host.hosts.keys())
s.sort()
x = 0
for n in s:
@@ -281,7 +281,7 @@ def on_exit():
logf.close()
except:
pass
print "exit"
print("exit")
def initlog(logfile):
@@ -296,7 +296,7 @@ def initlog(logfile):
#
def checkoverdue():
now = time.time()
for h in Host.hosts.keys():
for h in list(Host.hosts.keys()):
pmsg = []
for c in Host.hosts[h].connections:
conn = Host.hosts[h].connections[c]
@@ -316,7 +316,7 @@ def checkoverdue():
def log(host, m, service=None):
if DEBUG > 0: print "Log: %s %s" % (host, m)
if DEBUG > 0: print(("Log: %s %s" % (host, m)))
now = time.time()
ts = time.strftime("%b %d %H:%M:%S", time.localtime(now))
if service:
@@ -359,27 +359,28 @@ def dnsupdatethread():
def readsock(sock):
global now
if DEBUG > 3: sys.stderr.write("readsock recfrom start")
data, addrp = sock.recvfrom(MAXRECV)
now = time.time()
if DEBUG > 2: sys.stderr.write("readsock = %s, %s\n" % (data,addrp))
data, addrp = sock.recvfrom(MAXRECV)
if DEBUG > 3: sys.stderr.write("readsock = %s, %s\n" % (data,addrp))
try:
msg = stodict(data)
except:
return
if DEBUG > 3: sys.stderr.write("msg is %s" % str(msg))
if not msg: # Old hbc client
if verbose: print "old hbc:", data
if verbose: print(("old hbc:", data))
oldclient = True
msg = oldmtodict(data)
else:
oldclient = False
if DEBUG > 2: print "readsock = %s, %s" % (msg,addrp)
if DEBUG > 2: print(("readsock = %s, %s" % (msg,addrp)))
addr = addrp[0:2]
name = shortname(msg.get('name', "unknown"))
if not name in Host.hosts: # was: hosts.has_key(name):
host = Host(name)
host.dyn = h in dyndnshosts
if verbose: print "XX: New host, num now %s" % (len(Host.hosts))
host.dyn = name in dyndnshosts
if verbose: print(("XX: New host, num now %s" % (len(Host.hosts))))
newh=True
else:
host = Host.hosts[name]
@@ -452,7 +453,7 @@ def readsock(sock):
ss=sock.sendto(opkt, addr)
except:
pass # XXX return pkg failes
if DEBUG > 2: print "sendto1: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50])
if DEBUG > 2: print(("sendto1: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50])))
# send any commands we have queued
while len(host.cmds):
@@ -477,11 +478,11 @@ def readsock(sock):
try:
ss=sock.sendto(opkt, addr)
except Exception as e:
print "opkt len is %s" % len(opkt)
print "cannot send: %s" % e
print(("opkt len is %s" % len(opkt)))
print(("cannot send: %s" % e))
if verbose: print "sendto2: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50])
if DEBUG > 2: print "msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss)
if verbose: print(("sendto2: %s (%s) %s %s" % (addr, len(opkt), op, str(rmsg)[:50])))
if DEBUG > 2: print(("msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss)))
@@ -505,13 +506,13 @@ def updatecode(ucode, uname):
#
# Web Server
#
class HttpServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
class HttpServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
allow_reuse_address = True
def threaded():
pass
#
#
class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
class HttpHandler(http.server.BaseHTTPRequestHandler):
server_version = "HeartbeatHTTP/%s" % VER
@@ -520,8 +521,9 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def handle(self):
return http.server.BaseHTTPRequestHandler.handle(self)
try:
return BaseHTTPServer.BaseHTTPRequestHandler.handle(self)
return http.server.BaseHTTPRequestHandler.handle(self)
except Exception as e:
self.log_error("Request went away: %r", e)
self.close_connection = 1
@@ -587,11 +589,11 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
global sig
code = 200
xsig = 0
rqAcceptEncoding = self.headers.getheader('Accept-encoding',{})
rqAcceptEncoding = self.headers.get('Accept-encoding',{})
headerdict = {"Content-Type": "text/html; charset = ISO-8859-1" }
if DEBUG > 2: sys.stderr.write("handle\n")
qr = urlparse.urlparse(self.path)
qa = urlparse.parse_qs(qr.query)
qr = urllib.parse.urlparse(self.path)
qa = urllib.parse.parse_qs(qr.query)
if DEBUG > 2: sys.stderr.write("handle = %s\n" % (qr.geturl()))
if qr.path == "/":
@@ -602,10 +604,10 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
ucmd=qa.get('c', [None])[0]
if not ucmd or not uname:
code, res=self.builderror(400, 'Argument error', "need h= and c= arguments")
elif not Host.hosts.has_key(uname):
elif uname not in Host.hosts:
code, res=self.builderror(400, 'Data error', "h=%s not found" % uname)
else:
Host.hosts[uname].cmds.append(('CMD', {'cmd': urllib.unquote(ucmd)}))
Host.hosts[uname].cmds.append(('CMD', {'cmd': urllib.parse.unquote(ucmd)}))
res=self.buildhead()
res.append("cmd %s queued for host %s" % (uname, ucmd))
@@ -634,11 +636,11 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
log(uname, ll)
elif qr.path == "/u": # update
uname=urllib.unquote(qa.get('h',[None])[0])
uname=urllib.parse.unquote(qa.get('h',[None])[0])
ucode=qa.get('c', [None])[0]
if not ucode or not uname:
code, res=self.builderror(400, 'Argument error', "need h= and c= arguments")
elif uname != 'All' and not Host.hosts.has_key(uname):
elif uname != 'All' and uname not in Host.hosts:
code, res=self.builderror(400, 'Data error', "h=%s not found" % uname)
else:
res=self.buildhead()
@@ -678,9 +680,9 @@ class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
if 'deflate' in rqAcceptEncoding:
headerdict['Content-Encoding'] = "deflate"
towrite = zlib.compress(string.join(res, "\n"), 6)
towrite = zlib.compress("\n".join(res).encode(), 6)
else:
towrite = string.join(res, "\n")
towrite = "\n".join(res)
headerdict['Content-Length'] = len(towrite)
headerdict['Cache-Control'] = 'private, must-revalidate, max-age=0'
headerdict['Expires'] = 'Thu, 01 Jan 1970 00:00:00 GMT'
@@ -731,9 +733,9 @@ def closeup():
def restart():
if verbose: print "execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs)
if verbose: 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"
print("should not be here")
def saveandrestart():
closeup()
@@ -741,8 +743,8 @@ def saveandrestart():
def pickleit():
pickf = open(pickfile, 'w')
pick = cPickle.Pickler(pickf)
pickf = open(pickfile, 'wb')
pick = pickle.Pickler(pickf)
pick.dump(Host.hosts)
pick.dump(msgs)
pick.dump(lastfm)
@@ -783,17 +785,17 @@ for o, a in optlist:
cmdargs += [o]
if helpflag:
print "hbc HeartBeatDaemon"
print "usage: hbd [-dfhvx] [-c configfile]"
print
print " -c configfile"
print " -d display"
print " -f run in foreground"
print " -h this help"
print " -v verbose"
print " -x increase debug lvl"
print
print """ config file can contain
print("hbc HeartBeatDaemon")
print("usage: hbd [-dfhvx] [-c configfile]")
print()
print(" -c configfile")
print(" -d display")
print(" -f run in foreground")
print(" -h this help")
print(" -v verbose")
print(" -x increase debug lvl")
print()
print(""" config file can contain
logfile = /var/log/heartbeat.log
logfmt = [text|msg]
hb_port = 50003
@@ -801,7 +803,7 @@ interval = 20
hbd_port = 50004
hbd_host = www.domain.com
grace = 2
"""
""")
sys.exit(1)
@@ -823,9 +825,9 @@ drophosts = []
try:
f = open(configfile, "r")
if verbose:
print "notice: using config file %s" % configfile
print(("notice: using config file %s" % configfile))
except:
print "warning: running without config file: %s" % configfile
print(("warning: running without config file: %s" % configfile))
f = None
if f:
@@ -837,13 +839,13 @@ if f:
if len(l) == 0 or l[0] == "#":
continue
if verbose:
print " %s" % l
print((" %s" % l))
r = l.split('=')
o = r[0].strip()
try:
a = eval(r[1].strip())
except Exception as e:
print "error: %s" % str(r)
print(("error: %s" % str(r)))
sys.exit(1)
if o == 'interval':
interval = a
@@ -870,18 +872,18 @@ if f:
f.close()
if len(args) != 0:
print "error: args"
print("error: args")
sys.exit(1)
if verbose:
print "notice: logging to %s" % logfile
print(("notice: logging to %s" % logfile))
logf = initlog(logfile)
if 1 and os.path.exists(pickfile):
if verbose: print "opening pickls %s" % pickfile
pickf = open(pickfile, 'r')
pick = cPickle.Unpickler(pickf)
if verbose: print(("opening pickls %s" % pickfile))
pickf = open(pickfile, 'rb')
pick = pickle.Unpickler(pickf)
try:
Host.hosts = pick.load()
msgs = pick.load()
@@ -891,18 +893,18 @@ if 1 and os.path.exists(pickfile):
lastfm = ["","",""]
pickf.close()
except Exception as e:
print "load pickled failed: %s" % e
print(("load pickled failed: %s" % e))
os.unlink(pickfile)
Connection.htab = {}
for h in Host.hosts.keys():
for h in list(Host.hosts.keys()):
Host.hosts[h].dyn = h in dyndnshosts
Host.hosts[h].fixup()
for h in drophosts:
if h in Host.hosts:
del Host.hosts[h]
if verbose: print "%s pickled hosts loaded" % len(Host.hosts)
if verbose: print(("%s pickled hosts loaded" % len(Host.hosts)))
else:
if verbose: print "no pickled data"
if verbose: print("no pickled data")
now = time.time()
@@ -930,7 +932,7 @@ if not forground:
pid = os.fork()
if pid > 0:
if verbose:
print "daemoinizing... pid = %d" % pid
print(("daemoinizing... pid = %d" % pid))
sys.exit(0)
verbose = False
@@ -951,14 +953,14 @@ if not forground:
try:
serv = HttpServer((hbd_host, hbd_port), HttpHandler)
except:
print "failed to start server on %s:%s" % (hbd_host, hbd_port)
print(("failed to start server on %s:%s" % (hbd_host, hbd_port)))
sys.exit(1)
servthread = threading.Thread(target=serv.serve_forever)
servthread.daemon = True
servthread.start()
Host.dnsQ = Queue.Queue()
Host.dnsQ = queue.Queue()
dnsT = threading.Thread(target=dnsupdatethread)
dnsT.daemon = True
dnsT.start()
@@ -968,13 +970,13 @@ sig = 0
signal.signal(signal.SIGTERM, handler)
signal.signal(signal.SIGHUP, handler)
next = int(now)+15 # 15 seconds time to settle after (re-)start
rnext = 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 > 3: sys.stderr.write("about to sleep = %s\n" % (sleep))
try:
sr = select.select(ilist, [], [], sleep)
now = time.time()
@@ -983,7 +985,7 @@ while running:
running = False
closeup()
continue
except select.error, value:
except select.error as value:
if value[0] != 4: # interrupted system call
sys.stderr.write("select err %s %s" % (select.error, value))
#raise os.error, value
@@ -992,7 +994,7 @@ while running:
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 > 3: 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)
@@ -1000,26 +1002,26 @@ while running:
# serv.handle_request()
else:
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))
if DEBUG > 3: sys.stderr.write("done handling, running is %s, sig is %s\n" % (running, sig))
# check hour/day/week
for v in xrange(3):
for v in range(3):
fm=tsfm[v]
ts=time.strftime(tsfm[v], time.localtime(now))
if ts != lastfm[v]:
lastfm[v]=ts
for h in Host.hosts.keys():
for h in list(Host.hosts.keys()):
Host.hosts[h].hdwcounts[v] = [Host.hosts[h].doesack, Host.hosts[h].upcount]
if now >= next and now >= firstcheck:
next = now+1
if now >= rnext and now >= firstcheck:
rnext = now+1
checkoverdue()
sleep = next-now
sleep = rnext-now
if sleep < 0:
sys.stderr.write("sleep is negative! %s next = %s\n" % (sleep, next))
sys.stderr.write("sleep is negative! %s next = %s\n" % (sleep, rnext))
sleep = 0
if DEBUG > 2: sys.stderr.write("sleep = %s next = %s\n" % (sleep, next))
if DEBUG > 3: sys.stderr.write("sleep = %s next = %s\n" % (sleep, rnext))
if sig != 0:
setrunning(False)