cfengine-develop
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Cfengine-develop] Re: Homework


From: Luke A. Kanies
Subject: Re: [Cfengine-develop] Re: Homework
Date: Tue, 4 Mar 2003 16:28:33 -0600 (CST)

On Tue, 4 Mar 2003 address@hidden wrote:

> There is a delicate balance to be found between making things
> explicit and hiding ugly imperatives. It requires some creativity.
> Implicit expansion, such as we have now in cfengine has advantages
> and disadvantages .. sigh. These are the decisions that are the
> hardest. Again, we could use examples where the current method
> is inadequate, and examples of what would be better.

I agree with you, there is a delicate balance.  That's one of the reasons
I specified that my syntax was only to prove how useful hashes are, not to
function as an actual recommendation.

The easiest example I can think of where the current syntax is invalid is
collecting cron jobs.  I _very_ much want to separate the actual
installation of the cron jobs from defining all of the available cron
jobs.  Currently, if I have a total of 200 cron jobs (which I probably
have more than right now), scattered across fifty hosts, and I want to use
cfengine to manage that, then I have to essentially have a separate
editfiles instance for every cron jobs:

editfiles:
  any:: { ${rootcron}
    AppendIfNoSuchLine "${cron1}"
    DefineClasses=restartcron
  }
  host1:: { ${rootcron}
    AppendIfNoSuchLine "${cron2}"
    DefineClasses=restartcron
  }
  hostgroup:: { ${rootcron}
    AppendIfNoSuchLine "${cron3}"
    DefineClasses=restartcron
  }
.
.
.

If I at least had implicit iteration, then I could do the following:

#--------------------------
# not using the '@' character, since no one else seemed to like it...

control:
  any:: push(rootcrons, ${cron1})
  host1:: push(rootcrons, ${cron2})
  hostgroup:: push(rootcrons, ${cron3})

groups:
  haverootcron = ( IsDefined(rootcrons) )

editfiles:
  rootcron:: { ${rootcron}
    AppendIfNoSuchLine "${rootcrons}"
    DefineClasses=restartcron
  }

#--------------------------

Why is this so much better?  In general, because it separates what is
being done (I'm configuring stuff to happen on a periodic basis) from how
it's being done (I'm adding it to a specific file, and then defining a
class if a change was necessary) and why it's being done (because i'm on
host1 or a member of hostgroup).  I've got my definition of the cron job
(what's being done) in one place, which hosts that cron job belongs on
(why it's being done, I guess), and what is specifically going to change
on the host (how it's being done).  All in separate places in the config
file.

These are three distinct types of information, and with iteration, hashes,
namespaces, etc., it's trivial to maintain them separately.  With none of
those, though, it becomes impossible without generating code, which I
prefer to avoid if possible.  If I ever have to change my method of cron
storage, or change how cron is restarted (say, by installing another
process which restarts for me without having to have cfengine do it), or
have to support multiple platforms with the same cron jobs but different
cron installation methods, then I can do that very easily with this level
of abstraction.

I understand if this is not your goal; some people seem to like coupling
all of these pieces of information together.  I personally think it makes
configurations less reusable and more brittle, which is why I have a
somewhat religious aversion to this level of coupling.

As to the use of explicit iteration suddenly turning cfengine into an
imperative language, I'm not sure that's really the case.  I think one of
the reasons people fear prolog so much is the heavy use of implicit
iteration; most times I've heard 'implicit' used WRT languages, it is in a
negative way.  It makes sense to have some of it here, but how do you
implicitly iterate across an array of arrays?  How do you implicitly
access portions of an array without getting the whole thing?

Luke

-- 
        Q: How many surrealists does it take to screw in a lightbulb?
        A: Two.  One to hold the giraffe and the other to fill the
bathtub with brightly colored machine tools.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]