From 8eaeab27c257a1643c9ed1c65ab05ce03836bf8e Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Fri, 1 Oct 2004 21:02:50 +0000 Subject: refactor code (Logical change 1.68) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@348 ce84e21b-d406-0410-9b95-82705330c041 --- src/sbin/bcfg2 | 158 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 58 deletions(-) (limited to 'src/sbin') diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 1741e748b..badec4d5c 100644 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -12,6 +12,14 @@ from sss.ssslib import comm_lib from Bcfg2.Client.Debian import Debian +def ElementMatch(master, sub): + if master.tag == sub.tag: + for k in sub.attrib.keys(): + if master.attrib[k] != sub.attrib[k]: + return False + return True + return False + def RunProbe(probe): ret = Element("probe-data", name=probe.attrib['name'], source=probe.attrib['source']) script = open(mktemp(), 'w+') @@ -46,6 +54,85 @@ def dgetopt(arglist, opt, vopt): r[vopt[option]] = garg return r +class ClientState(object): + def __init__(self, cfg, setup): + self.states = {} + self.structures = {} + self.cfg = cfg + self.setup = setup + self.modified = [] + self.extra = [] + self.toolset = Debian(cfg, setup) + + def LogFailure(self, area, entry): + print "Failure in %s for entry: %s"%(area, tostring(entry)) + (t,v,tb) = exc_info() + for line in extract_tb(tb): + print "File %s, line %i, in %s\n %s\n"%(line) + print "%s: %s\n"%(t,v) + del t,v,tb + + def VerifyEntry(self, entry, modlist = []): + try: + method = getattr(self.toolset, "Verify%s"%(entry.tag)) + # verify state and stash value in state + if entry.tag == 'Package': + self.states[entry] = method(entry, modlist) + else: + self.states[entry] = method(entry) + + if self.setup['debug']: + print entry.attrib['name'], self.states[entry] + except: + self.LogFailure("Verify", entry) + + def InstallEntry(self, entry): + try: + method = getattr(self.toolset, "Install%s"%(entry.tag)) + self.states[entry] = method(entry) + except: + self.LogFailure("Install", entry) + + def Inventory(self): + # build initial set of states + unexamined = map(lambda x:(x,[]), self.cfg.getchildren()) + while unexamined: + (r, modlist) = unexamined.pop() + if r.tag not in ['Bundle', 'Independant']: + self.VerifyEntry(r, modlist) + else: + modlist = [x.attrib['name'] for x in r.getchildren() if x.tag == 'ConfigFile'] + unexamined += map(lambda x:(x,modlist), r.getchildren()) + self.structures[r] = False + + for structure in self.cfg.getchildren(): + self.CheckStructure(structure) + + # TwoWay: build list of "extra configs" + #e = self.toolset.FindElements() + #known = self.states.keys() + #for entry in e: + # if not filter(lambda x:ElementMatch(x, entry), known): + # self.extra.append(entry) + #print self.extra + + def CheckStructure(self, structure): + if structure in self.modified: + self.modified.remove(structure) + if structure.tag == 'Bundle': + # check for clobbered data + modlist = [x.attrib['name'] for x in structure.getchildren() if x.tag == 'ConfigFile'] + for entry in structure.getchildren(): + self.VerifyEntry(entry, modlist) + state = map(lambda x:self.states[x], structure.getchildren()) + if False not in state: + self.structures[structure] = True + + def Install(self): + self.modified = [k for (k,v) in self.structures.iteritems() if not v] + for entry in [k for (k,v) in self.states.iteritems() if not v]: + self.InstallEntry(entry) + if __name__ == '__main__': # parse command line options options = {'v':'verbose','q':'quick', 'd':'debug', 'n':'dryrun', 'B':'build', 'p':'paranoid'} @@ -60,7 +147,7 @@ if __name__ == '__main__': # get probes comm.SendMessage(h, "") data = comm.RecvMessage(h) - if setup['verbose']: print data + #if setup['verbose']: print data probes = XML(data) # execute probes probedata = map(RunProbe, probes.findall(".//probe")) @@ -86,64 +173,19 @@ if __name__ == '__main__': print "got error from server" exit(1) - # initialize toolset stuff - toolset = Debian(cfg, setup) - + client = ClientState(cfg, setup) # verify state - unexamined = cfg.getchildren() - structurestate = {} - entrystate = {} - while unexamined: - r = unexamined.pop() - unexamined += r.getchildren() - if r.tag in ['Bundle', 'Image']: - structurestate[r] = False - continue - try: - method = getattr(toolset, "Verify%s"%(r.tag)) - except: - print ":failed: for %s :failed:"%(tostring(r)) - continue - # verify state and stash value in state - entrystate[r] = method(r) - if setup['debug']: - print r.attrib['name'], entrystate[r] - - # now we go back to check structures - for structure in cfg.getchildren(): - for child in structure.getchildren(): - if not entrystate[child]: - break - structurestate[structure] = True - - for entry in [k for (k,v) in entrystate.iteritems() if not v]: - method = getattr(toolset, "Install%s"%(entry.tag)) - try: - entrystate[entry] = method(entry) - except: - print "Install failed for %s"%(tostring(entry)) - (t,v,tb) = exc_info() - print "Unexpected failure in Install:" - for line in extract_tb(tb): - print "File %s, line %i, in %s\n %s\n"%(line) - print "%s: %s\n"%(t,v) - del t,v,tb - - for structure in structurestate.keys(): - if structurestate[structure]: - continue - for entry in structure.getchildren(): - entrystate[entry] = getattr(toolset, "Verify%s"%(entry.tag)) - states = map(lambda x:entrystate[x], structure.getchildren()) - if False not in states: - structurestate[structure] = True - - #print entrystate - print "good:", - for k,v in entrystate.iteritems(): - if v: - print k.attrib['name'], - + client.Inventory() + + # summarize current state + print "--> %s of %s config elements correct"%(client.states.values().count(True), len(client.states.values())) + 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']) # install config # upload statistics comm.ClientClose(h) -- cgit v1.2.3-1-g7c22