diff options
-rw-r--r-- | doc/server/plugins/generators/cfg.txt | 45 | ||||
-rw-r--r-- | 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<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: |