Forum: CFEngine Help
Subject: Re: inserting lines into crontab
Author: sauer
Link to topic: https://cfengine.com/forum/read.php?3,23442,23471#msg-23471
The suggestion to use cron.d is only superficially different from adding lines
to a file; you're still combining a bunch of small parts into a larger
configuration. The drawback to a cron.d-based solution is that it becomes a
fair amout harder to make sure that the only entries in your configuration are
those that you put there.
If you simply add lines to a file, then yes, you have to craft crazy regexps to
remove old variants of the lines. But, like Neil suggested, you can also
aggregate the lines you need in your file into an slist, and with one edit
promise simply empty the file and add the lines which are supposed to be there.
The result is that you don't have to explicitly remove anything; each time,
you wipe and readd, and Cfengine is smart enough to not actually edit the file
if the result would be the same as what's already in place. So that converges
nicely.
Adding entries to a directory is similar to adding lines to a file. Sure, when
you're adding it's easy. But what if you replace an entry? Well, if it's the
same filename, great. But then you want to remove an entry, or move an entry
to a different file for some reason. Well, now you have to add patterns for
files which should be removed. Oh, and if some other process (say, a person
unfamiliar with policy, etc) added a rogue entry to cron.d, how are you going
to catch and remove that with a directory? You'll have to do an ls on the
directory and do a diff on every run, and now things are taking longer because
you're doing a bunch of extra fork/exec's. Or you manually manage a second
directory and keep cron.d in sync with it, but at that point you've lost some
of the Cfengine advantages.
If only one area ultimately controls the contents of /etc/crontab, it's IMHO
more stable to just manage one file. I tend to create one bundle (call it
varbundle) with an array, and use classes to add different cron rules into that
array. Then in another bundle (say, actionbundle), I get the keys from
varbundle's "config" array, which results in a list within actionbundle's
context.
bundle agent varbundle{
vars:
any::
"config" string => "*/5 * * * * /bin/true"
host1::
"config" string => "*/5 * * * * /bin/false"
host2::
"config" string => "*/5 * * * * echo hello"
}
Then actionbundle can reference $(varbundle.config), which will vary based on
whether we're on host1, host2, or host3. I usually do that in two separate
bundles, though, so I can potentially define extra classes (perhaps based on
calling a module script) or similar in varbundle and have a consistent
definition for the array by the time I get to actionbundle.
The benefit of this kind of structure, IMHO, is that you can get basically your
whole enteprise config expressed in a way that's pretty easy to read in one
place. In my situation, this is also helpful as it allows for me to develop a
frontend which, in combination with pulling allclasses.txt back to a central
server, can go through and show what crontab entries (or whatever's managed
this way - sudoers, users in /etc/passwd, etc) should be applied on a given
host. Nova probably does that magically, but I don't have that option right
now. :) So this way I can both say "what crontab entries should be on host X"
and "what hosts have crontab entry Y" very easily.
This, BTW, is where I thank the Cfengine developers for the consistency in the
language; it's super easy to parse with another tool. I took a Puppet class a
few weeks ago (don't ask) and man is that tool's syntax a mess. It made me
really appreciate Cfengine that much more. :)
_______________________________________________
Help-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine