Announcing CF4! (or is it CF-FORTH?!)
I imagine you didn’t expect such a big release so soon after our most recent release of 3.12.4 and 3.15.1 on March 26, but here it is: our alpha-release. Thus the reason for the .-4 in the version number. Of course choosing -4 has something to do with the fun of spelling FORTH without the ‘U’. Also, it’s nearly a palindrome and I imagine we’ll have a few alphas/betas before the final release is finished. (a good palindrome: a man a plan a canal panama)
We learned our lesson from the CFE2 to CFE3 transition and have completely preserved backwards compatibility while adding some amazing new language and runtime features.
A brand new(old) language: FORTH!
With CF4 we use the FORTH language invented by Charles H. Moore to really bring a lot of power to the policy language. Define your own words to create promises, bundles, variables, you name it!
- Interactive REPL/debugger
- Introspection of vars/classes/promises
- Easy-to-construct DSL (domain specific language) for your policy. Create forth words to represent important aspects of your policy!
- New language constructs provided by our transition to a Forth-based
policy language
- Control structures like IF THEN ENDIF, IF THEN, BEGIN UNTIL, REPEAT
- Exception handling: CATCH THROW
- Extensive artihmetics operations
- Recursion
Let’s get started!
Download cf4 and run it like this:
$ cf4
This will present you with the following information and be ready for your input:
CFEngine Core 4.0.-4
(You might be confused by the lack of a prompt, but we feel keeping
things simple is important, just as with my favorite text editor ed(1)).
You can add a prompt if you wish (see the info
pages).
At this point, you can start entering policy manually or loading policy from files, either directly including them or by requiring them.
include promises.cf4
S" promises.cf4" included
require my-library.cf4
S" promises.cf4" required
Here is a simple hello world example in CFE3:
bundle agent main
{
reports:
"Hello world!";
}
The equivalent CF4 policy is much more succinct and clear:
S" Hello world!" reports promise
By default in CF4, there is an assumed bundle agent main
present. If
you want to specify a different name simple add it to the end!
S" Hello world!" reports promise S" main" agent bundle
Now that it is entered into the system you can evaluate the promises
with the word keep_promises
:
% keep_promises
R: Hello world!
A more advanced example
Now let’s try a slightly more complicated example from Diego Zamboni’s excellent book: Learning CFEngine.
bundle agent edit_motd
{
vars:
"motd" string => "/etc/motd";
files:
"$(motd)"
create => "true",
edit_line => addmessage;
}
bundle edit_line addmessage
{
insert_lines:
"This system is managed by CFEngine 4!";
}
In CF4 you would first define a few words for the motd
path and your
edit_line
bundle details:
: motd S" /etc/motd" ;
: addmessage S" This system is managed by CFEngine 4!" insert_lines edit_line bundle ;
Next, you would use those words to express the files promise:
motd files
The word files
takes the string returned by the word motd
and starts
formulating a new promise. At this point, we can add any number of
attributes before we “close out” the current promise.
S" true" create
addmessage edit_line
And finally, we close out the promise with the promise
word
promise
And execute/evaluate the policy with keep_promises
keep_promises
info: Created file '/etc/motd', mode 0600
info: Edit file '/etc/motd'
Compare that CFE3 policy above with the precision of the equivalent CF4
policy we have built up! (this one includes the bundle
and policy
words for fun, not required)
: motd S" /etc/motd" ;
: addmessage S" This system is managed by CFEngine 4!" insert_lines edit_line bundle ;
motd files
true create
addmessage edit_line
promise
S" edit_motd" agent bundle
policy
At this point, you can examine vars, classes, promise outcomes and
various other aspects of the system in real-time. When you are done
simply type bye
and you are done!
There is so much more to explore with CF4, but we’ll leave that for another time.
If you’d like to hack-a-long (and trust me, this is a SERIOUS hack at this point, not all the build steps are even documented right now! :O (I really need to learn autotools better))
git clone -b cf-forth --depth 1 --recursive git@github.com:craigcomstock/core.git
Cheers, be well, and trust in your promises.
This April Fools joke brought to you by the CFEngine Forth fan club!