Graphviz

En muchas ocasiones necesito dibujar un diagrama que ilustre alguna explicación. Estos diagramas suelen ser complejos y, en muchos casos, repetitivos. Por ejemplo, una tabla de páginas con sus correspondientes marcos de página físicos y flechas que los conecten. O una red compleja. En muchos casos hay un programa específico que lo puede hacer.

Yo suelo usar DIA o una extensión de Google Drive llamada Draw.io para los diagramas simples o que necesitan ser vistosos.

Pero, en ocasiones, echo de menos una manera de hacerlo automático. Para ello se puede usar un programa muy veterano llamado Graphviz. Este programa lleva más de 26 años funcionando y dibuja los diagramas interpretando el lenguage DOT. Es muy probable que el estilo nos resulte familiar, como el de los diagramas de los libros teóricos de la universidad.

Gracias a que DOT es un lenguaje relativamente fácil de generar con scripts, puedo crear diagramas complejos a partir de otros datos o inventados.

Por ejemplo, este código permite mostrar un diagrama de la red de contenedores LXD:

#!/bin/bash
echo 'digraph {
graph [pad="0.5", nodesep="0.5", ranksep="2", splines=ortho,];
node [shape=none]
rankdir=LR;'
bridges=($(brctl show | tail -n +2 |cut -f1 | tr "\n" " "))
for i in ${bridges[@]}
do
echo "$i [label=\"$i\" shape=box];"
done
containers=($(lxc list | egrep '(STOPPED|RUNNING)' | cut -d" " -f2 | tr "\n" " "))
xarxes="$(lxc list --format json | jq -r '.[] | {container: .name, dev: .expanded_devices[]} | [.container,.dev.name,.dev.parent,.dev.type] | @csv' | grep '"nic"$')"
relations=""
for i in ${containers[@]}
do
pc="$i [label=<<table border=\"0\" cellborder=\"1\" cellspacing=\"0\"><tr><td bgcolor=\"#CCCCCC\" >$i</td></tr>"
while read dev
do
nom=$(echo $dev | cut -d "," -f2 | tr -d '"')
switch=$(echo $dev | cut -d"," -f3 | tr -d '"')
pc=$pc"<tr><td port=\"$nom\">$nom</td></tr>"
#La IP
ip=$(lxc info $i | tr "\t" " " | grep "$nom: inet " | tr -s " " | cut -d" " -f4)
relations=$relations"$switch -> $i:$nom [dir=none headlabel=\"$ip\"] \n"

done <<< "$(echo "$xarxes" | grep "$i")"
pc=$pc"</table>>];"
echo $pc
done
echo -e "$relations"
echo '}'

Esto genera un fichero DOT como este:

digraph {
graph [pad="0.5", nodesep="0.5", ranksep="2", splines=ortho,];
node [shape=none]
rankdir=LR;
lxdbr0 [label="lxdbr0" shape=box];
switch1 [label="switch1" shape=box];
switch2 [label="switch2" shape=box];
dns1 [label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="#CCCCCC" >dns1</td></tr><tr><td port="eth1">eth1</td></tr></table>>];
dns2 [label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="#CCCCCC" >dns2</td></tr><tr><td port="eth1">eth1</td></tr></table>>];
firewall [label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="#CCCCCC" >firewall</td></tr><tr><td port="eth0">eth0</td></tr><tr><td port="eth1">eth1</td></tr></table>>];
pc1 [label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="#CCCCCC" >pc1</td></tr><tr><td port="eth1">eth1</td></tr></table>>];
pc2 [label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="#CCCCCC" >pc2</td></tr><tr><td port="eth1">eth1</td></tr></table>>];
switch1 -> dns1:eth1 [dir=none headlabel="10.20.30.100"]
switch1 -> dns2:eth1 [dir=none headlabel="10.20.30.200"]
lxdbr0 -> firewall:eth0 [dir=none headlabel="10.150.173.32"]
switch1 -> firewall:eth1 [dir=none headlabel="10.20.30.254"]
switch1 -> pc1:eth1 [dir=none headlabel=""]
switch1 -> pc2:eth1 [dir=none headlabel="10.20.30.2"]
}

El resultado sería algo así:

Para hacer el gráfico hago uso de jq i de la extension html-like de graphviz.

Usando LXD para prácticas

Este año estoy usando LXD para que los alumnos hagan las prácticas de Sistemas Operativos y de Servicios en Red. La manera en que lo tengo organizado es la siguiente:

  • En cada aula hay un servidor que hace de proxy y da DHCP a los PC del aula. Este no es demasiado potente, ya que sólo es la puerta de enlace al exterior.
  • Tengo un servidor más potente (i5 i 8GB) que hace de servidor de LXD. Este tiene 15 contenedores (15 alumnos en segundo) y cada uno de ellos 3 contenedores en «Nesting».
  • Cada uno de los 15 contenedores tiene asignada por DHCP, gracias al servidor de proxy, una IP que acaba en el número de asiento del alumno. Por ejemplo, el alumno 12 tiene la IP que acaba en 212.
  • Los alumnos tienen un usuario y contraseña para entrar a su contenedor por SSH.
  • Los alumnos son administradores de ese contenedor y pueden modificar los ‘subcontenedores’ o instalar programas.
  • Una vez dentro de los contenedores que ellos administran, pueden crear servidores y clientes o lo que necesiten.
  • De esta manera yo siempre tengo acceso a todo por SSH y porque administro el servidor que los contiene. Entre los turnos de mañana y tarde hemos llegado a tener más de 90 contenedores en marcha. El disco duro es el cuello de botella en mi caso, ya que sólo van lentos en el arranque.

Ventajas:

  • Ellos no tienen que hacerse máquinas virtuales y llenar el disco duro de su ordenador.
  • Se puede controlar todo el trabajo desde una terminal.
  • Puedo hacer exámenes y corregirlos sin que me tengan que enviar la máquina virtual o los ficheros de configuración. Puedo probar directamente que funciona.

Inconvenientes:

  • No pueden llevarse fácilmente en trabajo a casa. Aunque pueden acceder de forma remota siempre que les abras el puerto.
  • No se pueden hacer contenedor de Windows.

Si queréis saber más, en este enlace tengo apuntes de cómo se ha configurado todo.

El módulo «Sistemas Informáticos»

El año pasado me tocó impartir el módulo «Sistemas Informáticos» del ciclo superior de DAM (Desarrollo de Aplicaciones Multiplataforma). Se trata de un módulo de 5 horas en el que se debe enseñar hardware (desde la teoría de los computadores hasta reparar un PC), sistemas operativos, seguridad, redes y Shell script.

Como se puede deducir, es una barbaridad para solo 5 horas a la semana durante un curso. Además, es un ciclo superior en el que se espera que adquieran un buen nivel. Yo suelo decir a mis alumnos que van a dar los 2 cursos del ciclo de grado medio comprimidos en un solo módulo.

El año pasado me fue bien, en gran parte por el buen nivel de la mayoría de alumnos. Pero sigo dándole vueltas a cómo enfocar la enseñanza de toda la informática menos la programación en tan poco tiempo.

Sigue leyendo