Puppet Tips&Tricks: Getting the version from a package

Sometimes you need to know the version of a package before you can do anything useful. For example, we need to make sure the augeas-lenses package is 0.6.0 or newer, otherwise it doesn’t include the aptpreferences lens. We need that lens to modify /etc/apt/preferences in a nice way.

It would be very nice if there was some sort of function that could check on the client which version a certain package was, but during the design of puppet it was decided that puppet is not allowed to execute functions on a client, all functions are executed on the puppetmaster. So that’s not a valid option.

Another solution would be to create puppet facts for every package installed containing their version. Although that would help, it would clutter the facts a bit and probably make each puppetd run quite a bit longer. Also, all those facts would have to be stored in the database, if you’re using storeconfigs, which would add a lot of useless data there (although I can imagine setups which would actually appreciate this). So I chose for a simpler way, creating a fact specifically for augeas-lenses.

Getting the version from the commandline is easy on Debian, simply execute dpkg-query -W -f='${Version}' augeas-lenses. Creating a fact from that, is in its turn easy too:

if  FileTest.exists?("/usr/bin/dpkg-query")
    Facter.add("augeas_version") do
        setcode do
            %x{/usr/bin/dpkg-query -W -f='${Version}' augeas-lenses}

I created a file in our common module, lib/facter/augeas_version.rb, since that module is included on every host and the fact isn’t specific for a certain module. Preferably, you should add the fact to the module which uses it, of course, to keep things separated.

Now I can simply do:

# We need to compare the current augeas version, to see if we have the

# aptpreferences lens available. It's only been included since 0.6.0.

if versioncmp($augeas_version, '0.6.0') 

Awesome puppet! Hope this helps someone.


Comments powered by Disqus