Commit 75cd315d authored by Mac Newbold's avatar Mac Newbold

Add stategraph for drawing our state machines.

parent 52ac5e8e
......@@ -1193,7 +1193,8 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf db/nodelog db/webnodelog db/unixgroups \
db/dbcheck db/interswitch db/dbboot db/schemacheck \
db/grabron db/idlecheck db/webnfree discvr/GNUmakefile \
db/grabron db/idlecheck db/webnfree db/stategraph \
discvr/GNUmakefile \
ipod/GNUmakefile \
lib/GNUmakefile lib/libtb/GNUmakefile \
os/GNUmakefile os/split-image.sh os/imagezip/GNUmakefile \
......
......@@ -265,7 +265,8 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf db/nodelog db/webnodelog db/unixgroups \
db/dbcheck db/interswitch db/dbboot db/schemacheck \
db/grabron db/idlecheck db/webnfree discvr/GNUmakefile \
db/grabron db/idlecheck db/webnfree db/stategraph \
discvr/GNUmakefile \
ipod/GNUmakefile \
lib/GNUmakefile lib/libtb/GNUmakefile \
os/GNUmakefile os/split-image.sh os/imagezip/GNUmakefile \
......
......@@ -14,7 +14,7 @@ include $(OBJDIR)/Makeconf
BIN_SCRIPTS = nalloc nfree nodeip idlecheck
SBIN_SCRIPTS = avail inuse showgraph if2port backup webcontrol node_status \
genelists genelists.proxy dhcpd_makeconf nodelog unixgroups \
dbcheck interswitch dbboot grabron
dbcheck interswitch dbboot grabron stategraph
LIBEXEC_SCRIPTS = webnodelog webnfree
LIB_SCRIPTS = libdb.pm
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# All rights reserved.
#
use lib '@prefix@/lib';
use libdb;
require "ctime.pl";
my $datetag = `date +%Y%m%d%H%M%S`;
chomp($datetag);
my $date = &ctime(time);
$date =~ s/[ \t]+/ /;
$date =~ s/\n//;
my $defprefix = "stategraph-$datetag";
my $prefix = $defprefix;
my $v = 0; # Verbose
my $help=0;
my $allmodes=1;
my %modes=();
while ($_ = shift) {
print "arg: '$_'\n" if ($v);
/^-h/ && do { $help=1; next; };
/^-[dv]/ && do { $v++; next; };
/^-o/ && do { $prefix=shift || $defprefix; next; };
# if it is all lowercase, caps it, otherwise leave it alone
if ("\L$_" eq "$_") { $_ = "\U$_"; }
$modes{$_}=1;
$allmodes=0;
print "mode '$_' added.\n" if ($v);
}
if ($help) {
#Help mode
print <<EOF;
Usage: stategraph [-h] [-v] [-d] [-o <out>] [op_mode1] ...
-h This help message
-v Verbose mode. Multiple -v options cause more verbosity.
-d Debug mode. Alias for -v.
-o <out> Prefix for output filenames.
This program generates a graph of the state machines as defined in the
state_transitions and mode_transitions tables in the database. This
graph is generated from the current in the actual database, and is
always current. Output is saved into images named "out-vcg.ps" and
"out-dot.ps", where out defaults to "$defprefix".
stategraph will show state machine diagrams for all operational modes
by default, or for a subset by specifying the desired modes on the
command line.
EOF
die("\n");
}
my $filename="/tmp/stategraph-vcg-$$";
my $filename2="/tmp/stategraph-dot-$$";
open(TMP,">$filename");
open(TMPN,">$filename2");
print TMP "graph: {\n orientation: top_to_bottom\n".
" title: \"Testbed State Machines Graph - ".$date."\"\n";
print TMP " height: 500\n width: 1000\n";
print TMP " priority_phase: yes\n straight_phase: yes\n";
print TMP " arrowmode: fixed\n node. shape:ellipse\n";
print TMP " layoutalgorithm: maxdegree\n port_sharing: no\n";
# Adjust the scale here...
print TMP " display_edge_labels: yes\n scaling: 1.0\n";
# Use one of the following to control layout... whichever works better...
print TMP " crossingweight: medianbary\n splines: yes\n";
#print TMP " crossingweight: barymedian\n splines: yes\n";
#print TMPN "digraph G {\n node [shape=ellipse]\n rotate=90\n";
print TMPN "digraph G {\n node [shape=ellipse]\n";
my %states=();
my $cmd1 = "select * from state_transitions order by op_mode,state1,state2;";
my $cmd2 = "select * from mode_transitions order by op_mode1,state1,".
"op_mode2,state2;";
my $lastmode="";
my $delim="_";
my $result = DBQueryFatal($cmd1);
while(@r=$result->fetchrow()) {
$m=$r[0];
print "mode='$m' lastmode='$lastmode'\n" if ($v>1);
if (!($allmodes || (defined($modes{$m}) && $modes{$m}))) { next; }
print "mode $m is on the list\n" if ($v && !$allmodes);
if ($m ne $lastmode) {
if ($lastmode ne "") { print TMPN " }\n";}#print "Ending subgraph\n";}
print TMPN " subgraph cluster_$m {\n label = \"$m\";\n";
#print "Starting subgraph $m\n";
}
$lastmode = $m;
$s1=$r[1];
$s2=$r[2];
mkstates([$m,$s1],[$m,$s2]);
$n1 = $m.$delim.$s1;
$n2 = $m.$delim.$s2;
print TMPN " $n1 -> $n2;\n";
print TMP " edge: { sourcename: \"$n1\" targetname: \"$n2\" }\n";
}
print TMPN " }\n"; # end the last subgraph
my $modetrans=1;
$result = DBQueryFatal($cmd2);
while(@r=$result->fetchrow()) {
$m1=$r[0];
$s1=$r[1];
$m2=$r[2];
$s2=$r[3];
print "Checking mode transition ($m1, $s1) -> ($m2, $s2)\n" if ($v);
if (!( $allmodes || (defined($modes{$m1}) && $modes{$m1}) ||
(defined($modes{$m2}) && $modes{$m2}))) { next; }
print "mode $m1 or $m2 is on the list\n" if ($v && !$allmodes);
mkstates([$m1,$s1],[$m2,$s2]);
$n1=$m1.$delim.$s1;
$n2=$m2.$delim.$s2;
print TMPN " $n1 -> $n2;\n";
print TMP " edge: { sourcename: \"$n1\" targetname: \"$n2\" }\n";
}
print TMP "}\n";
close TMP;
print TMPN "}\n";
close TMPN;
print "Generating vcg graph...\n";
system("/usr/X11R6/bin/xvcg -silent -color -psoutput $prefix-vcg.ps $filename");
print "Generating dot graph...\n";
system("/usr/local/bin/dot -Tps -o $prefix-dot.ps $filename2");
print "Done.\n";
#exec "/bin/rm $filename";
sub mkstates {
foreach $pair (@_) {
my ($m, $s) = @$pair;
$n = $m.$delim.$s;
$l = $m."\n".$s;
if (!defined($states{$n})) {
if ($modetrans) {
# if we're doing modes and it isn't made yet, we don't
# have a cluster for it, so label it better for TMPN
$s=$m."\\n".$s;
}
print "Adding node '$n'\n" if ($v);
print TMP " node: { title: \"$n\" label: \"$l\"}\n";
print TMPN " $n [label=\"$s\"];\n";
$states{$n}=1;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment