The language-puppet website.

Work with your manifests!

Version 1.7.2, With More PuppetDB

A new maintenance version is out. The long awaited resource relationship update will still have to wait, but there are exciting promises in this upgrade, such as the early PuppetDB support. I will blog later about it, but this will rock.

First of all, quite a few bugs were fixed since 1.7.0, and a few nice features have been added. A lot of minor enhancements have been added now that the official language documentation is published. The behaviour of the library should now more closely match that of Puppet. The problem is that there is a huge difference in behaviour that might bite you.

When I started this project, all that was available was the language tutorial and the Puppet source code. As I explained already, I find it less troublesome to just rewrite it from scratch than to try to follow Ruby code. I recently wrote a pair of resource providers, so I can attest this still holds true. It seemed to me at that time that the various statements could be inserted at any place in a manifest and without changing its meaning.

Some effects would be undefined obviously (putting two conflicting defaults in the same class for example), but everything seemed doable with little effort. One of the early design decisions was to support this feature fully, except in conditionnals where I couldn’t see how to handle them efficiently.

The cost of this decision is that all data types have been doubled : one version for the “raw” or “unresolved” version, and one version for the “final” or “resolved” version. Everytime a statement is interpreted, it might be left in an unresolved state, which leads to all kind of performance and logic problems (for example, when you can’t resolve a variable you have to store some pointer to its scope to resolve it later).

It turns out that this was not needed to be Puppet-perfect, as Puppet doesn’t even attempt to do this for variable assignements. This means that every data types could be fully resolved when first found.

This means that the following code fragment will work as you might expect in language-puppet, but not in Puppet:

file { $filename: ensure => present; }
$filename = 'foo'

And while language-puppet is much faster than Puppet, despite spawning a ruby process for (almost) every template evaluation, it could have been even more. Also the internals would be much cleaner …

Anyway, here goes the changelog:

New features

  • Amending attributes with a collector.
  • Stdlib functions : chomp
  • Resource pretty printer now aligns =>.
  • Case statements with regexps.

Bugs fixed

  • Various details have been modified since the official language documentation has been published.
  • Better handling of collector conditions.
  • Solves bug with interpolable strings that are not resolved when first found.