#!/usr/bin/env python from getopt import getopt, GetoptError from os import popen, chmod, unlink from sys import argv, exit from string import join from tempfile import mktemp from elementtree.ElementTree import Element, XML, tostring from sss.ssslib import comm_lib from Bcfg2.Client.Debian import Debian def RunProbe(probe): ret = Element("probe-data", name=probe.attrib['name'], source=probe.attrib['source']) script = open(mktemp(), 'w+') script.write("#!%s\n"%(probe.attrib.get('interpreter', '/bin/sh'))) script.write(probe.text) script.close() chmod(script.name, 0755) ret.text = popen(script.name).read() unlink(script.name) return ret 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 if __name__ == '__main__': # parse command line options options = {'v':'verbose','q':'quick', 'd':'debug', 'n':'dryrun', 'B':'build', 'p':'paranoid'} doptions = {'b':'bundle', 'f':'file', 'c':'cache', 'p':'profile', 'i':'image'} setup = dgetopt(argv[1:], options, doptions) print setup # connect to bcfg2d comm = comm_lib() h = comm.ClientInit("bcfg2") # get probes comm.SendMessage(h, "") data = comm.RecvMessage(h) #if setup['verbose']: print data probes = XML(data) # execute probes probedata = map(RunProbe, probes.findall(".//probe")) # upload probe responses cpd = Element("probe-data") map(lambda x:cpd.append(x), probedata) if setup['verbose'] : print tostring(cpd) comm.SendMessage(h, tostring(cpd)) r = comm.RecvMessage(h) msg = Element("get-config") if setup['profile']: msg.attrib['profile'] = setup['profile'] if setup['image']: msg.attrib['image'] = setup['image'] # get config comm.SendMessage(h, tostring(msg)) r = comm.RecvMessage(h) if setup['cache']: try: open(setup['cache'], 'w').write(r) except: print "failed to write config cache file %s"%(setup['cache']) cfg = XML(r) if cfg.tag == 'error': print "got error from server" exit(1) client = Debian(cfg, setup) # verify state client.Inventory() # summarize current state print "--> %s of %s config elements correct"%(client.states.values().count(True), len(client.states.values())) # install incorrect aspects of configuration client.Install() print "--> %s of %s config elements correct"%(client.states.values().count(True), len(client.states.values())) print "bad:" for k,v in client.states.iteritems(): if not v: print "%s:%s"%(k.tag, k.attrib['name']) # upload statistics m = Element("upload-statistics") stats = client.GenerateStats() m.append(stats) comm.SendMessage(h, tostring(m)) r = comm.RecvMessage(h) # clean up comm.ClientClose(h)