cfengine-develop
[Top][All Lists]
Advanced

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

[Cfengine-develop] Re: Homework


From: Luke A. Kanies
Subject: [Cfengine-develop] Re: Homework
Date: Mon, 3 Mar 2003 15:56:43 -0600 (CST)

On Mon, 3 Mar 2003 address@hidden wrote:

>
> Here's a homework for you all:
>
>  What would the syntax of your ideal cfengine statement (with loops and types
>  or whatever you want) look like?
>
>  Everyone submit a couple of examples. One the the big issues in language
>  design is syntax.

Well, I'll start with arrays.  I'm going to assume at least push/pop
functions for manipulating them within the 'control' section.  I'm also
going to take perl's '@' character for arrays, but not switch to '$' when
referring to individual members (similar to how perl 6 is supposed to be).

Problem, though:  cfengine doesn't use datatype sigils when assigning
variables, only when interpolating them, which means that the following
syntaxes could be ambiguous:

scalar = ( this is a scalar value )
array = ( this is an array )

We could require all strings to be quoted (which I think is generally a
good idea), or commas separating array members (probably also a good
idea), or could move to using (or at least allowing) datatype sigils at
variable assignment time (which I think is a great idea; more perl, less
shell).

I'll go ahead and use the datatype sigils throughout.

Here's an example I'd use on oracle clusters:

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

groups:
  oracle1 = ( host1 host2 host3 )
  oracle2 = ( host4 host5 host6 )

  oracle_cluster = ( oracle1 oracle2 )

control:
  $nbbindir = ( "/opt/openv/netbackup/bin" )

  oracle_cluster::
    @backuptypes = ( "HOT", "COLD" )
    @backupstates = ( "start", "end" )

  oracle1::
    @dbs = ( "db1", "db2" )

  oracle2::
    @dbs = ( "db3", "db4" )

# implicitly iterate over all of the lists
links:
  oracle_cluster:
    $nbbindir/address@hidden@address@hidden
      ->! bpscript

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

This creates a link to the bpscript for every configured database, backup
type, and backup state.

Compare to the following cut-n-pasted or generated code:

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

groups:
  oracle1 = ( host1 host2 host3 )
  oracle2 = ( host4 host5 host6 )

  oracle_cluster = ( oracle1 oracle2 )

control:
  $nbbindir = ( "/opt/openv/netbackup/bin" )

links:
  oracle1::
    $nbbindir/bpend_notify.ORACLE_db1.HOT ->! bpscript
    $nbbindir/bpend_notify.ORACLE_db1.COLD ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db1.HOT ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db1.COLD ->! bpscript

    $nbbindir/bpend_notify.ORACLE_db2.HOT ->! bpscript
    $nbbindir/bpend_notify.ORACLE_db2.COLD ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db2.HOT ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db2.COLD ->! bpscript

  oracle2::
    $nbbindir/bpend_notify.ORACLE_db3.HOT ->! bpscript
    $nbbindir/bpend_notify.ORACLE_db3.COLD ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db3.HOT ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db3.COLD ->! bpscript

    $nbbindir/bpend_notify.ORACLE_db4.HOT ->! bpscript
    $nbbindir/bpend_notify.ORACLE_db4.COLD ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db4.HOT ->! bpscript
    $nbbindir/bpstart_notify.ORACLE_db4.COLD ->! bpscript


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

In other words, in the above example, with a couple extra lines creating
the arrays, I've reduced 16 lines of code to a single line of code.  Yay!

This, however, brings up things like whether we only implicitly iterate on
the left side of operators, whether all sections implicitly iterate,
should we iterate implicitly at all, etc.  I think implicit iteration when
interpreted as a string makes the most sense.

#---------------
# another array example
# a mythical cron.cf

control:
  $cfexec = ( "/var/cfengine/bin/cfexecd" )
  $ip = MyIP() # I know this function doesn't exist...
  $isminutes = ( ExecResult(/bin/randomminute $ip) )
  $ishour = ( ExecResult(/bin/randomhour $ip) )

  $cronpath = ( "/var/spool/crontabs" )

  $cfcron = ( "0,30 * * * * $cfexec -F" )

  $logchkcron = ( "10 3 * * 0,4" )
  $iscron = ( "$isminutes $ishour * * * \
/var/isconf/sbin/isboothook -c DAILY" )

  $dmesgcron = ( "0,5,10,15,20,25,30,35,40,45,50,55 * * * \
/usr/sbin/dmesg - >> /var/adm/messages" )

  *any::
    push @rootcrons, $cfcron, $iscron

  *hpux::
    push @rootcrons, $dmesgcron

  *sunos::
    push @rootcrons, $logchkcron

editfiles:
  { $cronpath/root
      AppendIfNoSuchLine @rootcrons
  }

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

This is nice because it completely abstracts the cron jobs themselves from
how they are put into the cron tab.  We can have a file which just defines
every single cronjob that could exist anywhere on our network, and then
later, selectively include those cronjobs.

With the addition of arrays of arrays (which would probably require
references to arrays), some kind of iteration keyword ("each"?), and a
generic block structure, you could abstract exactly how the crons get
stored; someone using xcrond could use the same cron definitions as
someone using crond.  A perl-style "join" keyword might be nice, but
wouldn't be necessary.

All of that is a pretty big jump, though, so I'm leaving it out for now.
I think the above is a good enough example, and would be tons of extra
functionality.

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

Datatype sigils

I've also been thinking about datatype sigils some; variables already have
them in cfengine ('$'), I would expect arrays to have a different one, and
hashes if we get those; what about classes?  I thought of using '*' as a
sigil for classes, or at least something like that. '^' could work also,
but not many others; the drawback to '*' is that it occurs in math
expressions, but I don't think cfengine has those, so that's not really a
problem.

So, the above code would look like:

#-----------------
groups:
  *oracle1 = ( *host1 *host2 *host3 )
  *oracle2 = ( *host4 *host5 *host6 )

  *oracle_cluster = ( *oracle1 *oracle2 )

control:
  $nbbindir = ( "/opt/openv/netbackup/bin" )

  *oracle_cluster::
    @backuptypes = ( "HOT", "COLD" )
    @backupstates = ( "start", "end" )

  *oracle1::
    @dbs = ( "db1", "db2" )

  *oracle2::
    @dbs = ( "db3", "db4" )

# implicitly iterate over all of the lists
links:
  *oracle_cluster::
    $nbbindir/address@hidden@address@hidden
       ->! bpscript

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

I like this, because it gets rid of barewords, which I like in general
because it makes parsing easier, both by the compiler and by the
programmer, and it just makes things cleaner in general, in my opinion.

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

Just one more thing:  Some kind of builtin command separator.  It's very
hard to mentall parse cfengine files, becuase there's no line terminator.
I recommend adopting the relatively standard ';' as a means of separation.
I think this would clean up the syntax a lot.

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

I'll limit my examples to this for now.  I have obviously not been
exhaustive on usage of either of these (especially arrays).  I have
glossed over $variable vs. ${variable}, I know.

Luke

-- 
                        ACHTUNG!!!

Das machine is nicht fur gefingerpoken und mittengrabben.  Ist easy
schnappen der springenwerk, blowenfusen und corkenpoppen mit
spitzensparken.  Ist nicht fur gewerken by das dummkopfen.  Das
rubbernecken sightseeren keepen hands in das pockets.  Relaxen und
vatch das blinkenlights!!!




reply via email to

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