Code examples for "Learning CFEngine 3" now available

I'm happy to announce that the code examples from Learning CFEngine 3 are now available for browsing and download at http://cf-learn.info/code.html. You can view or download individual files, and also the whole collection. You can also get them from the GitHub repository.

These examples are extracted automatically from the source files for the book, and as such reflect exactly the current state of what you will find in it. This also means, of course, that as the book evolves you will see changes in the files.

As usual, please feel free to play with them, and let me know if you find anything broken.

CFEngine 3 training on January 25-27th, 2012

Quick plug: if you are in the Bay Area and are interested in getting some hands-on introduction to CFEngine 3, please make sure to check out this training session:

Automating System Administration using CFEngine 3
Presented by Mark Burgess & Aleksey Tsalolikhin
Date: January 25-27
Location: Palo Alto, CA
Price: $1950 per person (group discount negotiable)
Registration & Agenda: http://cfengine3.eventbrite.com
Mark is the original author of CFEngine and the ultimate CFEngine authority in the world. He will be joined by Aleksey, one of the most experienced CFEngine trainers around. Both are excellent teachers, so the course is guaranteed to be excellent.

cf-cmd: A command-line tool for running CFEngine snippets

While writing this book, I've had to run hundreds of little CFEngine snippets to run tests, develop examples, verify functionality, or get a solid idea of what some constructs did. After building the typical "test bundle" scaffolding in an editor for the hundredth time, I decided to do something about it. The result is the cf-cmd command. I will let it speak for itself:

$ cf-cmd help
cf-cmd v1.0 - Diego Zamboni diego@zzamboni.org>

cf-cmd is a tool that allows you to run small CFEngine snippets quickly,
by automatically wrapping them around a standard "test" bundle.

The CFEngine Standard Library is automatically included.

The following inputs are understood by this tool:

help     Print this message
list     Print current policy
clear    Clear current policy
go|run   Execute current policy using cf-agent
type:    Switch to the given promise type
         (classes:, commands:, databases:, environments:, files:, interfaces:,
         methods:, outputs:, packages:, processes:, reports:, services:,
         storage:, vars:)
           The current promise type is shown in the prompt.

All other lines are added literally to the current promise type.

Commands can be abbreviated to any part of their name (for example,
"r" or "ru" for "run").

You can add lines to any of the standard promise types inside the test
bundle by switching to the appropriate promise type first.

The default promise type is "reports:", to make it easier to quickly print
the value of expressions.

You can give the inputs also on the command line, they are interpreted
in exactly the same way (make sure to quote things correctly).

Examples:
  cf-cmd '"Flavor: $(sys.flavor)";' list run
  cf-cmd '"var1 = $(var1)";' vars: '"var1" string => "test";' l r
  cf-cmd h

You should try out those examples at the end to see what they do. An example interactive session looks like this (I have bolded the inputs to make them easier to see):

$ cf-cmd 
reports: > "this is a test";
reports: > list
body common control {
   inputs => { "/var/cfengine/inputs/cfengine_stdlib.cf" };
   bundlesequence => { "test" };
}

bundle agent test
{
reports:
cfengine::
  "this is a test";
}
reports: > run
-> Running policy with 'cf-agent -KI -f ./test.cf'
R: this is a test
reports: > clear
reports: > l    (abbreviation of "list")
body common control {
   inputs => { "/var/cfengine/inputs/cfengine_stdlib.cf" };
   bundlesequence => { "test" };
}

bundle agent test
{
}
reports: > files: 
-> Switching to files: promise type.
files: > "/tmp/test"
files: >   create => "true",
files: >   classes => if_repaired("done");
files: > reports: 
-> Switching to reports: promise type.
reports: > done::
reports: > "Success";
reports: > l
body common control {
   inputs => { "/var/cfengine/inputs/cfengine_stdlib.cf" };
   bundlesequence => { "test" };
}

bundle agent test
{
files:
  "/tmp/test"
    create => "true",
    classes => if_repaired("done");
reports:
  done::
  "Success";
}
reports: > run
-> Running policy with 'cf-agent -KI -f ./test.cf'
 -> Created file /tmp/test, mode = 600
R: Success
reports: > 

The interactive prompt supports editing and completion of all commands and promise types - press Tab to view available completions.

You can download the script here: .

Just put it somewhere in your path. If needed, modify the location of the cfengine_stdlib.cf file on your system (by default it looks for it under /var/cfengine/inputs/). You need Ruby installed (I tested with version 1.9.3).

If you find it useful, or if you find any problems or have any suggestions, please let me know. I'd be happy to hear from you.

Migrating from CFEngine 2 to CFEngine 3

When designing the CFEngine 3 language, its author Mark Burgess decided a complete overhaul was needed. This decision freed CFEngine 3 from any backwards-compatibility constraints, resulting in a completely new language that is much more flexible, extensible, powerful and expressive.

Unfortunately, this means that migrating from CFEngine 2 to CFEngine 3 is not automated, and requires a certain level of hand-tweaking. One of the frequent comments I heard at LISA'11 was from people who are currently using CFEngine 2, and have been hesitant of migrating to CFEngine 3 because they are not sure how to proceed, and are afraid of the amount of work it will involve (and also, "if it ain't broke, don't fix it"). However, upgrading to CFEngine 3 is a tremendous opportunity for improving the state of the infrastructure, and many of its features can help in making the policies more understandable, flexible and scalable. It is partly for this reason that there is no automatic conversion tool from CF2 to CF3 policy format. Doing it by hand allows close examination of the policies, their intended purpose, and provides an opportunity to improve them in the process.

To help, there is the Upgrading from CFEngine 2 to 3 guide (PDF). It contains some general suggestions, different ways in which the conversion can be handled, and a "Translation Codebook" that helps in converting from CFEngine 2 constructs to their equivalents in CFEngine 3.

Additionally, CFEngine AS is holding a webinar called Migrating from CFEngine 2 to CFEngine 3 on January 25th, 2012. It will be imparted by Joe Netzel from CFEngine. Joe is a great speaker and teacher, and knows CFEngine in and out, so the webinar is assured to be full of good content, and a fantastic learning opportunity. It's free, so why not sign up?

Update: the webinar has passed, but you can view the recording and a related presentation.

http://cf-learn.info/ goes live

I'm happy to announce http://cf-learn.info/, the accompanying website for my book Learning CFEngine 3, currently in Early Release from O'Reilly. 

In this website you will find:
  • General information about the book.
  • A discussion forum for any type of questions, feedback or suggestions about the book.
  • Downloadable code examples from the book, plus (over time) many other new examples.
  • List of Errata, and access to the Errata system at O'Reilly.
  • A blog devoted to the book and to CFEngine.
The site is mostly empty at the moment (the blog, the forum and the errata page are live, I encourage you to participate, particularly if you have purchased the Early Release version of the book and want to provide any sort of feedback), but content will grow over time.

Thank you for visiting, and please let me know what you think!

Best regards,
--Diego