From beed44ac11bbf70449c080262f98fb3ecb951c62 Mon Sep 17 00:00:00 2001 From: Joe Digilio Date: Mon, 26 Sep 2011 13:26:02 -0500 Subject: Cfg: Add support for .cheetah files --- doc/server/plugins/generators/cfg.txt | 45 ++++++++++++++++++++++++++++------- src/lib/Server/Plugins/Cfg.py | 31 +++++++++++++++++++++++- 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%s)(|\\.H_(?P\S+?)|.G(?P\d+)_(?P\S+?))(?P\\.genshi)?$' % name) + self.basefile_reg = re.compile('^(?P%s)(|\\.H_(?P\S+?)|.G(?P\d+)_(?P\S+?))((?P\\.genshi)|(?P\\.cheetah))?$' % name) self.delta_reg = re.compile('^(?P%s)(|\\.H_(?P\S+)|\\.G(?P\d+)_(?P\S+))\\.(?P(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: -- cgit v1.2.3-1-g7c22