add IPv6 support

This commit is contained in:
2014-01-08 21:09:36 -05:00
parent d176dab654
commit 6374d7375f
2 changed files with 256 additions and 218 deletions
+240 -212
View File
@@ -1,212 +1,240 @@
#!/usr/bin/env python #!/usr/bin/env python
# $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $ # $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $
import sys, time, socket, os, signal, getopt, string, select import sys, time, socket, os, signal, getopt, string, select
PORT=50003 PORT=50003
INTERVAL=10 INTERVAL=10
False=0 False=0
True=1 True=1
class NullDevice:
def write(self, s): sock=None
pass
class NullDevice:
def write(self, s):
def handler(signum, frame): pass
global up
if up == 0:
return def handler(signum, frame):
sys.exit(0) global up
if up == 0:
msgonly=False return
helpflag=False sys.exit(0)
verbose=False
daemon=False
optlist=[] def getsock(host):
args=[] try:
msgboot=[] r=socket.getaddrinfo(host, 50001, 0, 0, socket.SOL_UDP)
home=os.environ['HOME'] except socket.gaierror:
configfile="%s/.hbrc" % home return None
if r[0][0] == 28:
try: af_type=socket.AF_INET6
optlist, args = getopt.getopt(sys.argv[1:], 'bc:dhm:v') elif r[0][0] == 2:
except: af_type=socket.AF_INET
helpflag=True else:
return None
for o,a in optlist: if verbose:
if o == '-b': print "socktype: %s" % af_type
msgboot.append("boot=1") sock=socket.socket(af_type, socket.SOCK_DGRAM)
elif o == '-c': sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \
configfile=a sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR) | 1)
elif o == '-d': if verbose: print "get socket %s" % sock
daemon=True
elif o == '-h': return sock
helpflag=True
elif o == '-m': def socksend(msg, tohost):
msgboot.append("service=%s" % "service") global sock
a.replace(';',':')
msgboot.append("msg=%s" % a) if sock == None:
msgonly=True sock=getsock(tohost[0])
elif o == '-v': sock.sendto(msg, tohost)
verbose=True
msgonly=False
if helpflag: helpflag=False
print "hbc HeartBeatClient" verbose=False
print "usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]" daemon=False
print optlist=[]
print " -b indicate machine boot" args=[]
print " -c configfile" msgboot=[]
print " -d daemonize" home=os.environ['HOME']
print " -h this help" configfile="%s/.hbrc" % home
print " -m send a message"
print " -v verbose" try:
print optlist, args = getopt.getopt(sys.argv[1:], 'bc:dhm:v')
print """ config file can contain except:
hb_hosts=('host1', 'host2', ..._ helpflag=True
hb_port=50003
interval=20 for o,a in optlist:
logfile=... if o == '-b':
logfmt={|test|msg} msgboot.append("boot=1")
grace=SECONDS elif o == '-c':
reportstrict={True|False} configfile=a
""" elif o == '-d':
daemon=True
sys.exit(1) elif o == '-h':
helpflag=True
# elif o == '-m':
# set defaults msgboot.append("service=%s" % "service")
a.replace(';',':')
hb_port=PORT msgboot.append("msg=%s" % a)
interval=INTERVAL msgonly=True
hb_hosts=[] elif o == '-v':
iam=socket.gethostname() verbose=True
try:
f=open(configfile,"r") if helpflag:
if verbose: print "notice: using config file %s" % configfile print "hbc HeartBeatClient"
except: print "usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]"
if verbose: print "warning: running without config file: %s" % configfile print
f=None print " -b indicate machine boot"
print " -c configfile"
if f: print " -d daemonize"
while 1: print " -h this help"
l=f.readline() print " -m send a message"
if len(l) == 0: print " -v verbose"
break print
r=l[:-1].split('=') print """ config file can contain
if r[0] == 'hb_hosts': hb_hosts=('host1', 'host2', ..._
hb_hosts=eval(r[1]) hb_port=50003
if verbose: interval=20
print "notice: cfg hb_hosts: %s" % hb_hosts logfile=...
elif r[0] == 'interval': logfmt={|test|msg}
interval=eval(r[1]) grace=SECONDS
elif r[0] == 'hb_port': reportstrict={True|False}
hb_port=eval(r[1]) """
elif r[0] == 'name':
iam=eval(r[1]) sys.exit(1)
if verbose: print "name set to %s" % iam
f.close() #
# set defaults
if len(args) != 0:
hb_hosts=args hb_port=PORT
interval=INTERVAL
if len(hb_hosts) == 0: hb_hosts=[]
print "no hb server specified" iam=socket.gethostname()
sys.exit(1)
try:
f=open(configfile,"r")
sock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) if verbose: print "notice: using config file %s" % configfile
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \ except:
sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR) | 1) if verbose: print "warning: running without config file: %s" % configfile
f=None
if verbose: if f:
print "notice: hb_hosts: %s" % str(hb_hosts) while 1:
print "notice: hb_port: %s" % hb_port l=f.readline()
print "notice: interval: %s" % interval if len(l) == 0:
print "notice: iam: %s" % iam break
r=l[:-1].split('=')
if not msgonly: if r[0] == 'hb_hosts':
msgboot.append("interval=%s" % interval) hb_hosts=eval(r[1])
if verbose:
if len(msgboot) > 0: print "notice: cfg hb_hosts: %s" % hb_hosts
msgboot.append("name=%s" % iam) elif r[0] == 'interval':
msgboot.append("time=%s" % time.time()) interval=eval(r[1])
msgboot.append("acks=0") elif r[0] == 'hb_port':
msg=";".join(msgboot) hb_port=eval(r[1])
while 1: elif r[0] == 'name':
fail=0 iam=eval(r[1])
for hb_host in hb_hosts: if verbose: print "name set to %s" % iam
try: f.close()
if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
sock.sendto(msg, (hb_host, hb_port)) if len(args) != 0:
except: hb_hosts=args
fail=1
if fail: if len(hb_hosts) == 0:
time.sleep(10) print "no hb server specified"
else: sys.exit(1)
break
if msgonly:
sys.exit(0) if verbose:
print "notice: hb_hosts: %s" % str(hb_hosts)
if daemon: print "notice: hb_port: %s" % hb_port
pid=os.fork() print "notice: interval: %s" % interval
if pid > 0: print "notice: iam: %s" % iam
if verbose:
print "daemoinizing... pid=%d" % pid if not msgonly:
sys.exit(0) msgboot.append("interval=%s" % interval)
if len(msgboot) > 0:
os.close(0) msgboot.append("name=%s" % iam)
os.close(1) msgboot.append("time=%s" % time.time())
os.close(2) msgboot.append("acks=0")
sys.stdin.close() msg=";".join(msgboot)
sys.stdout = NullDevice() while 1:
sys.stderr = NullDevice() fail=0
os.chdir("/") for hb_host in hb_hosts:
os.setsid() try:
os.umask(0) if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
socksend(msg, (hb_host, hb_port))
except:
up=1 fail=1
signal.signal(signal.SIGTERM, handler) if fail:
signal.signal(signal.SIGHUP, handler) time.sleep(10)
ackcount=0 else:
lastT=time.time() break
while up:
sleep=(lastT+interval) - time.time() if msgonly:
if verbose: print "sleep %s" % sleep sys.exit(0)
if sleep > 0:
try: if daemon:
r=select.select([sock.fileno()],[],[],sleep) pid=os.fork()
# time.sleep(interval) if pid > 0:
except: if verbose:
break print "daemoinizing... pid=%d" % pid
if verbose: print r sys.exit(0)
if sock.fileno() in r[0]:
data, addr = sock.recvfrom(1024)
if data == "ACK": os.close(0)
ackcount+=1 os.close(1)
else: os.close(2)
try: sys.stdin.close()
os.system(data) sys.stdout = NullDevice()
except: sys.stderr = NullDevice()
pass os.chdir("/")
continue os.setsid()
lastT=time.time() os.umask(0)
for hb_host in hb_hosts:
try:
msg="interval=%s;name=%s;time=%s;acks=%s" % (interval, iam, time.time(), ackcount) up=1
if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port) signal.signal(signal.SIGTERM, handler)
sock.sendto(msg, (hb_host, hb_port)) signal.signal(signal.SIGHUP, handler)
except: ackcount=0
pass lastT=time.time()
while up:
up=0 sleep=(lastT+interval) - time.time()
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount) if verbose: print "sleep %s" % sleep
for hb_host in hb_hosts: if sleep > 0:
if verbose: print "hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port) try:
sock.sendto(msg, (hb_host, hb_port)) r=select.select([sock.fileno()],[],[],sleep)
time.sleep(1) # time.sleep(interval)
sock.close() except:
break
if verbose: print r
if sock.fileno() in r[0]:
data, addr = sock.recvfrom(1024)
if data == "ACK":
ackcount+=1
else:
try:
os.system(data)
except:
pass
continue
lastT=time.time()
for hb_host in hb_hosts:
try:
msg="interval=%s;name=%s;time=%s;acks=%s" % (interval, iam, time.time(), ackcount)
if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
socksend(msg, (hb_host, hb_port))
except:
pass
up=0
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount)
for hb_host in hb_hosts:
if verbose: print "hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
socksend(msg, (hb_host, hb_port))
time.sleep(1)
sock.close()
+16 -6
View File
@@ -340,6 +340,7 @@ def display():
def log(m, service="heartbeat"): def log(m, service="heartbeat"):
if DEBUG: print "Log: %s" % m
msg = time.strftime("%b %d %H:%M:%S", time.localtime(time.time()))+": "+m+"\n" msg = time.strftime("%b %d %H:%M:%S", time.localtime(time.time()))+": "+m+"\n"
msgs.append(msg) msgs.append(msg)
if logfmt == "msg": if logfmt == "msg":
@@ -396,7 +397,7 @@ def fromaddr(name, addr, boot, interval, acks):
# #
# #
def readsock(): def readsock(sock):
global htab, win global htab, win
data, addr = sock.recvfrom(1024) data, addr = sock.recvfrom(1024)
pairs = string.split(data, ';') pairs = string.split(data, ';')
@@ -475,7 +476,9 @@ def readsock():
del hosts[name].cmds[0] del hosts[name].cmds[0]
log("%s command initiated" % name) log("%s command initiated" % name)
try: try:
sock.sendto(rmsg, addr) ss=sock.sendto(rmsg, addr)
if DEBUG:
log("msg from %s,%s, sent %s bytes back" % (addr[0], addr[1], ss))
except: except:
pass pass
@@ -791,11 +794,16 @@ atexit.register(on_exit)
ilist = [] ilist = []
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", hb_port)) sock.bind(("", hb_port))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ilist.append(sock) ilist.append(sock)
sock6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock6.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock6.bind(("", hb_port))
ilist.append(sock6)
serv = HtmlServer((hbd_host, hbd_port), HtmlHandler) serv = HtmlServer((hbd_host, hbd_port), HtmlHandler)
ilist.append(serv.fileno()) ilist.append(serv.fileno())
@@ -861,10 +869,12 @@ while running:
except: except:
sys.exit(1) sys.exit(1)
for fh in sr[0]: for fh in sr[0]:
if fh == sock: if fh in [sock, sock6]:
readsock() readsock(fh)
if fh == serv.fileno(): elif fh == serv.fileno():
serv.handle_request() serv.handle_request()
else:
print("what happend just now")
if now >= next: if now >= next:
next = now+1 next = now+1
checkoverdue() checkoverdue()