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