"""This provides bundle clauses with translation functionality.""" __revision__ = '$Revision$' import copy import lxml.etree import os import os.path import re import sys import Bcfg2.Server import Bcfg2.Server.Plugin try: import genshi.template import genshi.template.base import Bcfg2.Server.Plugins.SGenshi have_genshi = True except: have_genshi = False class BundleFile(Bcfg2.Server.Plugin.StructFile): def get_xml_value(self, metadata): bundlename = os.path.splitext(os.path.basename(self.name))[0] bundle = lxml.etree.Element('Bundle', name=bundlename) [bundle.append(copy.copy(item)) for item in self.Match(metadata)] return bundle class Bundler(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Structure, Bcfg2.Server.Plugin.XMLDirectoryBacked): """The bundler creates dependent clauses based on the bundle/translation scheme from Bcfg1. """ name = 'Bundler' __version__ = '$Id$' __author__ = 'bcfg-dev@mcs.anl.gov' patterns = re.compile('^(?P.*)\.(xml|genshi)$') def __init__(self, core, datastore): Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) Bcfg2.Server.Plugin.Structure.__init__(self) self.encoding = core.encoding self.__child__ = self.template_dispatch try: Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data, self.core.fam) except OSError: self.logger.error("Failed to load Bundle repository") raise Bcfg2.Server.Plugin.PluginInitError def template_dispatch(self, name): bundle = lxml.etree.parse(name, parser=Bcfg2.Server.XMLParser) nsmap = bundle.getroot().nsmap if name.endswith('.xml'): if have_genshi and \ (nsmap == {'py': 'http://genshi.edgewall.org/'}): # allow for genshi bundles with .xml extensions spec = Bcfg2.Server.Plugin.Specificity() return Bcfg2.Server.Plugins.SGenshi.SGenshiTemplateFile(name, spec, self.encoding) else: return BundleFile(name) elif name.endswith('.genshi'): if have_genshi: spec = Bcfg2.Server.Plugin.Specificity() return Bcfg2.Server.Plugins.SGenshi.SGenshiTemplateFile(name, spec, self.encoding) def BuildStructures(self, metadata): """Build all structures for client (metadata).""" bundleset = [] bundle_entries = {} for key, item in self.entries.items(): bundle_entries.setdefault(self.patterns.match(os.path.basename(key)).group('name'), []).append(item) for bundlename in metadata.bundles: try: entries = bundle_entries[bundlename] except KeyError: self.logger.error("Bundler: Bundle %s does not exist" % bundlename) continue try: bundleset.append(entries[0].get_xml_value(metadata)) except genshi.template.base.TemplateError: t = sys.exc_info()[1] self.logger.error("Bundler: Failed to template genshi bundle %s" % bundlename) self.logger.error(t) except: self.logger.error("Bundler: Unexpected bundler error for %s" % bundlename, exc_info=1) return bundleset