#!/usr/bin/env python #GenerateHostInfo - Joey Hagedorn - hagedorn@mcs.anl.gov """Generates hostinfo.xml at a regular interval.""" __revision__ = '$Revision$' from os import dup2, execl, fork, uname, wait import sys import time import lxml.etree import Bcfg2.Options if __name__ == '__main__': opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY, 'configfile': Bcfg2.Options.CFILE} setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) cfpath = setup['configfile'] clientdatapath = "%s/Metadata/clients.xml" % setup['repo'] clientElement = lxml.etree.parse(clientdatapath) hostlist = [client.get('name') for client in clientElement.findall("Client")] pids = {} null = open('/dev/null', 'w+') #use uname to detect OS and use -t for darwin and -w for linux #/bin/ping on linux /sbin/ping on os x osname = uname()[0] while hostlist or pids: if hostlist and len(list(pids.keys())) < 15: host = hostlist.pop() pid = fork() if pid == 0: # in child dup2(null.fileno(), sys.__stdin__.fileno()) dup2(null.fileno(), sys.__stdout__.fileno()) dup2(null.fileno(), sys.__stderr__.fileno()) if osname == 'Linux': execl('/bin/ping', 'ping', '-w', '5', '-c', '1', host) elif osname in ['Darwin', 'FreeBSD']: execl('/sbin/ping', 'ping', '-t', '5', '-c', '1', host) elif osname == 'SunOS': execl('/usr/sbin/ping', 'ping', host, '56', '1') else: # default execl('/bin/ping', 'ping', '-w', '5', '-c', '1', host) else: pids[pid] = host else: try: (cpid, status) = wait() except OSError: continue chost = pids[cpid] del pids[cpid] elm = clientElement.xpath("//Client[@name='%s']" % chost)[0] if status == 0: elm.set("pingable", 'Y') elm.set("pingtime", str(time.time())) else: elm.set("pingable", 'N') fout = open(clientdatapath, 'w') fout.write(lxml.etree.tostring(clientElement.getroot(), encoding='UTF-8', xml_declaration=True)) fout.close()