Here at Normation, we use Cfengine 3 extensively for configuration management across Linux and Windows servers. Cfengine 3 is an open source project, and as every good open source project, the trunk version is always available (but not always very reliable) and stable versions are released regularly. Prior to the release of a new version, a beta version is available, for the community to test and rule out any bugs in the stable version.
We’ve been testing this beta version, and we are quite thrilled about it. This post won’t go through every detail of the changelog (Eystein is much better at it that I would be) but will run over the changes that improve our ways of using Cfengine.
Bug fixes
Some nagging bugs have been corrected, most notably:
- Bad class evaluation: sometimes, the evaluation of complex class conditions was invalid
- Segfault when calling a function in trustkeyfrom or allowconnects: when using the escape function in these lists, the agent or the server crashed
- Sanitization of the environment variables: on certain servers, the processes could not be correctly detected. It was because the number of columns of the output of program calls was limited to 80 columns by the system and not overriden in the agent.
- Packages promises didn’t define resulting classes if an action was taken: if a packages promise ran a command (ie, “aptitude install foo”), no classes were set on completion. Reasonable defaults are now used (a 0 return code means success, anything else is a failure), but can still be overridden.
- Memory leak in the Cfengine server (cf-serverd) when opening many secure connections: the memory consumption of the server daemon would jump occasionally if serving many clients.
New features
An improved release system
For more robust and reliable stable versions, features have been added to industrialize building and releasing Cfengine itself:
- New scripts to automate release, so that human error is mostly ruled out;
- Units test, to prevent regressions. Users are even encouraged to create unit tests;
- Easier compilation from sources. The following lines are enough to build Cfengine from sources:
[sourcecode language=’text’]
# ./autogen.sh [CONFIGURE OPTIONS]
# make clean
# make
[/sourcecode]
Improved reporting in file editing
Classes can be set on every atomic file edit, meaning that each line insertion, replacement or removal can be tracked and reported.
Let’s say we want to enforce the content of the file /tmp/foo to be two lines containing foo and bar (yes, this is just an example), and be able to know if these lines are added or were already there (for the sake of simplicity, we won’t bother about knowing if other lines were present). The following promise defines a class for each added line, for each repaired line and for each line that couldn’t be added:
Note the reports in the bundle edit_line which does the reporting based on the classes defined in the insert_lines promise.
The first execution would result in:
[sourcecode language=’text’]
# /var/cfengine/bin/cf-agent -Kf ./test.cf
R: Line foo added
R: Line bar added
[/sourcecode]
So each line has been added, the agent did its job. A second execution would result in :
[sourcecode language=’text’]
# /var/cfengine/bin/cf-agent -Kf ./test.cf
R: Line foo already present
R: Line bar already present
[/sourcecode]
Which proves that no one tampered with the file while we were away.
Of course, this level of detailed reporting would probably be excessive in a real-life example, but this illustrates how classes can be used to build your own custom reporting systems.
Improved string manipulation
Cfengine 3 has pretty neat functions to read files, parse them and extract data into arrays (for instance, reading data from /etc/passwd). The 3.1.5 version introduces the same neat functions for parsing variables, rather than files. And that’s really cool to be able to manipulate complex strings rather than files if you, like me, generate your promises with external tools.
Here is an example that illustrates this new feature:
- We generate a promise file, with a variable containing a list of users, and parameters for them
- The variable is parsed and data are extracted in an array
- The array is used to edit a passwd file, and a report is made if the line is added. This is a bit different from the ways described in a previous article on file editing.
Please note that the data are inserted in a random order. Indeed, the keys of an array are not ordered, being indexed by a kind of hash.
These new features are really great, and we’d like to thank the team behind Cfengine 3 and the Community for their great job at making Cfengine 3 a really powerful and reliable product.