In the last few days, I got the impression that my puppet class hierarchy was growing a bit out of control. In particular, it looked like "glue" classes aimed to simplify stuff were actually causing more harm than benefit. How I found out? Well, it was getting too complicated to understand what included what, and walking the classes by hand quickly became a terrible task.
So, I decided to go for something that could do the work for me: go through my modules, get the include statements, and draw the relationships. Luckily, I remembered I saw that graphviz was designed explicitly to ease that latest task. …Skimming through the documentation pointed me to a nice user guide of the "dot" tool, and some more google searches pointed me to another interesting page. That was more than enough to get started, and with some shell and perl I got my dot-file:
$ find . -type d -name modules -print | while read MODDIR ; do for DIR in $MODDIR/* ; do for FILE in $DIR/manifests/*.pp ; do egrep "(class|include)" $FILE ; done ; done ; done | perl -alne 'BEGIN { print qq[digraph P {] } ; next if /^s*#/ ; if (/class/) { $class = $F[1] ; next } ; if (/include/) { print qq{"$class" -> "$F[1]" ;} } ; END { print "}" }' > /tmp/puppet.dot
Or, more readable:
$ find . -type d -name modules -print | while read MODDIR ; do for DIR in $MODDIR/* ; do for FILE in $DIR/manifests/*.pp ; do egrep "(class|include)" $FILE ; done ; done ; done | perl -alne ' BEGIN { print qq[digraph P {] } ; next if /^s*#/ ; if (/class/) { $class = $F[1] ; next } ; if (/include/) { print qq{"$class" -> "$F[1]" ;} } ; END { print "}" }' > /tmp/puppet.dot
This produced a puppet.dot file, not 100% accurate but still useful. Now, to get an image from it:
$ dot -Tpng puppet.dot -o puppet.png
That's a PNG file, but many other formats are supported, even vector formats like SVG.
The resulting graph was the best confirmation that my class hierarchy is a complete mess, and that it really needs some reworks. sigh… :faint:
Update: it is also possible to get "isolated" nodes in the graph with a slightly change in the perl code. It's enough to change this part:
if (/class/) { $class = $F[1] ; next }
With this:
if (/class/) { print qq{"$class" ;} if $class ; $class = $F[1] ; next }
The whole line is then:
$ find . -type d -name modules -print | while read MODDIR ; do for DIR in $MODDIR/* ; do for FILE in $DIR/manifests/*.pp ; do egrep "(class|include)" $FILE ; done ; done ; done | perl -alne 'BEGIN { print qq[digraph P {] } ; next if /^s*#/ ; if (/class/) { print qq{"$class" ;} if $class ; $class = $F[1] ; next } ; if (/include/) { print qq{"$class" -> "$F[1]" ;} } ; END { print "}" }' > /tmp/puppet.dot
and the indented code is now:
$ find . -type d -name modules -print | while read MODDIR ; do for DIR in $MODDIR/* ; do for FILE in $DIR/manifests/*.pp ; do egrep "(class|include)" $FILE ; done ; done ; done | perl -alne ' BEGIN { print qq[digraph P {] } ; next if /^s*#/ ; if (/class/) { print qq{"$class" ;} if $class ; $class = $F[1] ; next } ; if (/include/) { print qq{"$class" -> "$F[1]" ;} } ; END { print "}" }' > /tmp/puppet.dot
mooolto interessante…
Originally posted by cernio:
Uhm… Come pensi di usarlo? adesso mi hai messo la curiosità… 😉
Eh pero' dovresti postare anche il png, se no… tiri il sasso e nascondi la mano? 🙂
Devo dire che aggiungere un
node [fontsize=8];
fra gli attributi del grafico produce dei risultati piacevoli 😉Originally posted by cstrep:
Ma scherzi? Mi vergogno come un ladro!!! Certe cose è meglio tenerle appese nella propria stanza, e scriverci sotto "NON LO FARÒ PIÙ" per 100 volte 😉