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