Puppet Lint 2.0 Upgrade

With the recent puppet-lint 2.0 release it seemed a good time to bump the version we use at $WORK and see what’d changed. In theory it was as simple as changing the version in our Gemfile and ideally everything should continue as normal, but in practise it was a little more work than that and in this post I’m going to explain what we found.

Firstly let’s cover a lovely, free, bonus. On our test codebase puppet-lint 1.0.1 took about 25 seconds to run on average. Immediately after the upgrade to 2.0.0 our run times dropped to around 19 seconds, with no changes required to our code. While it might seem like a tiny amount of time, considering how often the tests get run, we’ve probably already recouped the time spent performing the upgrade.

In terms of lint warnings the first, and easiest to fix, complaint was the change from --no-80chars-check to --no-140chars-check. While most places already disable the line length check the Puppet style guide has become a little more accepting recently and now allows lines up to 140 characters. We have some longer lines, such as embedded ssh public keys, that hit this limit so we migrated from disabling the 80 character check to disabling the 140 one. This also required us to move from using the old config file .puppet-lintrc to the newer one .puppet-lint.rc. That was a few minutes of work so shouldn’t be a blocker for anyone.

The second source of lint warnings from the upgrade came as a bit of a surprise. It seems that fat arrow (=>) alignment wasn’t being correctly checked on attributes that ended with a semi-colon. We had code that looked like this:

file { '/tmp/fake':
  content => 'Hello',
  mode => '0644';
}

That ran fine under puppet-lint 1.0.1 but raised issues under 2.0.0. Fixing it was easy enough

file { '/tmp/fake':
  content => 'Hello',
  mode    => '0644';
}

and then the awkward, unneeded semi-colon was replaced with a sensible comma to make future diffs bit nicer too.

file { '/tmp/fake':
  content => 'Hello',
  mode    => '0644',
}

We fixed up nearly all the code violations with no manual intervention. We always work on branches so it safe enough to run bundle exec puppet- lint --fix . over the entire code base, let it change what it wanted, and then read through the diffs. While this completed 99% of the fixes it did raise one interesting --fix edge case / bug that I have on the TODO list to investigate:

-   warning => "@${minimum_request_rate * 1.2}",
+   warning => "@${minimum_request_rate} * 1.2",

The fix code is a little aggressive in its protecting of variable names and in this case changes the functionality significantly by replacing a multiplication with a variable and a literal string. There is something to be said that this’d be better as an inline_template but for now changing it back was simple enough and the checks are happy with it.

In closing, technically the upgrade is worth doing for the performance improvements and stricter linting. From a community side it’s nice to see more people involved and have versioned releases coming out rather than pinning to individual git hashes. A big ‘thank you’ is deserved by all the people involved. If you want to see exactly what was done you can see the full puppet-lint 2.0 upgrade in our public puppet code.