Templating Ideas
From Cfwiki
Contents |
Copy Templates: Templating in Cfengine Itself
Examine your copy: sections--you've probably got a number of sections which are largely the same, differing only in the source and destination files. For example, here's a short section from one of my files:
copy:
...
${configroot}/redhat/profile
dest=/etc/profile
server=${cfserver}
owner=root
group=root
mode=0444
type=checksum
${configroot}/redhat/bashrc
dest=/etc/bashrc
server=${cfserver}
owner=root
group=root
mode=0444
type=checksum
I have a dozen or more files in this one imported config file like this. All of this repetition seems needless. Consider, instead, for example, Nagios's new template-based configuration system: you define a named template, but disable it from being used as a regular configuration section by adding
register = 0
Then in your instance stanzas, you add
use = template_name
and provide configuration attributes only for those few entries that are specific to the particular instance. Here is an example of how this may work with cfengine: Add two attributes to configuration stanzas in each section: template_name and use_template. The former indicates that the stanza is a template (and hence the attribute requirements do not apply) and names it. The latter is used for an instance stanza to pull in the pre-defined attributes from the template. Here's what it might look like in practice, given my example above:
copy:
template_name=basic_conf_file
server=${cfserver}
owner=root
group=root
mode=0444
type=checksum
${configroot}/redhat/profile
dest=/etc/profile
use_template=basic_conf_file
${configroot}/redhat/bashrc
dest=/etc/bashrc
use_template=basic_conf_file
Jamie Wilkinson posted a link to some work he did to implement a templating system for cfengine using GNU m4 in this mailing list article: http://article.gmane.org/gmane.comp.sysutils.cfengine.general/5063 His m4 macros are available here.
Action Templating
General Overview
Tim writes: My idea about templating is that, at various points in the cfengine process, templating actions can be triggered. This would allow the embedding of other code in cfengine. The points I'm suggesting the templating be triggered at are:
- PreCopy: Before the file is copied from the source
- PostCopy: After the file is copied to the destination
- PreRun: For cfengine files, this is evaluated before running it
- InRun: For cfengine files, this text is evaluated during the run
Typically it would send the template block to the stdin of the processor, and import the stdout back into the cfengine code, but would be possible to make it operate on other files.
PreCopy Templating: Templating in Configuration Files
Template a file before copying.
There have been at least two conflicting ideas on this
| EricSorensen's idea | Tim Nelson's idea | |
|---|---|---|
| Activation location | That there be a new block other than copy which activated this. He already made a workaround in his Singlecopy Nirvana | That it be an option on copy statements, also settable globally, and via a regex on the filename (ie. if $(filename) matches $(template_repository), copy, otherwise not) |
| Calling programs | He suggested that there be a well-defined set of transformations (programs) | That programs be defined on an ad-hoc basis (see example below) |
Eric Sorensen's idea
The following is a more specific suggestion by Wilco on Eric Sorensen's idea:
After further consideration, if cfengine has a means to copy a file on a host other than using 'cp' in shellcommands:, this would not be impossible to achieve, althought it might be more tedious. copy: would define a class when one of the template files was updated, which would fire off a local copy to a staging area, which defines a class to fire off an editfiles:, which in turn (finally) defines a class to fire off a local copy from the staging area to the live area. You can see, of course, how some specialized facilities would make this much easier to use.
There was discussion recently on the cfengine mailing list with some other implementations which have also been (or will be) captured here.
Tim Nelson's idea
In addition to what's in the comparison table above, I was pretty much intending that it be like Wilco's idea above (in the Eric Sorensen section), except triggered on an actual copy, instead of a separate section
PostCopy Templating
It should also be possible to have cfengine trigger a templating action after copying a file. This could include rebuilding aliases, binary files, postfix databases, and the like. Similar ideas were also suggested by Wil Cooley in this post.
The deploy section of Ted Zlatanov's cfperl does something similar, I think.
PreRun Templating
You could also trigger a templating before a run of cfengine, if it depends on constantly updated parts of the machine.
InRun Templating
You could also run some templated code inline, while running cfengine. This would also replace the "import" section.
This would make it possible to separate most of editfiles into a separate language. We'd need to retain eg. the file choosing stuff (filters, etc) in cfengine, but the stuff which does internal editing on files could be put into a separate language. Possible new versions of editfiles are documented on the Editfiles page.
Example
Here are a few possible ways we could do it:
#
# cfengine config file
#
=== begin pre-copy /usr/bin/doc-generator > $docodir/$1.html
This is documentation on this cfengine code
=== end pre-copy
copy:
any:
=== begin pre-copy /usr/bin/perl
foreach(qw(/usr/bin/pickles /etc/pickles.conf)) {
print <<EOT;
$(repository)/$_
dest=$_
EOT
}
=== end
# The line below uses a cfengine variable
=== begin in-run TextSQL $(filename)
WHERE Option = "/dev/fd0" AND NOT Field[3] = /noauto/ DO Field[3] = "noauto"
=== end
Obviously a simple example with some doco, some config generation, and some editfiles-alike