Drawing puppet class relationships with graphviz

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 
Advertisement

5 thoughts on “Drawing puppet class relationships with graphviz

  1. Originally posted by cstrep:

    Eh pero' dovresti postare anche il png

    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 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.