On Tue, Apr 06, 2010 at 04:19:56PM -0400, fo...@cfengine.com wrote:
>Subject: Re: Setting a variable conditionally, depending on a class?
>Author: neilhwatson
>Link to topic: https://cfengine.com/forum/read.php?3,16796,16800#msg-16800
>
>Show us a practical example describing your plight that cannot be resolved 
>using hard classes.

I'd actually spin this around:  give me a reason why it shouldn't work 
with soft classes.

This is the same reason you use DNS CNAME entries for things
like "mail.example.com" and not "canonical_hostname.example.com".  You
only have to change things in one place, instead of several.

Let's say that, as a matter of policy, all computers managed by cfengine
have a file that stores a list of services that they provide in
/etc/adm/services.txt.  Cfengine should auto-populate this this file
(and yes, this is a slightly contrived example).  The canonical name of
the server is "bluebox.example.com."


Here's some code to attempt this:

<--- snip ---> 

bundle edit_line edit_service(service,status) {
vars:
       "line" string => "${service}: ${status}";

replace_patterns:
       "^${service}.*" replace_with => With("${line}");

insert_lines:
       "${line}";
}

bundle agent mail_server {

classes:
       "Mail_Server"  expression => 'bluebox.example.com';

vars:
       any::
           "service" string => "DNS";
       Mail_Server::
           "status" string => "${sys.fqhost} is a mail server, postfix ok."
       !Mail_Server::
           "status" string => "${sys.fqhost} is not a mail server";

files:
       "/etc/adm/services.txt"
           edit_line => edit_service('DNS', "${status}");
}

<--- snip ---> 

The expected behavior (to *me*) is that the value of ${status} will
be set according to membership in the Mail_Server:: class.  It is not,
because vars: runs before classes:, and thus Mail_Server is unset, so the
"!Mail_Server::" promise applies.  On subsequent passes, ${status} is
not changed.  

This is, to me, a big pain to deal with, since I wind up jumping through
hoops to try and accomplish this.  Yes, this could be coded with hard
classes, replacing Mail_Server:: with "signpost_example_com::" througout
the file.

Now consider the case where the hostnames change (I'm moving to the UK,
or something), and the hostname "bluebox.example.com" should now be
"redbox.example.com".  If I hardcode the class name, that has to be
changed throughout the file, instead of in a single location in the
classes: action.

Another example:  I have a class that is set based on the presense of a
file that is created by some mechanism outside of cfengine.  It is easy
to set a class based on the presence of this file, but there is no way
to define a variable based on the presense of this file.

You can *try* and do stuff with the isvariable() function, but that's
been hit-or-miss for me.  Furthermore, since cfengine3 will only iterate
through the actions 3 times--this is *waaay* to few, at least IMO--using
isvariable() basically blows one of your three passes.



-- 
Jesse Becker
NHGRI Linux support (Digicon Contractor)
_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to