The Augtool
In a previous post on augeas in puppet I mentioned I’d be writing another post on debugging with the command line augeas tool since the puppet augeas provider doesn’t provide the clearest way of debugging.
Puppet with augeas requires the --debug
flag to be set for it to print out the statements it is running via augeas but by the time you’ve got an error in your manifest run, the issue might not be replicable; such as a malformed insertion resulting in an onlyif check failing and allowing other statements to run.
Using the command line tooling will enable you to get your syntax correct without flushing the changes to disk (the save
command) or having to run your puppet manifest every time you try to construct a match
query for example, it makes for a much quicker process.
Augtool
Augtool is the command line Augeas tool, it is useful for prototyping changes before you run puppet (as provisioning a whole system can take time).
It is installed via apt-get: sudo apt-get install augeas-tools
.
Lenses are used to allow Augeas to read and manipulate file formats such as .xml, .conf etc. they are stored in either /usr/share/augeas/lenses/
or /usr/local/share/augeas/lenses
.
Starting the tool:
augtool --noload --noautoload --echo
will start the augeas command line tool.
Install the lens to use:
set /augeas/load/xml/lens/ "Xml.lns"
Add the file you wish to parse (adds this file to the existing list of files):
set /augeas/load/xml/incl/ "/filepath.xml"
Load these settings:
load
Now you’re ready to query your file contents:
augtool print /files/<filepath>
will print the augeas representation of the file to standard out, this is very useful for debugging and knowing how to reference parts of a file.
augtool print /files/<filepath> > some.txt
will capture the output into a file.
Augtool (and the augeas resource by proxy) has a number of operations you can perform on a file:
set path/in/file value
set a value for the specified entryrm path/in/file
will remove the entryclear path/in/file
will remove any sub entries or attributes from the entry, best used before remove a bit like doingrm dir/*
beforermdir dir
Note these operations can have different value syntax based on the lens used.ins path/in/file value
will create an entirely new entry, a bit likeset
but will fail if an entry already exists, whereas set will overwritematch path/in/file/arg size == 0
can be used for conditional execution (using puppet’sonlyif
) in this example we are checking if the arguments of the file leaf are of size 0.
When performing any of the operations above you can also use a rich assortment of path expressions:
set path/in/file[last()+1] value
the built in function last() can be used within square brackets to handle positional path manipulation in this example to insert a new entry after the last one.path/in/file[. = 'value']
will match on a path where the current entry (denoted by the period) matches the specified string.path/in[file = 'value']
is equivalent to the above example except we’re matching from the perspective of thein
node and examining if the childfile
matches with thevalue
and
andor
can be used to match multiple predicates- Ordering of predicate evaluation is important
/files/etc/services/service-name[port = '22'][last()]
will find the last service with a port of 22 whereas/files/etc/services/service-name[last()][port = '22']
will match if the last service out of all services has a port of 22. - There are many more to play around with as detailed in path expressions such as self, child, parent.
Flush your changes to disk:
save
Debugging with Augtool
print /augeas//error
will print off the errors tha augeas has encountered.
ls /files/<path>
can be used like ls in linux to query what augeas can see, also brings auto-tab completion.
The following:
/augeas/files/var/lib/jenkins/config.xml/error = "mk_augtemp"
/augeas/files/var/lib/jenkins/config.xml/error/message = "Permission denied"
Is encountered when augeas doesn’t have permission to modify a file, run the tool with admin permissions (e.g. sudo
or su
).
Conclusion
Sensible use of Augeas should prevent overly large and verbose .erb
templates from becoming common place in your puppet code. The main thing hindering more widespread use of augeas is the rather sparse documentation, especially when it comes to the lenses, instead you tend to have to rely on loading up Augtool with the lens and a process of trial and error to see how the file gets parsed and modified.