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 Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine