Puppet Syntax Checking¶
Puppet can perform a syntax check of your manifests using the —parseonly option. This is a great way to very quickly check all of your manifests to make sure you have not made syntax errors. The checking will not, however, verify things such as misspelled file names and other values in strings. One way you can perform a more thorough check is to generate the catalog using the “puppetmasterd —compile node-name” command. Here is a simple script which you can adapt to your needs to check all your manifests.
A script to test your nodes¶
This script runs through all the files in the manifests/nodes directory and presumes each node has a file named the same as the node_name.pp.:
#! /usr/bin/env ruby
exit_code = 0
Dir[File.expand_path(File.dirname(__FILE__)) + '/manifests/nodes/*'].each do |file|
node= File.basename(file, '.pp')
puts "Processing #{node}"
`puppetmasterd --compile #{node}`
exit_code = $? unless exit_code != 0
end
exit exit_code
Although you can use a script like this as your pre-commit hook be aware that this will take significantly longer than a simple syntax check and may be inappropriate if you have lots of nodes.
Some example subversion commit hooks¶
Pre-commit Parse Check¶
Here’s a sanity check script which pulls out every file in the commit transaction, matches filenames(this example only looks for all .pp files under /puppet/trunk), and runs a parseonly on each of them:
#!/usr/bin/env ruby
TRUNK_REGEX = /puppet\/trunk/
MANIFEST_REGEX = /\.pp$/
class CommitCmd
attr_reader :status, :output, :cmd
def initialize(cmd)
@cmd = cmd
@status = nil
end
def run
@output = `#{@cmd} 2>&1`
@status = $?
end
end
repos = ARGV[0]
txn = ARGV[1]
if repos.nil? or txn.nil?
puts "Invalid commands"
exit(1)
end
filelistcmd = CommitCmd.new("/usr/bin/svnlook changed -t #{txn} #{repos}")
filelistcmd.run
if filelistcmd.status.exitstatus != 0
puts "Error getting change list:"
puts filelistcmd.output
exit(1)
end
errors = []
workdir = "/tmp/puppet.commit.#{$$}"
Dir.mkdir(workdir)
ENV["HOME"] = workdir
ENV["RUBYLIB"] = "/path/to/libdir"
filestocleanup = []
filelistcmd.output.split("\n").each do |l|
op = l[0..3].strip
f = l[4..-1].strip
next if not ["U", "A"].include?(op)
next if TRUNK_REGEX !~ l
next if MANIFEST_REGEX !~ l
wf = f.gsub("/", ".")
filestocleanup << wf
filecatcmd = CommitCmd.new("/usr/bin/svnlook cat -t #{txn} #{repos} #{f} > #{workdir}/#{wf}")
filecatcmd.run
if filecatcmd.status.exitstatus != 0
errors << "Error reading #{f}:\n #{filecatcmd.output.gsub("\n", "\n ")}"
next
end
puppetcmd = CommitCmd.new("/usr/scea/puppet/bin/puppet --noop --color=false --parseonly --ignoreimport #{workdir}/#{wf}")
puppetcmd.run
if puppetcmd.status.exitstatus != 0
errors << "Puppet errors in #{f}:\n #{puppetcmd.output.gsub("\n", "\n ")}"
next
end
end
# cleanup
begin
filestocleanup.each do |f|
File.unlink("#{workdir}/#{f}")
end
Dir.rmdir(workdir)
rescue StandardError => e
puts "Error cleaning up: #{e}"
end
# print errors
if not errors.empty?
puts
errors.each do |e|
puts e
end
exit(errors.length)
end
exit(0)
It can be used as the pre-commit script, or you can reference it in a pre-commit script like:
#!/bin/bash
REPOS=$1
TXN=$2
exec $REPOS/hooks/manifestcheck $REPOS $TXN 1>&2