Use dot rather than neato, for generally nicer output

Add some graphviz-layout specific commands
Quoting improvements, so that e.g. VLAN interfaces link correctly
Add trial code for alternate label places
This commit is contained in:
Philip Whineray 2016-04-07 23:03:39 +01:00
parent c544e3c919
commit 2fd5b180bb
3 changed files with 214 additions and 53 deletions

@ -356,6 +356,7 @@ AX_NEED_PROG([IP], [ip], [])
AX_NEED_PROG([MKDIR], [mkdir], []) AX_NEED_PROG([MKDIR], [mkdir], [])
AX_NEED_PROG([MKTEMP], [mktemp], []) AX_NEED_PROG([MKTEMP], [mktemp], [])
AX_CHECK_PROG([NEATO], [neato], []) AX_CHECK_PROG([NEATO], [neato], [])
AX_CHECK_PROG([DOT], [dot], [])
AX_NEED_PROG([RM], [rm], []) AX_NEED_PROG([RM], [rm], [])
AX_CHECK_PROG([SH], [sh], []) AX_CHECK_PROG([SH], [sh], [])
AX_CHECK_PROG([SH], [bash], []) AX_CHECK_PROG([SH], [bash], [])

@ -25,6 +25,7 @@ CUT_CMD="@CUT@"
DATE_CMD="@DATE@" DATE_CMD="@DATE@"
DIFF_CMD="@DIFF@" DIFF_CMD="@DIFF@"
DIRNAME_CMD="@DIRNAME@" DIRNAME_CMD="@DIRNAME@"
DOT_CMD="@DOT@"
EGREP_CMD="@EGREP@" EGREP_CMD="@EGREP@"
ENV_CMD="@ENV@" ENV_CMD="@ENV@"
EXPR_CMD="@EXPR@" EXPR_CMD="@EXPR@"

@ -66,9 +66,26 @@ test $status -eq 0 || exit $status
needroot=Y needroot=Y
haderror="" haderror=""
#gvprog=dot #gvprog=$NEATO_CMD
#gvprog=sfdp gvprog=$DOT_CMD
gvprog=$NEATO_CMD
gv_devices_left_right=
if [ "$gv_devices_left_right" ]
then
# Format graph as host | dev1 | dev2 | ...
gvdevdownopen=""
gvdevdownclose=""
else
# Format graph as host
# dev1
# dev2
# ...
gvdevdownopen="{"
gvdevdownclose="}"
fi
gv_label_outside="Y"
gv_label_outside=""
setup="$1" setup="$1"
mode="$2" mode="$2"
@ -85,6 +102,7 @@ case "$mode" in
;; ;;
graphviz) graphviz)
common_require_cmd $PROGRAM_FILE NEATO_CMD common_require_cmd $PROGRAM_FILE NEATO_CMD
common_require_cmd $PROGRAM_FILE DOT_CMD
needroot= needroot=
case "$outfile" in case "$outfile" in
*.gv|"") *.gv|"")
@ -102,6 +120,10 @@ case "$mode" in
format=png format=png
graphviz="$gvprog -T$format" graphviz="$gvprog -T$format"
;; ;;
*.svg)
format=svg
graphviz="$gvprog -T$format"
;;
*) *)
1>&2 echo "Unrecognised file extension: $mode" 1>&2 echo "Unrecognised file extension: $mode"
haderror="Y" haderror="Y"
@ -186,22 +208,40 @@ $SED_CMD = "$setup" > $MYTMP/withnum
$MKDIR_CMD $MYTMP/ns $MKDIR_CMD $MYTMP/ns
$MKDIR_CMD $MYTMP/runtime-lines $MKDIR_CMD $MYTMP/runtime-lines
$MKDIR_CMD $MYTMP/clusters
> $MYTMP/clusterlist
current_name= current_name=
declare_namespace() {
errline=$lineno
local current_name="$1"
local NSTMP=$MYTMP/ns/$current_name
if [ -d $NSTMP ]
then
return 0
fi
$MKDIR_CMD $NSTMP
echo $errline > $NSTMP/undefined
$MKDIR_CMD $NSTMP/devices
$MKDIR_CMD $NSTMP/devicepairs
}
create_namespace() { create_namespace() {
errline=$lineno errline=$lineno
local type="$1" current_name="$1"
current_name="$2" local type="$2"
NSTMP=$MYTMP/ns/$current_name NSTMP=$MYTMP/ns/$current_name
if [ -d $NSTMP ] if [ ! -f $NSTMP/undefined ]
then then
error="$current_name: $($CAT_CMD $NSTMP/type) already defined" error="$current_name: $($CAT_CMD $NSTMP/type) already defined"
return 1 return 1
fi fi
$MKDIR_CMD $NSTMP $RM_CMD -f $NSTMP/undefined
$MKDIR_CMD $NSTMP/devices
$MKDIR_CMD $NSTMP/devicepairs
echo $type > $NSTMP/type echo $type > $NSTMP/type
echo 0 > $NSTMP/forward echo 0 > $NSTMP/forward
> $NSTMP/routes > $NSTMP/routes
@ -214,12 +254,14 @@ create_namespace() {
host() { host() {
errline=$lineno errline=$lineno
create_namespace host "$1" declare_namespace "$1"
create_namespace "$1" host
} }
switch() { switch() {
errline=$lineno errline=$lineno
create_namespace switch "$1" declare_namespace "$1"
create_namespace "$1" switch
} }
dev() { dev() {
@ -281,8 +323,7 @@ dev() {
then then
if [ ! -d $MYTMP/ns/$otherns ] if [ ! -d $MYTMP/ns/$otherns ]
then then
error="$otherns undefined" declare_namespace "$otherns"
return 1
fi fi
echo "$current_name $device" > $MYTMP/ns/$otherns/devicepairs/$otherdev echo "$current_name $device" > $MYTMP/ns/$otherns/devicepairs/$otherdev
echo "n/a n/a" > $NSTMP/devicepairs/$device echo "n/a n/a" > $NSTMP/devicepairs/$device
@ -398,6 +439,60 @@ pre_up() {
return 0 return 0
} }
gv_label() {
errline=$lineno
if [ ! "$current_name" ]
then
error="can only specify gv_label in a host or switch"
return 1
fi
if [ -f $NSTMP/gv_label ]
then
echo -n '\\n' >> $NSTMP/gv_label
fi
echo -n "$*" >> $NSTMP/gv_label
return 0
}
gv_omit() {
errline=$lineno
if [ ! "$current_name" ]
then
error="can only specify gv_omit in a host or switch"
return 1
fi
echo > $NSTMP/gv_omit
return 0
}
gv_cluster() {
errline=$lineno
local cluster="$1"
shift
if [ ! "$current_name" ]
then
error="can only specify gv_cluster in a host or switch"
return 1
fi
if [ ! -f $MYTMP/clusters/$cluster ]
then
echo "$cluster" >> $MYTMP/clusterlist
if [ "$*" ]
then
echo "$*" > $MYTMP/clusters/$cluster.label
fi
fi
local type="$($CAT_CMD $NSTMP/type)"
echo "${type}_$current_name" >> $MYTMP/clusters/$cluster
return 0
}
is_ipv6() { is_ipv6() {
case "$1" in case "$1" in
*:*) *:*)
@ -629,52 +724,85 @@ then
then then
echo "size=7; /* Max size 7 inches */" >>$gv echo "size=7; /* Max size 7 inches */" >>$gv
fi fi
echo "overlap=prism;" >>$gv echo "overlap=scale;" >>$gv
#echo "splines=compound;" >>$gv
echo "node [sep=10];" >>$gv
echo "edge [color=blue,style=dashed];" >>$gv echo "edge [color=blue,style=dashed];" >>$gv
while read cluster
do
echo "subgraph cluster_$cluster{" >>$gv
if [ -s "$MYTMP/clusters/$cluster.label" ]
then
echo "label=\"`$CAT_CMD $MYTMP/clusters/$cluster.label`\"" >>$gv
fi
while read ns
do
echo "$ns" >>$gv
done < $MYTMP/clusters/$cluster
echo "}" >>$gv
done < $MYTMP/clusterlist
while read ns while read ns
do do
type="$($CAT_CMD $MYTMP/ns/$ns/type)" type="$($CAT_CMD $MYTMP/ns/$ns/type)"
if [ "$type" = "switch" ] if [ -f $MYTMP/ns/$ns/gv_label ]
then then
echo "switch_$ns [shape=polygon,sides=4,skew=.4,label=\"$ns\"];" >>$gv read label < $MYTMP/ns/$ns/gv_label || true
else else
echo -n "host_$ns [shape=record,label=\"$ns" >>$gv label="$ns"
while read route fi
do
echo -n "\\n$route" >>$gv if [ ! -f $MYTMP/ns/$ns/gv_omit ]
done < $MYTMP/ns/$ns/routes then
while read bridge if [ "$type" = "switch" ]
do then
echo -n "|{<$bridge> $bridge" >>$gv echo "\"switch_$ns\" [shape=ellipse,label=\"$label\"];" >>$gv
while read ip else
echo -n "\"host_$ns\" [shape=record,label=\"$gvdevdownopen$label" >>$gv
while read route
do do
echo -n "\\n$ip" >>$gv echo -n "\\n$route" >>$gv
done < $MYTMP/ns/$ns/devices/$bridge done < $MYTMP/ns/$ns/routes
while read dev while read bridge
do do
echo -n "|{" >>$gv echo -n "|{<$bridge> $bridge" >>$gv
echo -n "<$dev> $dev" >>$gv
while read ip
do
echo -n "\n$ip" >>$gv
done < $MYTMP/ns/$ns/devices/$dev
echo -n "}" >>$gv
echo "$bridge" > $MYTMP/ns/$ns/suppress-$dev
done < $MYTMP/ns/$ns/devices/$bridge-bridged
echo -n "}" >>$gv
done < $MYTMP/ns/$ns/bridgelist
while read dev
do
if [ ! -f $MYTMP/ns/$ns/suppress-$dev ]
then
echo -n "|<$dev> $dev" >>$gv
while read ip while read ip
do do
echo -n "\\n$ip" >>$gv echo -n "\\n$ip" >>$gv
done < $MYTMP/ns/$ns/devices/$dev done < $MYTMP/ns/$ns/devices/$bridge
fi while read dev
done < $MYTMP/ns/$ns/devlist do
echo "\"];" >>$gv echo -n "|{" >>$gv
echo -n "<$dev> $dev" >>$gv
if [ ! "$gv_label_outside" ]
then
while read ip
do
echo -n "\n$ip" >>$gv
done < $MYTMP/ns/$ns/devices/$dev
fi
echo -n "}" >>$gv
echo "$bridge" > $MYTMP/ns/$ns/suppress-$dev
done < $MYTMP/ns/$ns/devices/$bridge-bridged
echo -n "}" >>$gv
done < $MYTMP/ns/$ns/bridgelist
while read dev
do
if [ ! "$gv_label_outside" -a ! -f $MYTMP/ns/$ns/suppress-$dev ]
then
echo -n "|<$dev> $dev" >>$gv
while read ip
do
echo -n "\\n$ip" >>$gv
done < $MYTMP/ns/$ns/devices/$dev
fi
done < $MYTMP/ns/$ns/devlist
echo "$gvdevdownclose\"];" >>$gv
fi
fi fi
done < $MYTMP/nslist done < $MYTMP/nslist
while read ns while read ns
@ -686,19 +814,50 @@ then
if [ "$ons" != "n/a" ] if [ "$ons" != "n/a" ]
then then
otype="$($CAT_CMD $MYTMP/ns/$ons/type)" otype="$($CAT_CMD $MYTMP/ns/$ons/type)"
if [ "$type" = "switch" ] if [ "$type" = "switch" ]
then then
from="switch_$ns" from="\"switch_$ns\""
fromlabel="taillabel=\"\\n\\n\""
else else
from="host_$ns:$dev" from="\"host_$ns\":\"$dev\""
fromlabel="taillabel=\"$dev"
while read ip
do
fromlabel="$fromlabel\\n$ip"
done < $MYTMP/ns/$ns/devices/$dev
fromlabel="$fromlabel\""
fi fi
if [ "$otype" = "switch" ] if [ "$otype" = "switch" ]
then then
to="switch_$ons" to="\"switch_$ons\""
tolabel="headlabel=\"\\n\\n\""
else else
to="host_$ons:$odev" to="\"host_$ons\":\"$odev\""
tolabel="headlabel=\"$odev"
while read ip
do
tolabel="$tolabel\\n$ip"
done < $MYTMP/ns/$ons/devices/$odev
tolabel="$tolabel\""
fi
alllabels=""
if [ "$gv_label_outside" ]
then
if [ "$fromlabel" -o "$tolabel" ]
then
if [ "$fromlabel" -a "$tolabel" ]
then
alllabels=" [labelfloat=false,$fromlabel,$tolabel]"
else
alllabels=" [labelfloat=false,$fromlabel$tolabel]"
fi
fi
fi
if [ ! -f $MYTMP/ns/$ns/gv_omit -a ! -f $MYTMP/ns/$ons/gv_omit ]
then
echo "$from -- $to$alllabels;" >>$gv
fi fi
echo "$from -- $to;" >>$gv
else else
: # gets set up from the other end : # gets set up from the other end
fi fi