From 6f728506855962f67fdc14ececd1fbefd0281f10 Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Wed, 7 Sep 2005 17:35:15 +0000 Subject: switch Construct call 2005/09/06 21:15:34-05:00 anl.gov!desai switch to new Plugin API 2005/09/06 21:14:38-05:00 anl.gov!desai Rename: src/lib/Server/Structures/Bundler.py -> src/lib/Server/Plugins/Bundler.py (Logical change 1.300) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1201 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Plugins/Bundler.py | 122 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'src/lib/Server/Plugins/Bundler.py') diff --git a/src/lib/Server/Plugins/Bundler.py b/src/lib/Server/Plugins/Bundler.py index e69de29bb..81b21435a 100644 --- a/src/lib/Server/Plugins/Bundler.py +++ b/src/lib/Server/Plugins/Bundler.py @@ -0,0 +1,122 @@ +'''This provides bundle clauses with translation functionality''' +__revision__ = '$Revision$' + +from copy import deepcopy +from syslog import LOG_ERR, syslog + +from Bcfg2.Server.Generator import SingleXMLFileBacked, XMLFileBacked, DirectoryBacked +from Bcfg2.Server.Plugin import Plugin + +from elementtree.ElementTree import Element, XML +from xml.parsers.expat import ExpatError + +class ImageFile(SingleXMLFileBacked): + '''This file contains image -> system mappings''' + def __init__(self, filename, fam): + self.images = {} + SingleXMLFileBacked.__init__(self, filename, fam) + + def Index(self): + '''Build data structures out of the data''' + try: + xdata = XML(self.data) + except ExpatError, err: + syslog(LOG_ERR, "Failed to parse file %s" % (self.name)) + syslog(LOG_ERR, err) + del self.data + return + self.images = {} + for child in xdata.getchildren(): + [name, pkg, service] = [child.get(field) for field in ['name', 'package', 'service']] + for grandchild in child.getchildren(): + self.images[grandchild.get('name')] = (name, pkg, service) + +class Bundle(XMLFileBacked): + '''Bundles are configuration specifications (with image/translation abstraction)''' + + def __init__(self, filename): + self.all = [] + self.attributes = {} + self.systems = {} + XMLFileBacked.__init__(self, filename) + + def Index(self): + '''Build data structures from the source data''' + try: + xdata = XML(self.data) + except ExpatError, err: + syslog(LOG_ERR, "Failed to parse file %s" % (self.name)) + syslog(LOG_ERR, str(err)) + del self.data + return + self.all = [] + self.systems = {} + self.attributes = {} + for entry in xdata.getchildren(): + if entry.tag == 'System': + self.systems[entry.attrib['name']] = entry.getchildren() + elif entry.tag == 'Attribute': + self.attributes[entry.get('name')] = entry.getchildren() + else: + self.all.append(entry) + del self.data + + def BuildBundle(self, metadata, system): + '''Build a bundle for a particular client''' + bundlename = self.name.split('/')[-1] + bundle = Element('Bundle', name=bundlename) + for entry in self.all + self.systems.get(system, []): + bundle.append(deepcopy(entry)) + for attribute in [aname for (scope, aname) in [item.split('.') for item in metadata.attributes] + if scope == bundlename[:-4]]: + for entry in self.attributes.get(attribute, []): + bundle.append(deepcopy(entry)) + return bundle + +class BundleSet(DirectoryBacked): + '''The Bundler handles creation of dependent clauses based on bundle definitions''' + __child__ = Bundle + +class Bundler(Plugin): + '''The bundler creates dependent clauses based on the bundle/translation scheme from bcfg1''' + __name__ = 'Bundler' + __version__ = '$Id$' + __author__ = 'bcfg-dev@mcs.anl.gov' + + def __init__(self, core, datastore): + Plugin.__init__(self, core, datastore) + self.imageinfo = ImageFile("%s/etc/imageinfo.xml"%(datastore), self.core.fam) + self.bundles = BundleSet(self.data, self.core.fam) + + def BuildStructures(self, metadata): + '''Build all structures for client (metadata)''' + try: + (system, package, service) = self.GetTransInfo(metadata) + except KeyError: + syslog(LOG_ERR, "Failed to find translation information for image %s" % metadata.image) + return [] + bundleset = [] + for bundlename in metadata.bundles: + if not self.bundles.entries.has_key("%s.xml"%(bundlename)): + syslog(LOG_ERR, "Client %s requested nonexistent bundle %s"%(metadata.hostname, bundlename)) + continue + + bundle = self.bundles.entries["%s.xml" % (bundlename)].BuildBundle(metadata, system) + # now we need to populate service/package types + for entry in bundle.getchildren(): + if entry.tag == 'Package': + entry.attrib['type'] = package + elif entry.tag == 'Service': + entry.attrib['type'] = service + bundleset.append(bundle) + return bundleset + + def GetTransInfo(self, metadata): + '''Get Translation info for metadata.image''' + if self.imageinfo.images.has_key(metadata.image): + return self.imageinfo.images[metadata.image] + else: + raise KeyError, metadata.image + + + -- cgit v1.2.3-1-g7c22