#!/usr/bin/env python # $Id: $ from getopt import getopt, GetoptError from socket import gethostbyaddr, herror from string import join, split from syslog import syslog, LOG_INFO, LOG_ERR from sys import argv, exit, exc_info from time import time from traceback import extract_tb from ConfigParser import ConfigParser from elementtree.ElementTree import Element, tostring from Bcfg2.Server.Core import Core from Bcfg2.Server.Metadata import MetadataStore from sss.daemonize import daemonize from sss.restriction import DataSet, Data from sss.server import Server def dgetopt(arglist, opt, vopt): r = {} for o in opt.values() + vopt.values(): r[o] = False gstr = join(opt.keys()) + join([x+':' for x in vopt.keys()]) try: (o, a) = getopt(arglist, gstr) except GetoptError, g: print g print "bcfg2 Usage:" for (k,v) in opt.iteritems(): print " -%s %s"%(k,v) for (k,v) in vopt.iteritems(): print " -%s <%s>"%(k,v) exit(1) for (gopt,garg) in o: option = gopt[1:] if opt.has_key(option): r[opt[option]] = True else: r[vopt[option]] = garg return r class BcfgServer(Server): __implementation__ = 'Bcfg2' __component__ = 'bcfg2' __dispatch__ = {'get-config':'BuildConfig', 'get-probes':'GetProbes', 'probe-data':'CommitProbeData', 'upload-statistics':'HandleStats'} __validate__ = 0 def __setup__(self): self.setup = self.kwargs['setup'] c = ConfigParser() c.read([self.kwargs.get('configfile', '/etc/bcfg2.conf')]) repo = c.get('server','repository') generators = split(c.get('server','generators'),',') structures = split(c.get('server', 'structures'),',') mpath = c.get('server','metadata') self.core = Core(repo, structures, generators) self.metadata = MetadataStore("%s/metadata.xml"%(mpath), self.core.fam) self.__progress__() def __progress__(self): while self.core.fam.fm.pending(): self.core.fam.HandleEvent() try: self.core.RunCronTasks() except: self.LogFailure("Cron") return 0 def BuildConfig(self, xml, (peer,port)): if setup['client']: client = setup['client'] else: try: client = gethostbyaddr(peer)[0].split('.')[0] except herror: return Element("error", type='host resolution error') t = time() config = Element("Configuration", version='2.0') # get metadata for host if xml.attrib.has_key("profile") and xml.attrib.has_key("image"): m = self.metadata.FetchMetadata(client, image=xml.attrib['image'], profile=xml.attrib['profile']) else: m = self.metadata.FetchMetadata(client) try: structures = self.core.GetStructures(m) except: self.LogFailure("GetStructures") return Element("error", type='structure error') for s in structures: try: self.core.BindStructure(s, m) config.append(s) except: self.LogFailure("BindStructure") #for x in s.getchildren(): # print x.attrib['name'], '\000' in tostring(x) syslog(LOG_INFO, "Generated config for %s in %s seconds"%(client, time()-t)) return config def GetProbes(self, xml, (peer,port)): r = Element('probes') try: client = gethostbyaddr(peer)[0].split('.')[0] except herror: return Element("error", type='host resolution error') m = self.GetMetadata(client) for g in self.core.generators: for p in g.GetProbes(m): r.append(p) return r def CommitProbeData(self, xml, (peer,port)): try: client = gethostbyaddr(peer)[0].split('.')[0] except herror: return Element("error", type='host resolution error') for data in xml.findall(".//probe-data"): try: [g] = [x for x in self.core.generators if x.__name__ == data.attrib['source']] g.AcceptProbeData(client, data) except: self.LogFailure("CommitProbeData") return Element("OK") def HandleStats(self, xml, (peer, port)): syslog(LOG_INFO, "Client %s reported state %s"%(peer, xml.attrib['state'])) return Element("ok") def LogFailure(self, failure): (t,v,tb)=exc_info() syslog(LOG_ERR, "Unexpected failure in %s"%(failure)) for line in extract_tb(tb): syslog(LOG_ERR, ' File "%s", line %i, in %s\n %s\n'%line) syslog(LOG_ERR, "%s: %s\n"%(t,v)) del t,v,tb if __name__ == '__main__': options = {'v':'verbose','d':'debug'} doptions = {'D':'daemon', 'C':'client'} setup = dgetopt(argv[1:], options, doptions) print setup if setup['daemon']: daemonize(setup['daemon']) server = BcfgServer(setup=setup) for i in range(10): server.__progress__() server.ServeForever()