summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2004-10-01 21:02:50 +0000
committerNarayan Desai <desai@mcs.anl.gov>2004-10-01 21:02:50 +0000
commit8eaeab27c257a1643c9ed1c65ab05ce03836bf8e (patch)
tree6d603a57b006cece4c65c94cd63e5fbed64dc182
parentcbf3ba0935daf23a6916667a312db1a8eed2d71f (diff)
downloadbcfg2-8eaeab27c257a1643c9ed1c65ab05ce03836bf8e.tar.gz
bcfg2-8eaeab27c257a1643c9ed1c65ab05ce03836bf8e.tar.bz2
bcfg2-8eaeab27c257a1643c9ed1c65ab05ce03836bf8e.zip
refactor code
(Logical change 1.68) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@348 ce84e21b-d406-0410-9b95-82705330c041
-rw-r--r--src/sbin/bcfg2158
1 files changed, 100 insertions, 58 deletions
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, "<get-probes/>")
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)