[Infrastructures] Is cfengine a good tool?

Luke A. Kanies luke@madstop.com
Fri, 21 Feb 2003 09:35:34 -0600 (CST)


On Fri, 21 Feb 2003, Tim Writer wrote:

> I've been lurking on this list for some time and have seen quite a few
> similar endorsements of cfengine.  I've been managing heterogeneous networks
> for over a decade and, while I haven't had the opportunity to get my hands
> dirty with isconf, I'm a strong proponent of the philosophy.  I've been
> dabbling with cfengine for some months now and I'm still not convinced it's a
> good tool.  Since so many others seem to have a good experience, I'm thinking
> it's me, maybe I just don't get it.  I'd like to start a discussion on
> whether cfengine is really a good tool.  In order to try and understand
> cfengine better, I've reviewed the archives of the cfengine mailing list.
> I've seen lots of trivial snippets of cfengine config files but no
> substantial examples.  Perhaps some of you who have used cfengine succesfully
> could share your configuration.

I'll share my config, for what it's worth.  It's still a work in progress,
but you should be able to find it at
http://luke.madstop.com/cfengine/config.

I've also successfully integrated cfengine and ISconf, such that a type
defined in ISconf is available as a class in cfengine, and vice-versa, so
you don't have to encode any of that information twice.  I plan on
releasing the cfengine module as soon as I've got a couple bugs worked out
and can provide a good cfengine config for it.

> One thing I find very frustrating with cfengine is the quirkiness of the
> language.  Variables are expanded in some places and not in others.  This,
> for example, doesn't work:
>
>     control:
>
>         actionsequence = ( copy )
>
>         prefix = ( /u/adm )
>         source = ( ${prefix}/etc/ssh )
>
>     copy:
>
>       any::
>         ${source}
>           dest=/etc/ssh
>           ...

I believe that quoting the variable there will get you what you want.

> Without consistent variable expansion, how do you prevent cfengine config
> files from becoming unmaintainable.

Even with consistent expansion, the files quickly become unmaintainable,
or close to that, in my opinion.

I think that cfengine provides some functionality all in one place that's
really hard to duplicate manually, but the hoops you have to jump through
to get there are not very fun.  See my thread recently on the cfengine
help list about discovering the domain name, instead of hard-coding it.

> Another thing I've had a huge problem with is dependencies, something the
> cfengine docs suggest it excels at.  For example, some of our networks use
> NIS which requires portmap.  If an upgrade to ypserv is available, cfengine
> should restart ypserv after performing the upgrade.  And if an upgrade to
> portmap is available, cfengine should apply it, restart portmap, and restart
> ypserv.  I've been able to achieve this with classes and actionsequence but
> with seemingly a lot of code and without the same clarity as with make.

Yeah, it's possible to string together a sequence of actions in cfengine,
but it's by no means pleasant.  It's made worse by the fact that variables
can only be defined in the 'control' section, the evaluated classes like
'IsDefined' can only be used in the 'groups/classes' section, and the
total lack of things like lists and iteration inside the language itself.

> I find cfengine's output horrible.  Since I'm not yet comfortable with
> cfengine, I like using the -n option (to cfagent) to see what it's going to
> do.  Without -v, it doesn't tell you enough.  It tells you what it's going to
> do but not why.  With -v, there's far too much output to wade through.

I don't have a problem with the output, really...

> So, what am I missing?

I don't think you're missing much.  I think cfengine has done a really
good job as a tool that grew from a small initial project, but I think
that it has outgrown its initial design.  I've spent a significant amount
of time looking at the code, hoping to enhance things like string parsing
(which you mentioned above) and to add a better module interface, but in
my opinion, the code needs substantial refactoring before this can happen.

And the language as it stands now is very limited for actual discovery.
Your options are basically to link eveyrthing you do, in a very highly
coupled and verbose fashion, such that it's relatively easy for something
to go wrong with your configs, and it's relatively difficult to add
functionality.

Apparently people are using cfengine to do some great things, but I can't
imagine doing much with it without some added support towards becoming a
more general-purpose language.

I've decided to implement cfengine at my work on a test basis, but I'm
largely doing three things with it:  Verifying important processes like
cron, sshd, and syslogd are running, checking permissions and ownerships
of files and directories, and running ISconf.  There are other things I'm
interested in doing, but all of them require me to autogenerate cfengine
code and run that, rather than being able to write scripts in cfengine,
which seems like a hefty limitation.

Cfengine is kind of amazing in that I've never seen a tool used so heavily
but which has so many people trying to work around it.

-- 
A government big enough to give you everything you want is big enough
to take from you everything you have.           --Gerald R. Ford