When the client requests a catalog, it is compiled on the master and sent down to the client. If the catalog fails to compile, the error is printed and can, most likely, be corrected easily. For example, the following base
class has an obvious error:
class base { file {'one': path => '/tmp/one', ensure => 'directory', } file {'one': path => '/tmp/one', ensure => 'file', } }
The file resource is defined twice with the same name. The error appears when we run Puppet, as shown in the following screenshot:
Fixing this type of duplicate declaration is very straightforward; the line numbers of each declaration are printed in the error message. Simply locate the two files and remove one of the entries.
A more perplexing issue is when the catalog compiles cleanly but fails to apply on the node. The catalog is stored in the agent's client_data
directory (current versions use JSON files, earlier versions used YAML files). In this case, the file is stored in /opt/puppetlabs/puppet/cache/client_data/catalog/client.example.com.json
. Using jq
, we can examine the JSON file and find the problem definitions.
jq
is a JSON processor and is available in the EPEL repository on enterprise Linux installations.
[root@client catalog]# jq .resources[].title <client.example.com.json "main" "Settings" "Main" "default" "Base" "one"
You can always just read the JSON file directly, but using jq
on extremely large files is useful. You can use jq
as you would use grep on a file, thus making searching within a JSON file much easier. More information on jq
can be found at http://stedolan.github.io/jq/.
Now, to look at our problem definition, we'll select the resource whose title is "one"
, as shown here:
[root@client catalog]# jq '.resources[] | select(.title=="one")' <client.example.com.json { "type": "File", "title": "one", "tags": [ "file", "one", "class", "base", "node", "default" ], "file": "/etc/puppetlabs/code/environments/production/modules/base/manifests/init.pp", ` "line": 17, "exported": false, "parameters": { "path": "/tmp/one", "ensure": "directory" } }
You may force a master to compile a catalog for a node, as follows (Puppet will print out the catalog, in JSON format, to the terminal):
[root@stand ~]# puppet master --compile client.example.com Notice: Compiled catalog for client.example.com in environment production in 0.60 seconds { "tags": ["settings","default","base","node","class"], "name": "client.example.com", "version": 1450506795, "environment": "production", "resources": [ ...
Using puppet master --compile
, you can also select to run a full trace on the compilation with the --trace
option. This option will show which providers were run and a much higher level of detail than the debug output. To do so, specify the log destination as well. Running a full trace will generate a lot of data and you'll want to store that in a log file.
The following output shows that we can see a lot more information than what the normal --debug
flag will show. The log file will also compile the catalog in the production environment by default:
To compile for another environment, specify the environment with –environment
, as shown in the following command:
[root@stand ~]# puppet master --compile client.example.com --debug --trace --logdest /var/log/puppetlabs/client.example.com.log --environment sandbox
The /opt/puppetlabs/puppet/cache/state/classes.txt
file contains a list of classes applied to the machine. If you are having trouble with a node, you can search here for the last set of classes that were successfully applied to a node. But, when you are having trouble, you are most interested in the classes in the current catalog and the classes that are different or missing. We can use jq
again to query the JSON of the current catalog, as shown in the following command:
[root@client ~]# jq .classes[] </opt/puppetlabs/puppet/cache/client_data/catalog/client.example.com.json "settings" "default" "base"
We can compare the list of classes returned by jq
to those listed in classes.txt
. The classes shown in classes.txt
are from the last successful run of Puppet. The file is created at the end of the Puppet agent run. The classes returned by jq
are from the catalog, which just fails to apply if we are debugging. These two lists will be consistent on a node with a successful Puppet agent run.