{"id":462,"date":"2009-08-19T18:16:57","date_gmt":"2009-08-19T17:16:57","guid":{"rendered":"http:\/\/wp.devco.net\/?p=462"},"modified":"2014-10-17T10:54:45","modified_gmt":"2014-10-17T09:54:45","slug":"tips_and_tricks_for_puppet_debugging","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2009\/08\/19\/tips_and_tricks_for_puppet_debugging.php","title":{"rendered":"Tips and Tricks for puppet debugging"},"content":{"rendered":"

We often have people asking ‘will this work…’ or ‘how do I…’ type questions on IRC, usually because it seems like such a big deal to upload a bit of code to your master just to test.<\/p>\n

Here are a quick few tips and tricks for testing out bits of puppet code to get the feel for things, I’ll show you how to test code without using your puppetmaster or needing root, so it’s ideal for just playing around on your shell, exploring the language structure and syntax..<\/p>\n

Getting more info
\n<\/strong>Most people know this one, but just running puppetd –test<\/em> will highlight all the various steps puppet is taking, any actions its
\nperforming etc in a nice colored display, handy to just do one-offs and see what is happening.<\/p>\n

Testing small bits of code:<\/strong>
\nOften you’re not sure if you’ve got the right syntax, especially for case statements, selectors and such, or you just want to test out some scenarios, you can’t just dump the stuff into your master because it might not even compile.<\/p>\n

Puppet comes with a executable called ‘puppet’ that’s perfect for this task, simply puppet some manifest into a file called test.pp and run it:<\/p>\n

<\/p>\n

puppet --debug --verbose test.pp<\/pre>\n

<\/code><\/p>\n

This will run through your code in test.pp and execute it.\u00a0 You should be aware that you couldn’t fetch files from the master in this case since it’s purely local but see the File types reference for a explanation of how the behavior changes – you can still copy files, just not from the master.<\/p>\n

You can do anything that puppet code can do, make classes, do defines, make sub classes, install packages, this is great for testing out small concepts in a safe way.\u00a0 Everything you see in this article was done in my shell like this.<\/p>\n

What is the value of a variable?<\/strong>
\nYou’ve set a variable in some class but you’re not sure if it’s set to what you’re expecting, maybe you don’t know the scoping rules just yet or you just want to log some state back to the node or master log.<\/p>\n

In a usual scripting language you’d add some debug prints, puppet is the same.\u00a0 You can print simple values in the master log by doing this in your manifest:<\/p>\n

<\/p>\n

notice(\"The value is: ${yourvar}\")<\/pre>\n

<\/code><\/p>\n

Now when you run your node you should see this being printed to the syslog (by default) on your master.<\/p>\n

To log something to your client, do this:<\/p>\n

<\/p>\n

notify{\"The value is: ${yourvar}\": }<\/pre>\n

<\/code><\/p>\n

Now your puppet logs – syslog usually – will show lines on the client or you could just do puppetd –test<\/em> on the client to see it run and see your debug bits.<\/p>\n

What is in an array?<\/strong>
\nYou’ve made an array, maybe from some external function, you want to know what is in it?\u00a0 This really is an extension to the above hint that would print garbage when passed arrays.<\/p>\n

Building on the example above and the fact that puppet loops using resources, lets make a simple defined type that prints each member of an array out to either the master or the client (use the technique above to choose)
\n<\/p>\n

\r\n$arr = [1, 2, 3]\r\n\r\ndefine print() {\r\n   notice(\"The value is: '${name}'\")\r\n}\r\n\r\nprint{$arr: }<\/pre>\n

<\/code><\/p>\n

This will print one line for each member in the array – or just one if $arr isn’t an array at all.<\/p>\n

<\/p>\n

$ puppet test.pp\r\nnotice: Scope(Print[1]): The value is: '1'\r\nnotice: Scope(Print[3]): The value is: '3'\r\nnotice: Scope(Print[2]): The value is: '2'<\/pre>\n

<\/code><\/p>\n

Writing shell scripts with puppet?<\/strong>
\nPuppet’s a great little language, you might even want to replace some general shell scripts with puppet manifest code, here’s a simple hello world:<\/p>\n

<\/p>\n

\r\n#!\/usr\/bin\/puppet\r\n\r\nnotice(\"Hello world from puppet!\")\r\nnotice(\"This is the host ${fqdn}\")<\/pre>\n

<\/code><\/p>\n

If we run this we get the predictable output:<\/p>\n

<\/p>\n

$ .\/test.pp\r\nnotice: Scope(Class[main]): Hello world from puppet!\r\nnotice: Scope(Class[main]): This is the host your.box.com<\/pre>\n

<\/code><\/p>\n

And note that you can access facts and everything from within this shell script language, really nifty!<\/p>\n

Did I get the syntax right?<\/strong>
\nIf I introduce a deliberate error in the code above – remove the last ” – it would blow up, you can test puppet syntax using puppet itself:<\/p>\n

<\/p>\n

\r\n$ puppet --parseonly test.pp\r\nerr: Could not parse for environment production: Unclosed quote after '' in 'Hello world from puppet!)\r\n' at \/home\/rip\/test.pp:1<\/pre>\n

<\/code><\/p>\n

You can combine this with a pre-commit hook on your SCM to make sure you don’t check in bogus stuff.<\/p>\n

How should I specify the package version? or user properties?<\/strong>
\nOften you’ve added a package, but not 100% sure how to pass the version string\u00a0 to ensure =><\/em> or you’re not sure how to specify password hashes etc, puppet comes with something called ralsh that can interrogate a running system, some samples below:<\/p>\n

<\/p>\n

\r\n% ralsh package httpd\r\npackage { 'httpd':\r\n    ensure => '2.2.3-22.el5.centos.2'\r\n}\r\n\r\n% ralsh package httpd.i386\r\npackage { 'httpd.i386':\r\n   ensure => '2.2.3-22.el5.centos.2'\r\n}\r\n\r\n% ralsh user apache\r\nuser { 'apache':\r\n   password => '!!',\r\n   uid => '48',\r\n   comment => 'Apache',\r\n   home => '\/var\/www',\r\n   gid => '48',\r\n   ensure => 'present',\r\n   shell => '\/sbin\/nologin'\r\n}\r\n<\/pre>\n

<\/code><\/p>\n

Note in the 2nd case I ran it as root, puppet needs to be able to read shadow and so forth.\u00a0 The code it’s outputting is valid puppet code that you can put in manifests.<\/p>\n

Will Puppet destroy my machine?<\/strong>
\nMaybe you’re just getting ready to run puppet on a host for the first time or you’re testing some new code and you want to be sure nothing terrible will happen, puppetd has a no-op option to make it just print what will happen, just run puppetd –test –noop<\/em><\/p>\n

What files etc are being managed by puppet?<\/strong>
\nSee my previous post for a script that can tell you<\/a> what puppet is managing on your machine, note this does not yet work on 0.25.x branch of code.<\/p>\n

Is my config changes taking effect?<\/strong>
\nOften people make puppet.conf<\/em> changes and it just isn’t working, perhaps they put them in the wrong [section] in the config file, a simple way to test is to run puppetd –genconfig<\/em> this will dump all the active configuration options.<\/p>\n

Be careful though don’t just dump this file over your puppet.conf<\/em> thinking you’ll have a nice commented file, this wont work as the option for genconfig<\/em> will be set to true in the file and you’ll end up with a broken configuration.\u00a0 In general I recommend keeping puppet.conf<\/em> simple and short only showing the things you’re changing away from defaults, that makes it much easier to see what differs from standard behavior when asking for help.<\/p>\n

Getting further help<\/strong>
\nPuppet has a irc channel #puppet on freenode, we try and be helpful and welcoming to newcomers, pop by if you have questions.<\/p>\n

As always you need to have these wiki pages bookmarked and they should be your daily companions:<\/p>\n