summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/server/plugins/generators/cfg.txt45
-rw-r--r--src/lib/Server/Plugins/Cfg.py31
2 files changed, 66 insertions, 10 deletions
diff --git a/doc/server/plugins/generators/cfg.txt b/doc/server/plugins/generators/cfg.txt
index 1039ff556..1c8f6f11a 100644
--- a/doc/server/plugins/generators/cfg.txt
+++ b/doc/server/plugins/generators/cfg.txt
@@ -29,8 +29,8 @@ in ``Cfg/etc/passwd/passwd``, while the ssh pam module config file,
``/etc/pam.d/sshd``, goes in ``Cfg/etc/pam.d/sshd/sshd``. The reason for
the like-name directory is to allow multiple versions of each file to
exist, as described below. Note that these files are exact copies of what
-will appear on the client machine (except when using genshi templating --
-see below).
+will appear on the client machine (except when using genshi or cheetah
+templating -- see below).
Group-Specific Files
====================
@@ -150,25 +150,52 @@ file. The reason the other deltas aren't applied to *foo.example.com*
is because a **.H_** delta is more specific than a **.G##_** delta. Bcfg2
applies all the deltas at the most specific level.
+Templates
+=========
+
Genshi Templates
-================
+----------------
Genshi templates maybe used for entries as well. Any file ending in .genshi
will be processed using the new template style (like .newtxt in the TGenshi
-plugin). Templates can be host and group specific as well. Deltas will not
-be processed for any genshi base file.
+plugin).
+
+Cheetah Templates
+-----------------
+
+Cheetah templates maybe used for entries as well. Simply name your file
+with a .cheetah extenstion and it will be processed like the TCheetah
+plugin.
+
+Notes on Using Templates
+------------------------
+
+Templates can be host and group specific as well. Deltas will not be
+processed for any genshi or cheetah base file.
.. note::
- If you are using genshi templating in combination with host-specific
+ If you are using templating in combination with host-specific
or group-specific files, you will need to ensure that the ``.genshi``
- extensions is at the **end** of the filename. Using the examples
- from above for *host.example.com* and group *server* you would have
- the following::
+ or ``.cheetah`` extension is at the **end** of the filename. Using the
+ examples from above for *host.example.com* and group *server* you would
+ have the following (using genshi only)::
Cfg/etc/fstab/fstab.H_host.example.com.genshi
Cfg/etc/fstab/fstab.G50_server.genshi
+Genshi templates take precence over cheetah templates. For example, if
+two files exist named
+
+ Cfg/etc/fstab/fstab.genshi
+ Cfg/etc/fstab/fstab.cheetah
+
+the cheetah template is ignored. But you can mix genshi and cheetah when
+using different host-specific or group-specific files. For example:
+
+ Cfg/etc/fstab/fstab.H_host.example.com.genshi
+ Cfg/etc/fstab/fstab.G50_server.cheetah
+
File permissions
================
diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py
index beea2c747..f202628cd 100644
--- a/src/lib/Server/Plugins/Cfg.py
+++ b/src/lib/Server/Plugins/Cfg.py
@@ -23,6 +23,13 @@ try:
except:
have_genshi = False
+try:
+ import Cheetah.Template
+ import Cheetah.Parser
+ have_cheetah = True
+except:
+ have_cheetah = False
+
logger = logging.getLogger('Bcfg2.Plugins.Cfg')
@@ -80,7 +87,7 @@ class CfgMatcher:
def __init__(self, fname):
name = re.escape(fname)
- self.basefile_reg = re.compile('^(?P<basename>%s)(|\\.H_(?P<hostname>\S+?)|.G(?P<prio>\d+)_(?P<group>\S+?))(?P<genshi>\\.genshi)?$' % name)
+ self.basefile_reg = re.compile('^(?P<basename>%s)(|\\.H_(?P<hostname>\S+?)|.G(?P<prio>\d+)_(?P<group>\S+?))((?P<genshi>\\.genshi)|(?P<cheetah>\\.cheetah))?$' % name)
self.delta_reg = re.compile('^(?P<basename>%s)(|\\.H_(?P<hostname>\S+)|\\.G(?P<prio>\d+)_(?P<group>\S+))\\.(?P<delta>(cat|diff))$' % name)
self.cat_count = fname.count(".cat")
self.diff_count = fname.count(".diff")
@@ -157,6 +164,25 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
e = sys.exc_info()[1]
logger.error("Cfg: genshi exception: %s" % e)
raise Bcfg2.Server.Plugin.PluginExecutionError
+ elif basefile.name.endswith(".cheetah"):
+ if not have_cheetah:
+ logger.error("Cfg: Cheetah is not available")
+ raise Bcfg2.Server.Plugin.PluginExecutionError
+ try:
+ fname = entry.get('realname', entry.get('name'))
+ s = {'useStackFrames': False}
+ template = Cheetah.Template.Template(open(basefile.name).read(),
+ compilerSettings=s)
+ template.metadata = metadata
+ template.path = fname
+ template.source_path = basefile.name
+ data = template.respond()
+ if data == '':
+ entry.set('empty', 'true')
+ except Exception:
+ e = sys.exc_info()[1]
+ logger.error("Cfg: cheetah exception: %s" % e)
+ raise Bcfg2.Server.Plugin.PluginExecutionError
else:
data = basefile.data
for delta in used:
@@ -206,6 +232,9 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
if os.path.exists("%s.genshi" % name):
logger.error("Cfg: Unable to pull data for genshi types")
raise Bcfg2.Server.Plugin.PluginExecutionError
+ elif os.path.exists("%s.cheetah" % name):
+ logger.error("Cfg: Unable to pull data for cheetah types")
+ raise Bcfg2.Server.Plugin.PluginExecutionError
try:
etext = new_entry['text'].encode(self.encoding)
except: