diff options
Diffstat (limited to 'src/sbin')
-rw-r--r-- | src/sbin/Bcfg2debug | 70 | ||||
-rwxr-xr-x[-rw-r--r--] | src/sbin/GenerateHostInfo | 77 | ||||
-rwxr-xr-x[-rw-r--r--] | src/sbin/StatReports | 33 | ||||
-rwxr-xr-x[-rw-r--r--] | src/sbin/bcfg2 | 0 | ||||
-rwxr-xr-x | src/sbin/bcfg2-info | 154 | ||||
-rw-r--r-- | src/sbin/bcfg2-repo-validate (renamed from src/sbin/ValidateBcfg2Repo) | 33 | ||||
-rwxr-xr-x[-rw-r--r--] | src/sbin/bcfg2-server (renamed from src/sbin/Bcfg2Server) | 12 |
7 files changed, 230 insertions, 149 deletions
diff --git a/src/sbin/Bcfg2debug b/src/sbin/Bcfg2debug deleted file mode 100644 index 95508a5b4..000000000 --- a/src/sbin/Bcfg2debug +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -'''This tool loads the Bcfg2 core into an interactive debugger''' -__revision__ = '$Revision$' - - -from sys import argv -from time import sleep -from Bcfg2.Server.Core import Core, CoreInitError - -def get_input(): - '''read commands from stdin''' - try: - return raw_input('> ').split(" ") - except: - return [''] - -if __name__ == '__main__': - settings = {} - if '-c' in argv: - cfile = argv[-1] - else: - cfile = '/etc/bcfg2.conf' - try: - core = Core({}, cfile) - except CoreInitError, msg: - print "Core load failed because %s" % msg - raise SystemExit, 1 - for i in range(25): - core.fam.Service() - sleep(0.5) - cmd = get_input() - while cmd != ['']: - if cmd[0] in ['exit', 'quit']: - raise SystemExit, 0 - elif cmd[0] == 'generators': - for generator in core.generators: - print generator.__version__ - elif cmd[0] == 'help': - print 'Commands:' - print 'exit - quit' - print 'generators - list current versions of generators' - print 'help - print this text' - print 'mappings <type*> - print generator mappings for optional type' - print 'set <variable> <value> - set variable for later use' - print 'settings - display all settings' - print 'shell - shell out to native python interpreter' - print 'update - process pending fam events' - print 'version - print version of this tool' - elif cmd[0] == 'set': - settings[cmd[1]] = cmd[2] - elif cmd[0] == 'settings': - for (key, value) in settings.iteritems(): - print "%s --> %s" % (key, value) - elif cmd[0] == 'shell': - cmd = [''] - continue - elif cmd[0] == 'version': - print 'Bcfg2debug v. %s' % __revision__ - elif cmd[0] == 'mappings': - # dump all mappings unless type specified - for generator in core.generators: - print "Generator -> ", generator.__name__ - for key, value in generator.__provides__.iteritems(): - for instance in generator.__provides__[key].keys(): - print " ", key, instance - elif cmd[0] == 'update': - core.fam.Service() - else: - print "Unknown command %s" % cmd[0] - cmd = get_input() diff --git a/src/sbin/GenerateHostInfo b/src/sbin/GenerateHostInfo index 04d257e8a..67521d628 100644..100755 --- a/src/sbin/GenerateHostInfo +++ b/src/sbin/GenerateHostInfo @@ -6,42 +6,30 @@ __revision__ = '$Revision$' from ConfigParser import ConfigParser -from lxml.etree import Element, SubElement, parse -from os import fork, execl, dup2, wait +from lxml.etree import Element, SubElement, parse, tostring +from os import fork, execl, dup2, wait, uname import sys -def pretty_print(element, level=0): - '''Produce a pretty-printed text representation of element''' - if element.text: - fmt = "%s<%%s %%s>%%s</%%s>" % (level*" ") - data = (element.tag, (" ".join(["%s='%s'" % keyval for keyval in element.attrib.iteritems()])), - element.text, element.tag) - children = element.getchildren() - if children: - fmt = "%s<%%s %%s>\n" % (level*" ",) + (len(children) * "%s") + "%s</%%s>\n" % (level*" ") - data = (element.tag, ) + (" ".join(["%s='%s'" % (key, element.attrib[key]) for key in element.attrib]),) - data += tuple([pretty_print(entry, level+2) for entry in children]) + (element.tag, ) - else: - fmt = "%s<%%s %%s/>\n" % (level * " ") - data = (element.tag, " ".join(["%s='%s'" % (key, element.attrib[key]) for key in element.attrib])) - return fmt % data - - if __name__ == '__main__': c = ConfigParser() c.read(['/etc/bcfg2.conf']) configpath = "%s/etc/report-configuration.xml" % c.get('server', 'repository') - hostinfopath = "%s/etc/hostinfo.xml" % c.get('server', 'repository') - metadatapath = "%s/etc/metadata.xml" % c.get('server', 'repository') + clientdatapath = "%s/Metadata/clients.xml" % c.get('server', 'repository') sendmailpath = c.get('statistics','sendmailpath') - metaElement = parse(metadatapath) - hostlist = [client.get('name') for client in metaElement.findall("Client")] + clientElement = parse(clientdatapath) + hostlist = [client.get('name') for client in clientElement.findall("Client")] - HostInfo = Element("HostInformation") pids = {} fullnames = {} 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(pids.keys()) < 15: host = hostlist.pop() @@ -51,26 +39,39 @@ if __name__ == '__main__': dup2(null.fileno(), sys.__stdin__.fileno()) dup2(null.fileno(), sys.__stdout__.fileno()) dup2(null.fileno(), sys.__stderr__.fileno()) - execl('/bin/ping', 'ping', '-w', '5', '-c', '1', host) + if osname == 'Linux': + execl('/bin/ping', 'ping', '-w', '5', '-c', '1', host) + elif osname == 'Darwin': + 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() - chost = pids[cpid] - del pids[cpid] - if status == 0: - SubElement(HostInfo, "HostInfo", name=chost, fqdn=chost, pingable='Y') + except OSError: + continue + chost = pids[cpid] + del pids[cpid] + if status == 0: + try: + clientElement.xpath("//Client[@name='%s']"%chost)[0].set("pingable",'Y') + except:#i think this is for a problem with aliases? + clientElement.xpath("//Client[@name='%s']"%fullnames[chost])[0].set("pingable",'Y') + #also set pingtime, if you can get it + + else: + if chost.count('.') > 0: + fullnames[chost.split('.')[0]] = chost + hostlist.append(chost.split('.')[0]) else: - if chost.count('.') > 0: - fullnames[chost.split('.')[0]] = chost - hostlist.append(chost.split('.')[0]) - else: - SubElement(HostInfo, "HostInfo", name=fullnames[chost], fqdn=fullnames[chost], pingable='N') - except: - pass + clientElement.xpath("//Client[@name='%s']"%(fullnames[chost]))[0].set("pingable",'N') + #also set pingtime if you can get it - fout = open(hostinfopath, 'w') - fout.write(pretty_print(HostInfo)) + fout = open(clientdatapath, 'w') + fout.write(tostring(clientElement.getroot())) fout.close() diff --git a/src/sbin/StatReports b/src/sbin/StatReports index ef6a8df66..cb74eb4bb 100644..100755 --- a/src/sbin/StatReports +++ b/src/sbin/StatReports @@ -30,8 +30,7 @@ def generatereport(rspec, nrpt): pattern = re.compile( '|'.join([item.get("name") for item in reportspec.findall('Machine')])) for node in nodereprt.findall('Node'): - if not (node.findall("HostInfo") and node.findall("Statistics") and - node.find("HostInfo").get("fqdn") and pattern.match(node.get('name'))): + if not (node.findall("Statistics") and pattern.match(node.get('name'))): # don't know enough about node nodereprt.remove(node) continue @@ -151,8 +150,7 @@ if __name__ == '__main__': c.read(['/etc/bcfg2.conf']) configpath = "%s/etc/report-configuration.xml" % c.get('server', 'repository') statpath = "%s/etc/statistics.xml" % c.get('server', 'repository') - hostinfopath = "%s/etc/hostinfo.xml" % c.get('server', 'repository') - metadatapath = "%s/etc/metadata.xml" % c.get('server', 'repository') + clientsdatapath = "%s/Metadata/clients.xml" % c.get('server', 'repository') transformpath = "/usr/share/bcfg2/xsl-transforms/" #websrcspath = "/usr/share/bcfg2/web-rprt-srcs/" @@ -173,12 +171,12 @@ if __name__ == '__main__': #See if hostinfo.xml exists, and is less than 23.5 hours old - try: - hostinstat = os.stat(hostinfopath) - if (time() - hostinstat[9])/(60*60) > 23.5: - os.system('GenerateHostInfo')#Generate HostInfo needs to be in path - except OSError: - os.system('GenerateHostInfo')#Generate HostInfo needs to be in path + #try: + #hostinstat = os.stat(hostinfopath) + #if (time() - hostinstat[9])/(60*60) > 23.5: + os.system('GenerateHostInfo')#Generate HostInfo needs to be in path + #except OSError: + # os.system('GenerateHostInfo')#Generate HostInfo needs to be in path '''Reads Data & Config files''' @@ -193,16 +191,10 @@ if __name__ == '__main__': print("StatReports: Failed to parse %s"%(configpath)) raise SystemExit, 1 try: - metadata = XML(open(metadatapath).read()) + clientsdata = XML(open(clientsdatapath).read()) except (IOError, XMLSyntaxError): - print("StatReports: Failed to parse %s"%(metadatapath)) + print("StatReports: Failed to parse %s"%(clientsdatapath)) raise SystemExit, 1 - try: - hostinfodata = XML(open(hostinfopath).read()) - except (IOError, XMLSyntaxError): - print("StatReports: Failed to parse %s. Is GenerateHostInfo in your path?"%(hostinfopath)) - raise SystemExit, 1 - #Merge data from three sources nodereport = Element("Report", attrib={"time" : asctime()}) @@ -210,12 +202,9 @@ if __name__ == '__main__': #should all of the other info in Metadata be appended? #What about all of the package stuff for other types of reports? - for client in metadata.findall("Client"): + for client in clientsdata.findall("Client"): nodel = Element("Node", attrib={"name" : client.get("name")}) nodel.append(client) - for hostinfo in hostinfodata.findall("HostInfo"): - if hostinfo.get("name") == client.get("name"): - nodel.append(hostinfo) for nod in statsdata.findall("Node"): if client.get('name').find(nod.get('name')) == 0: diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index fcc3a757c..fcc3a757c 100644..100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info new file mode 100755 index 000000000..e325b2fd0 --- /dev/null +++ b/src/sbin/bcfg2-info @@ -0,0 +1,154 @@ +#!/usr/bin/python -i +'''This tool loads the Bcfg2 core into an interactive debugger''' +__revision__ = '$Revision$' + +from sys import argv +from time import sleep +from Bcfg2.Server.Core import Core, CoreInitError +from lxml.etree import tostring + +def print_tabular(rows): + '''print data in tabular format''' + cmax = tuple([max([len(str(row[index])) for row in rows]) + 1 for index in xrange(len(rows[0]))]) + fstring = (" %%-%ss |" * len(cmax)) % cmax + fstring = ('|'.join([" %%-%ss "] * len(cmax))) % cmax + print fstring % rows[0] + print (sum(cmax) + (len(cmax) * 2) + (len(cmax) - 1)) * '=' + for row in rows[1:]: + print fstring % row + +def get_input(): + '''read commands from stdin''' + try: + return raw_input('> ').split(" ") + except: + return [''] + +def do_build(cmd, core): + '''build client configuration''' + if len(cmd) == 3: + output = open(cmd[2], 'w') + output.write(tostring(core.BuildConfiguration(cmd[1]))) + output.close() + else: + print 'Usage: build <hostname> <output file>' + +def do_bundles(cmd, core): + '''print out group/bundle info''' + data = [('Group', 'Bundles')] + groups = core.metadata.groups.keys() + groups.sort() + for group in groups: + data.append((group, ','.join(core.metadata.groups[group][0]))) + print_tabular(data) + +def do_clients(cmd, core): + '''print out client info''' + data = [('Client', 'Profile')] + clist = core.metadata.clients.keys() + clist.sort() + for client in clist: + data.append((client, core.metadata.clients[client])) + print_tabular(data) + +def do_help(cmd, core): + '''print out usage info''' + print 'Commands:' + print 'build <hostname> <filename> - build config for hostname, writing to filename' + print 'bundles - print out group/bundle information' + print 'clients - print out client/profile information' + print 'debug - shell out to native python interpreter' + print 'generators - list current versions of generators' + print 'groups - list groups' + print 'help - print this text' + print 'mappings <type*> <name*>- print generator mappings for optional type and name' + print 'quit' + print 'update - process pending file events' + print 'version - print version of this tool' + +def do_generators(cmd, core): + '''print out generator info''' + for generator in core.generators: + print generator.__version__ + +def do_groups(cmd, core): + '''print out group info''' + data = [("Groups", "Profile", "Category", "Contains")] + grouplist = core.metadata.groups.keys() + grouplist.sort() + for group in grouplist: + if group in core.metadata.profiles: + prof = 'yes' + else: + prof = 'no' + if core.metadata.categories.has_key(group): + cat = core.metadata.categories[group] + else: + cat = '' + gdata = [grp for grp in core.metadata.groups[group][1]] + gdata.remove(group) + data.append((group, prof, cat, ','.join(gdata))) + print_tabular(data) + +def do_mappings(cmd, core): + '''print out mapping info''' + # dump all mappings unless type specified + data = [('Plugin', 'Type', 'Name')] + for generator in core.generators: + if len(cmd) == 1: + etypes = generator.Entries.keys() + elif len(cmd) > 1: + etypes = [cmd[1]] + if len(cmd) == 3: + interested = [(etype, [cmd[2]]) for etype in etypes] + else: + interested = [(etype, generator.Entries[etype].keys()) for etype in etypes + if generator.Entries.has_key(etype)] + if [etype for (etype, names) in interested + if generator.Entries.has_key(etype) and [name for name in names + if generator.Entries[etype].has_key(name)]]: + for (etype, names) in interested: + for name in names: + if generator.Entries.has_key(etype) and generator.Entries[etype].has_key(name): + data.append((generator.__name__, etype, name)) + print_tabular(data) + +def do_quit(cmd, core): + '''exit program''' + raise SystemExit, 0 + +def do_update(cmd, core): + '''Process pending fs events''' + core.fam.Service() + +def do_version(cmd, core): + '''print out code version''' + print __revision__ + +if __name__ == '__main__': + dispatch = {'build': do_build, 'bundles': do_bundles, 'clients': do_clients, + 'generators': do_generators, 'groups': do_groups, + 'help': do_help, 'mappings': do_mappings, 'quit': do_quit, + 'update': do_update, 'version': do_version} + if '-c' in argv: + cfile = argv[-1] + else: + cfile = '/etc/bcfg2.conf' + try: + bcore = Core({}, cfile) + except CoreInitError, msg: + print "Core load failed because %s" % msg + raise SystemExit, 1 + for i in range(25): + bcore.fam.Service() + sleep(0.5) + ucmd = get_input() + while True: + if ucmd[0] == 'debug': + break + else: + if dispatch.has_key(ucmd[0]): + dispatch[ucmd[0]](ucmd, bcore) + else: + print "Unknown command %s" % ucmd[0] + ucmd = get_input() diff --git a/src/sbin/ValidateBcfg2Repo b/src/sbin/bcfg2-repo-validate index a1b9552ce..a87b31cc6 100644 --- a/src/sbin/ValidateBcfg2Repo +++ b/src/sbin/bcfg2-repo-validate @@ -1,7 +1,7 @@ #!/usr/bin/env python -'''ValidateBcfg2Repo checks all xml files in Bcfg2 repos against their respective XML schemas''' -__revision__ = '0.7.3' +'''bcfg2-repo-validate checks all xml files in Bcfg2 repos against their respective XML schemas''' +__revision__ = '$Revision$' from glob import glob from lxml.etree import parse, XMLSchema @@ -12,27 +12,32 @@ from ConfigParser import ConfigParser, NoSectionError, NoOptionError if __name__ == '__main__': cf = ConfigParser() schemadir = '/usr/share/bcfg2/schemas' - cf.read(['/etc/bcfg2.conf']) - try: - repo = cf.get('server', 'repository') - except (NoSectionError, NoOptionError): - if len(argv) == 1: + if len(argv) > 1: + repo = argv[1] + else: + cf.read(['/etc/bcfg2.conf']) + try: + repo = cf.get('server', 'repository') + except (NoSectionError, NoOptionError): print "Repository location not specified in config file or on command line" - print "Usage: validate_repo <repo directory>" + print "Usage: bcfg2-repo-validate <repo directory>" raise SystemExit, 1 - repo = argv[1] # add more validation as more schemas get written - filesets = {'metadata':("%s/etc/metadata.xml", "%s/metadata.xsd"), + filesets = {'metadata':("%s/Metadata/groups.xml", "%s/metadata.xsd"), + 'clients':("%s/Metadata/clients.xml", "%s/clients.xsd"), 'bundle':("%s/Bundler/*.xml", "%s/bundle.xsd"), 'pkglist':("%s/Pkgmgr/*.xml", "%s/pkglist.xsd"), - 'base':("%s/etc/base.xml", "%s/base.xsd"), - 'imageinfo':("%s/etc/imageinfo.xml", "%s/translation.xsd"), + 'base':("%s/Base/*.xml", "%s/base.xsd"), 'imageinfo':("%s/etc/reports.xml", "%s/report-configuration.xsd"), - 'services':("%s/etc/services.xml", "%s/services.xsd")} + 'services':("%s/Svcmgr/*.xml", "%s/services.xsd")} for k, (spec, schemaname) in filesets.iteritems(): - schema = XMLSchema(parse(open(schemaname%(schemadir)))) + try: + schema = XMLSchema(parse(open(schemaname%(schemadir)))) + except: + print "Failed to process schema %s" % (schemaname%(schemadir)) + continue for filename in glob(spec%(repo)): try: datafile = parse(open(filename)) diff --git a/src/sbin/Bcfg2Server b/src/sbin/bcfg2-server index c1b93644b..2da6ff325 100644..100755 --- a/src/sbin/Bcfg2Server +++ b/src/sbin/bcfg2-server @@ -1,7 +1,7 @@ #!/usr/bin/env python '''The XML-RPC Bcfg2 Server''' -__revision__ = '$Revision:$' +__revision__ = '$Revision$' from getopt import getopt, GetoptError from sys import argv, exc_info @@ -77,7 +77,7 @@ def verbose(message): syslog(LOG_INFO, "%s" % (message)) def print_usage(opt, vopt, descs, argDescs): - print "Bcfg2Server usage:" + print "bcfg2-server usage:" for arg in opt.iteritems(): print " -%s\t\t\t%s" % (arg[0], descs[arg[0]]) for arg in vopt.iteritems(): @@ -176,6 +176,8 @@ class Bcfg2(Component): return False def resolve_client(self, client): + if self.setup['client']: + return self.setup['client'] try: return gethostbyaddr(client)[0] except herror: @@ -189,7 +191,7 @@ class Bcfg2(Component): resp = Element('probes') try: - meta = self.Core.metadata.FetchMetadata(client) + meta = self.Core.metadata.get_metadata(client) for generator in self.Core.generators: for probe in generator.GetProbes(meta): @@ -241,8 +243,8 @@ class Bcfg2(Component): # Update statistics self.Core.stats.updateStats(sdata, client) - verbose("Client %s reported state %s" % - (client, state.attrib['state'])) + syslog(LOG_INFO, "Client %s reported state %s" % + (client, state.attrib['state'])) return "<ok/>" if __name__ == '__main__': |