#!/usr/bin/env python import os, sys, re, logging, signal, time, threading ROOT = '/q/public/mdnsexporter' HOSTNAME = 'fleet' SVC_PATH = '/etc/avahi/services' QUIT = False PID_FILE = os.path.join(ROOT, 'var', 'mdnsexporter.pid') LOG_FILE = os.path.join(ROOT, 'log', 'mdnsexporter.log') logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', filename=LOG_FILE, filemode='a' ) def handler(signum, sigframe): if os.path.exists(PID_FILE): os.unlink(PID_FILE) globals()['QUIT'] = True signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGINT, handler) class DNSSDRunner(threading.Thread): def __init__(self, file, svc): self.svc_name, self.svc_type, self.svc_port, self.svc_text = svc self.file = file threading.Thread.__init__(self) def run(self): pid = os.fork() if pid: while not QUIT and self.file in svcs().keys(): time.sleep(1) pass logging.info('killing %s' % self.file) os.kill(pid, 15) else: os.execlp( 'dns-sd', 'dns-sd', '-R', '"%s"' % self.svc_name, self.svc_type, '.', self.svc_port, self.svc_text, ) def svcs(): svcs = {} for file in os.listdir(SVC_PATH): try: data = open(os.path.join(SVC_PATH, file), 'r').read() m = re.search(r']*>(.*?)', data) svc_name = m.group(1) if '%h' in svc_name: svc_name = svc_name.replace('%h', HOSTNAME) m = re.search(r'(.*?)', data) svc_type = m.group(1) m = re.search(r'(.*?)', data) svc_port = m.group(1) m = re.search(r'(.*?)', data) svc_text = m.group(1) svcs[file] = (svc_name, svc_type, svc_port, svc_text) except: pass return svcs threads = [] spawned = {} pid = os.fork() if pid: sys.exit(0) os.chdir('/') os.setsid() os.umask(0) pid = os.fork() if pid: sys.exit(0) open(PID_FILE, 'w').write(str(os.getpid())) while not QUIT: sv = svcs() delete = [] for sp_file, sp_svc in spawned.iteritems(): if sp_file not in sv.keys(): delete.append(sp_file) for d in delete: logging.debug('removing %s' % d) del spawned[d] for file, svc in sv.iteritems(): svc_name, svc_type, svc_port, svc_text = svc if file not in spawned.keys(): logging.info('spawning %s' % svc_name) t = DNSSDRunner(file, svc) t.start() threads.append(t) spawned[file] = svc time.sleep(1) logging.info('quitting') for t in threads: t.join()