PC> But, as you said, problem is that many of the existing promise types
PC> (implementations, that is) have arbitrary quirks in the way they are evaluated
PC> and executed.
Indeed.
The theory is that one shouldn't have to worry about sequence when writing CFEngine 3 policy. The reality is that one has to worry about sequence MUCH, MUCH MORE than when writing in any language wherein commands are simply executed one after another.
Here is a real case study in CFEngine evaluation sequence.
Consider the following three promises:
[root@hub ~]# cat nameservers.cf
bundle agent main {
commands:
any::
"/bin/sed -f $(this.promise_dirname)/nameservers.sed /etc/resolv.conf"
classes => kept_successful_command,
module => "true";
vars:
DEBUG::
"report_indices"
slist => getindices("inventory_module.nameserver");
reports:
DEBUG::
"Inventorying nameserver: '$(inventory_module.nameserver[$(report_indices)])'";
}
body classes kept_successful_command {
# from standard library
kept_returncodes => { "0" };
}
Below is the Sed script referenced. It converts the nameservers from the resolv.conf file into module protocol for CFEngine inventory. (As a side note, this sort of text parsing is extraordinarily difficult/overcomplicated with pure CFEngine, but as I'm quite decent with POSIX text processing tools, this doesn't bother me too much.)
[root@hub ~]# cat nameservers.sed
#!/bin/sed -f
1i\
^context=inventory_module
1i\
^meta=inventory,attribute_name=Nameservers
/^nameserver[[:space:]]*/!d
s///
s/[[:space:]]*$//
s/.*/=nameserver[&]=&/
Note the vars promise and reports promise in the bundle up above, written so we can see what CFEngine is adding to inventory.
Now, before going any further—do you see the error in the policy up above? (If you do see it, it's possible you've been spending way too much debugging CFEngine's evaluation sequence.) ;)
What do we get if we run this policy with the DEBUG class set?
[root@hub ~]# cf-agent -KIC -DDEBUG -f ./nameservers.cf
info: Executing 'no timeout' ... '/bin/sed -f /root/./nameservers.sed /etc/resolv.conf'
info: Command related to promiser '/bin/sed -f /root/./nameservers.sed /etc/resolv.conf' returned code defined as promise kept 0
info: Completed execution of '/bin/sed -f /root/./nameservers.sed /etc/resolv.conf'
R: Inventorying nameserver: '$(cf_null)'
R: Inventorying nameserver: '10.0.2.3'
[root@hub ~]#