On Tue, Apr 06, 2010 at 04:19:56PM -0400, [email protected] 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
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine