summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Plugins/Bundler.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Bcfg2/Server/Plugins/Bundler.py')
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Bundler.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py
new file mode 100644
index 000000000..ccb99481e
--- /dev/null
+++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py
@@ -0,0 +1,99 @@
+"""This provides bundle clauses with translation functionality."""
+
+import copy
+import lxml.etree
+import os
+import os.path
+import re
+import sys
+
+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'
+ __author__ = 'bcfg-dev@mcs.anl.gov'
+ patterns = re.compile('^(?P<name>.*)\.(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)
+ 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