from xml.sax import make_parser, handler from sets import Set from os.path import getmtime class SteelToeXML(handler.ContentHandler): def __init__(self, filename="/etc/steeltoe/steeltoe.xml"): self.filename = filename self.reload() def reload(self): self.mtimes = {self.filename: getmtime(self.filename)} self.config = {'bootloader': {}} self.hosts = [] self.hostnames = Set() self.groups = [] self.groupnames = Set() self.trees = [] self.treenames = Set() self.meta = {} # tree metadata index self._context = [] self._curname = "" parser = make_parser() parser.setContentHandler(self) parser.parse(self.filename) def refresh(self): reload = False for (fn, mtime) in self.mtimes.items(): if mtime != getmtime(fn): reload = True if reload: self.reload() def get_group(self, name): return [x for x in self.groups if x['name'] == name][0] def get_host(self, name): return [x for x in self.hosts if x['name'] == name][0] def characters(self, content): self._text = self._text + content def startElement(self, name, attrs): if name in ['config', 'tree', 'host', 'bootloader', 'kickstart', 'meta']: self._context.append(name) if name in ['group', 'tree', 'host']: self._curname = attrs['name'] if name == 'repo': if not self._curtree.has_key(name): self._curtree[name] = [attrs['name']] else: self._curtree[name].append(attrs['name']) if name == 'host': self._curhost = {'name': self._curname} self.hostnames.add(self._curname) if name == 'tree': self._curtree = {'name': self._curname, 'meta': {}} self.treenames.add(self._curname) if name == 'group': self.groupnames.add(self._curname) # Hack to handle simple XIncludes if name == 'xi:include': href = attrs['href'] self.mtimes[href] = getmtime(href) subp = make_parser() subp.setContentHandler(self) subp.parse(href) self._text = "" def _parent(self): if len(self._context): return self._context[-1] else: None def endElement(self, name): self._text = self._text.strip() if self._parent() == name: self._context.pop() if self._parent() == 'config': self.config[name] = self._text elif self._parent() == 'bootloader': self.config['bootloader'][name] = self._text elif name == 'group': self.groups.append({ 'name': self._curname, 'members': self._text.split()}) self._curname = None elif self._parent() == 'kickstart' or name == 'kickstart': # Ignore the kickstart sections for now pass elif self._parent() == 'host': self._curhost[name] = self._text elif name == 'host': self.hosts.append(self._curhost) self._curname = None elif self._parent() == 'meta': self._curtree['meta'][name] = self._text if not self.meta.has_key(name): self.meta[name] = {self._text: Set([self._curname])} elif not self.meta[name].has_key(self._text): self.meta[name][self._text] = Set([self._curname]) else: self.meta[name][self._text].add(self._curname) elif self._parent() == 'tree': if name == 'path': self._curtree[name] = self._text elif name == 'tree': self.trees.append(self._curtree) self._curname = None steeltoe = SteelToeXML()