Hi folks, I have a question concerning scope of classes in CFEngine 3. I run CFE 3.10.2 on CentOS 7.4. # cf-agent -V CFEngine Core 3.10.2 # cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) I'm logged in as root and located in current working dir /root. I have the following file # ll ./samples/scope_of_class.cf -rwx------. 1 root root 720 10. Jul 16:33 ./samples/scope_of_class.cf with content ----BEGIN---------------------------------- bundle agent scope_of_class() { vars: any:: "web_servers" slist => { "ws-1.example.com", "ws-2.example.com", "webserver.example.com", }; methods: any:: "scope_of_class_b1" usebundle => scope_of_class_b1( $(scope_of_class.web_servers) ); } bundle agent scope_of_class_b1( server ) { classes: any:: "is_dir" expression => isdir( "/tmp/scope_of_class/$(server)" ), scope => "bundle"; reports: is_dir:: "is_dir is SET"; !is_dir:: "is_dir is UNset"; any:: "server = $(server)"; } ----END------------------------------------ From my understanding the scope "bundle" is default for a class definition inside a bundle of type agent, but I added the scope to be sure. The definition of class is_dir should depend on directories existing inside /tmp/scope_of_class. I have two subdirectories # ls -1 /tmp/scope_of_class/ webserver.example.com ws-1.example.com but when I run CFE I do NOT get expected behaviour for the definition of class is_dir: # cf-agent -IK --file ./samples/scope_of_class.cf --bundlesequence scope_of_class info: Using command line specified bundlesequence R: is_dir is SET R: server = ws-1.example.com R: is_dir is UNset R: server = ws-2.example.com R: server = webserver.example.com When the bundle scope_of_class_b1 is processed for parameter webserver.example.com I expect is_dir to bet set, but from the report it seems not to be set. If I change the slist definition to hold "webserver.example.com" as the first entry, then the class is_dir is set correctly: # grep slist ./samples/scope_of_class.cf -A 4 "web_servers" slist => { "webserver.example.com", "ws-1.example.com", "ws-2.example.com", }; # cf-agent -IK --file ./samples/scope_of_class.cf --bundlesequence scope_of_class info: Using command line specified bundlesequence R: is_dir is SET R: server = webserver.example.com R: server = ws-1.example.com R: is_dir is UNset R: server = ws-2.example.com It also works "correct" (or as expected by me) if "ws-2.example.com" is first entry in the slist definition: # grep slist ./samples/scope_of_class.cf -A 4 "web_servers" slist => { "ws-2.example.com", "ws-1.example.com", "webserver.example.com", }; # cf-agent -IK --file ./samples/scope_of_class.cf --bundlesequence scope_of_class info: Using command line specified bundlesequence R: is_dir is UNset R: server = ws-2.example.com R: is_dir is SET R: server = ws-1.example.com R: server = webserver.example.com I do not understand why the ordering inside slist influences how the class is_dir will be defined later by CFE for each processing of scope_of_class_b1. Some background information: my aim is to create webserver vhost configuration files where I have two variants, one with SSL configuration and one without SSL configuration. Which one to configure depends if the directory with the SSL certificate exists for a given vhost or not. I'll replace the report promise type by a file promise type, which should bring the correct vhost configuration file in place, assumed that I understand how the scope of the class definition works. Thanks in advance for any help or explanation of that behaviour. Regards, Meikel
Alexander Dalloz
2019-Jul-10 20:22 UTC
[CentOS] Scope of classes in CFE 3.10.2 on CentOS 7
Am 10.07.2019 um 18:07 schrieb Meikel:> > # cat /etc/redhat-release > CentOS Linux release 7.4.1708 (Core)Any good reason to not keep that system up to date? Minor release 7.4 is pretty old and has serious bugs. 7.6.1810 is current. Alexander
Am 10.07.2019 um 18:07 schrieb Meikel:> Thanks in advance for any help or explanation of that behaviour.Hi folks, yesterday in the IRC I got an answer which explains everything for me, so from my point of view my question is answered and the problem is solved. In short with my words: The bundle scope_of_class_b1 is called one time for each entry in the slist, so it is called three times. The promisee of the "reports" type is "is_dir is SET" and even if the class "is_dir" is set in two of the three executions, the "report" is print out only once, because the promisee is the same, and a promise for the same promisee is only kept/repaired/executed only once in an agent run. To get the expected output the promisee of the "reports" has to be rewritten to become unique for each execution, i.e. adding $(server) like this: reports: is_dir:: "is_dir is SET"; is_dir:: "$(server): is_dir is SET"; !is_dir:: "$(server): is_dir is UNset"; I kept "is_dir is SET" to better show the difference. It gives the following result: # cf-agent -IK --file ./samples/scope_of_class.cf --bundlesequence scope_of_class info: Using command line specified bundlesequence R: is_dir is SET R: ws-1.example.com: is_dir is SET R: ws-2.example.com: is_dir is UNset R: webserver.example.com: is_dir is SET The output "is_dir is SET" is never shown more than once in one agent run, even if all three directories exist, but if the promisee becomes unique, i.e. "ws-1.example.com: is_dir is SET" vs. "webserver.example.com: is_dir is SET" then they're both print out. The problem is NOT, that the definition/evaluation of the class "is_dir" does not work as expected, it works as expected, but I didn't see it in the output, because my expectation of what to see was wrong. As I don't have skills in CFE my wording might be imprecise, I'm sorry, hopefully the idea became clear. Regards, Meikel
Reasonably Related Threads
- Problem with definition of slist in CFEngine
- failure converting Linux ESX guest to KVM hypervisor
- [PATCH] fish: fix dir completion on filesystems w/o dirent.d_type (RHBZ#1153844).
- virt-customize fail to inject firstboot script when running it from script.
- Problem with definition of slist in CFEngine