summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/Server/Plugin.py13
-rw-r--r--src/lib/Server/Plugins/SGenshi.py81
-rw-r--r--src/lib/Server/Plugins/TGenshi.py14
3 files changed, 50 insertions, 58 deletions
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 10bc4f1fc..4a973ba1c 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -446,6 +446,10 @@ class EntrySet:
pattern += '(G(?P<prio>\d+)_(?P<group>\S+))))?$'
self.specific = re.compile(pattern)
+ def get_matching(self, metadata):
+ return [item for item in self.entries.values() \
+ if item.specific.matches(metadata)]
+
def handle_event(self, event):
'''Handle FAM events for the TemplateSet'''
action = event.code2str()
@@ -547,8 +551,7 @@ class EntrySet:
def bind_entry(self, entry, metadata):
'''Return the appropriate interpreted template from the set of available templates'''
self.bind_info_to_entry(entry, metadata)
- matching = [ent for ent in self.entries.values() if \
- ent.specific.matches(metadata)]
+ matching = self.get_matching(metadata)
hspec = [ent for ent in matching if ent.specific.hostname]
if hspec:
@@ -645,14 +648,12 @@ class GroupSpool(Plugin):
def AddDirectoryMonitor(self, relative):
'''Add new directory to FAM structures'''
- if not relative:
- relative = '/'
- if relative[-1] != '/':
+ if not relative.endswith('/'):
relative += '/'
name = self.data + relative
if relative not in self.handles.values():
if not posixpath.isdir(name):
- print "Genshi: Failed to open directory %s" % (name)
+ print "Failed to open directory %s" % (name)
return
reqid = self.core.fam.AddMonitor(name, self)
self.handles[reqid] = relative
diff --git a/src/lib/Server/Plugins/SGenshi.py b/src/lib/Server/Plugins/SGenshi.py
index 76d1dd6bf..469cd493e 100644
--- a/src/lib/Server/Plugins/SGenshi.py
+++ b/src/lib/Server/Plugins/SGenshi.py
@@ -1,69 +1,52 @@
'''This module implements a templating generator based on Genshi'''
__revision__ = '$Revision$'
-import Bcfg2.Server.Plugin
+import Bcfg2.Server.Plugin, Bcfg2.Server.Plugins.TGenshi
import lxml.etree, logging
logger = logging.getLogger('Bcfg2.Plugins.SGenshi')
-try:
- import genshi.template, genshi.core, genshi.template.base
-except:
- logger.error("Failed to load Genshi; disabling SGenshi")
- raise
-
-def removecomment(stream):
- """A genshi filter that removes comments from the stream."""
- for kind, data, pos in stream:
- if kind is genshi.core.COMMENT:
- continue
- yield kind, data, pos
-
-class TemplateFile(Bcfg2.Server.Plugin.FileBacked):
- '''Genshi template file object'''
- loader = genshi.template.TemplateLoader(auto_reload=True,
- max_cache_size=64)
- def HandleEvent(self, _=None):
- '''Process FAM/GAMIN event'''
- try:
- self.template = self.loader.load(self.name,
- cls=genshi.template.MarkupTemplate)
- except genshi.template.base.TemplateSyntaxError, e:
- logger.error("SGenshi: Parse failure due to %s" % (e))
-
- def GetValue(self, metadata):
- '''Build actual structure contents'''
- if not hasattr(self, 'template'):
- logger.error("Template data for %s could not be loaded" % self.name)
- raise Bcfg2.Server.Plugin.PluginExecutionError
- stream = self.template.generate(metadata=metadata).filter(removecomment)
+class SGenshiTemplateFile(Bcfg2.Server.Plugins.TGenshi.TemplateFile):
+ def get_xml_value(self, metadata):
+ stream = self.template.generate(metadata=metadata,
+ properties=self.properties).filter( \
+ Bcfg2.Server.Plugins.TGenshi.removecomment)
data = stream.render('xml')
return lxml.etree.XML(data)
-class SGenshi(Bcfg2.Server.Plugin.Plugin,
- Bcfg2.Server.Plugin.XMLDirectoryBacked):
- '''SGenshi is a structure plugin that provides direct plugin access to templated structures'''
- __child__ = TemplateFile
+class SGenshiEntrySet(Bcfg2.Server.Plugin.EntrySet):
+ def __init__(self, path, fam):
+ fpattern = '[A-Za-z]+\.xml'
+ Bcfg2.Server.Plugin.EntrySet.__init__(self, fpattern, path,
+ True, SGenshiTemplateFile)
+ fam.AddMonitor(path, self)
+
+ def HandleEvent(self, event):
+ if event.filename != self.path:
+ return self.handle_event(event)
+
+ def BuildStructures(self, metadata):
+ '''Build SGenshi structures'''
+ ret = []
+ for entry in self.get_matching(metadata):
+ try:
+ ret.append(entry.get_xml_value(metadata))
+ except Bcfg2.Server.Plugin.PluginExecutionError:
+ logger.error("SGenshi: Failed to template file %s" % entry.name)
+ return ret
+
+class SGenshi(SGenshiEntrySet, Bcfg2.Server.Plugin.Plugin):
+ '''The SGenshi plugin provides templated structures'''
__name__ = 'SGenshi'
__version__ = '$Id$'
+ __author__ = 'bcfg-dev@mcs.anl.gov'
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
try:
- Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self,
- self.data,
- self.core.fam)
+ SGenshiEntrySet.__init__(self, self.data, self.core.fam)
except:
logger.error("Failed to load SGenshi repository; disabling SGenshi")
raise Bcfg2.Server.Plugin.PluginInitError
- def BuildStructures(self, metadata):
- '''Build SGenshi structures'''
- ret = []
- for entry in self.entries.values():
- try:
- ret.append(entry.GetValue(metadata))
- except Bcfg2.Server.Plugin.PluginExecutionError:
- logger.error("SGenshi: Failed to template file %s" % entry.name)
- return ret
-
+
diff --git a/src/lib/Server/Plugins/TGenshi.py b/src/lib/Server/Plugins/TGenshi.py
index d7199d78c..0b9acfe58 100644
--- a/src/lib/Server/Plugins/TGenshi.py
+++ b/src/lib/Server/Plugins/TGenshi.py
@@ -4,9 +4,17 @@ __revision__ = '$Revision$'
from genshi.template import TemplateLoader, TextTemplate, MarkupTemplate, TemplateError
import logging
import Bcfg2.Server.Plugin
+import genshi.core
logger = logging.getLogger('Bcfg2.Plugins.TGenshi')
+def removecomment(stream):
+ """A genshi filter that removes comments from the stream."""
+ for kind, data, pos in stream:
+ if kind is genshi.core.COMMENT:
+ continue
+ yield kind, data, pos
+
class TemplateFile:
'''Template file creates Genshi template structures for the loaded file'''
def __init__(self, name, properties, specific):
@@ -38,9 +46,9 @@ class TemplateFile:
'''Build literal file information'''
fname = entry.get('realname', entry.get('name'))
try:
- stream = self.template.generate(name=fname,
- metadata=metadata,
- properties=self.properties)
+ stream = self.template.generate( \
+ name=fname, metadata=metadata,
+ properties=self.properties).filter(removecomment)
if isinstance(self.template, TextTemplate):
entry.text = stream.render('text')
else: