Commit cac0fafc authored by Chad Barb's avatar Chad Barb

Added new vis tools.

(we should remove the old ones soon)

These allow zooming and present (optionally)
  - Node type
  - Node IP listing
  - Link characteristics
     - always shows bw
     - shows latency if > 0
     - shows loss if > 0%

Added links in shownsfile.php3 for specifying zoom and more/less detail.
parent eb4bccb3
......@@ -8,9 +8,9 @@ SUBDIR = vis
include $(OBJDIR)/Makeconf
BIN_SCRIPTS = vistopology
BIN_SCRIPTS = vistopology dbvistopology
LIBEXEC_SCRIPTS = webvistopology
LIBEXEC_VIS = topper render top2gif top2png
LIBEXEC_VIS = topper render top2gif top2png dbtopper
#
# Force dependencies on the scripts so that they will be rerun through
......
#!/usr/bin/perl -w
use English;
use Getopt::Std;
use lib '@prefix@/lib';
use libdb;
my $optlist = "d:";
%options = ();
if (! getopts($optlist, \%options)) {
printf( "Usage:\ndbtopper [-d <detaillevel>] <pid> <eid>\n" );
die;
}
my $detail;
if (defined($options{"d"})) {
$detail = $options{"d"};
if ($detail =~ /^([0-9]+)$/) {
$detail = $1;
}
else {
die("argument to -d must be integer, not '$detail'.");
}
} else {
$detail = "0";
}
if (@ARGV != 2) {
printf( "Usage:\ndbtopper [-d <detaillevel>] <pid> <eid>\n" );
die;
}
my $pid = $ARGV[0];
my $eid = $ARGV[1];
# my $result = DBQueryFatal("SELECT vname FROM delays WHERE pid='$pid' AND eid='$eid""
my $result = DBQueryFatal("SELECT ips, type, vname FROM virt_nodes " .
"WHERE pid='$pid' AND eid='$eid'");
my %nodeip = ();
# I can visualize topologies again, Topper!
print "graph G {\n";
#my %lanips = ();
while (my ($ips, $type, $vname) = $result->fetchrow) {
$ips =~ s/^\d\://g;
$ips =~ s/\s\d\:/ /g;
$ips =~ s/^192\.168//g;
$ips =~ s/\s192\.168/ /g;
$nodeip{ $vname } = $ips;
if ($detail > 0) {
print "{node [label = \"$vname($type) $ips\", shape = box, ";
} else {
print "{node [label = \"$vname\", shape = box, ";
}
print "color = skyblue";
$vname =~ s/[^\w]/_/g;
print "] $vname}\n";
# $lanips{ $vname } .=
}
$result = DBQueryFatal("SELECT vname, delay, bandwidth, lossrate, member FROM virt_lans " .
"WHERE pid='$pid' AND eid='$eid'");
my %lansize = ();
my %lanmap = ();
my %landesc = ();
my %lanput = ();
my %singlemap = ();
while (my ($vname, $delay, $bandwidth, $lossrate, $member) = $result->fetchrow) {
$member =~ /^([^\:]+)\:/;
my $fullnodename = $1;
my $nodename = $fullnodename;
$nodename =~ s/[^\w]/_/g;
$lanmap{$vname} .= $nodename . ",";
my $desc;
if ($bandwidth >= 1000000) {
$desc = sprintf( "%.0f", ($bandwidth / 1000000) ) . "Gb";
} elsif ($bandwidth >= 1000) {
$desc = sprintf( "%.0f", ($bandwidth / 1000) ) . "Mb";
} else {
$desc = sprintf( "%.0f", $bandwidth ) . "kb";
}
if ($delay > 0) {
$desc .= " " . sprintf( "%1.0f", $delay ) . "msec";
}
if ($lossrate > 0) {
$desc .= " " . sprintf( "%1.1f", ($lossrate / 100) ) . "\%loss";
}
if ($detail > 0) {
$landesc{ $vname } = $desc;
} else {
$landesc{ $vname } = "";
}
}
foreach $i (keys %lanmap) {
my @foo = split ",", $lanmap{$i};
if (scalar( @foo ) == 2) {
print "$foo[0] -- $foo[1] [label = \"$landesc{$i}\"];\n";
} else {
my $lanname = "$i";
if (!exists $lanput{$i}) {
$lanput{$i} = 1;
print "{node [label = $lanname, shape = box, ";
print "color = green";
print "] $lanname}\n";
}
foreach $j (@foo) {
print "$j -- $lanname [label = \"$landesc{$i}\"];\n";
}
}
}
print "}\n";
#!/usr/bin/perl -wT
use English;
use Getopt::Std;
#
# Generate a PNG image of the topology for an experiment.
#
sub usage()
{
print STDOUT
"Usage: vistoplogy [-o <outputfile>] [-z <zoomfactor>] [-d <detaillevel>] <pid> <eid>\n";
exit(-1);
}
my $optlist = "o:z:d:";
#
# Configure variables
#
my $TB = "@prefix@";
#
# Testbed Support libraries
#
use lib "/usr/testbed/lib";
use libdb;
use libtestbed;
my $neato = "neato";
my $dbtopper = "$TB/libexec/vis/dbtopper";
my $render = "$TB/libexec/vis/render";
my $tbdata = "tbdata";
my $output;
my $zoom;
my $detail;
#
# Turn off line buffering on output
#
$| = 1;
#
# Untaint the path
#
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Parse command arguments. Once we return from getopts, all that should
# be left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (@ARGV != 2) {
usage();
}
my $pid = $ARGV[0];
my $eid = $ARGV[1];
if (defined($options{"o"})) {
$output = $options{"o"};
if ($output =~ /^([-\@\w.\/]+)$/) {
$output = $1;
}
else {
die("Bad data in output name: $output");
}
}
if (defined($options{"z"})) {
$zoom = $options{"z"};
if ($zoom =~ /^([\.0-9]+)$/) {
$zoom = $1;
}
else {
die("Bad data in zoom factor: $zoom");
}
}
if (defined($options{"d"})) {
$detail = $options{"d"};
if ($detail =~ /^([0-9]+)$/) {
$detail = $1;
}
else {
die("Bad data in detail level: $detail");
}
}
#
# Untaint the arguments.
#
if ($pid =~ /^([-\@\w]+)$/) {
$pid = $1;
}
else {
die("Tainted argument $pid!\n");
}
if ($eid =~ /^([-\@\w]+)$/) {
$eid = $1;
}
else {
die("Tainted argument $eid!\n");
}
#
# Verify existing experiment.
#
if (! ExpState($pid, $eid)) {
die("*** $0:\n".
" No such experiment $pid/$eid\n");
}
#
# Verify that this person is allowed to look at experiment.
#
if (! TBExptAccessCheck($UID, $pid, $eid, TB_EXPT_READINFO)) {
die("*** $0:\n".
" You do not have permission to view experiment $pid/$eid\n");
}
my $args;
if (defined($output)) {
$args = "> $output";
} else {
$args = "2> /dev/null";
}
if (defined($zoom)) {
$args = "-z $zoom $args";
}
if (defined($detail)) {
$topperargs = "-d $detail";
} else {
$topperargs = "";
}
if (system("$dbtopper $topperargs $pid $eid | $neato | $render $args") != 0) {
exit(1);
}
exit(0);
......@@ -8,15 +8,32 @@
#
use GD;
use Getopt::Std;
#
# Configure variables
#
my $TB = "@prefix@";
my $ICONDIR = "$TB/www";
my $optlist = "z:";
if (! getopts($optlist, \%options)) {
die("Usage:\nrender [-z zoomfactor]\n");
}
my $zoom = 1;
if ( defined($options{"z"} ) ) {
my $zf = $options{"z"};
if ($zf =~ /^([\.0-9]+)/) {
$zoom = $1;
} else {
die("Bad argument to -z.. must be float.");
}
}
%props = ();
%nodes = ();
%linklabels = ();
@links = ();
#parse input file
......@@ -48,7 +65,12 @@ while (<>) {
} elsif (/^\s*(\w+)\s\-\-\s(\w+)\s/) {
# a link.
($a, $b) = ($1, $2);
push( @links, $a . " " . $b );
push( @links, $a . " " . $b );
if (/label\s*\=\s*\"([^\"]*)\"/) {
$linklabels{ "$a $b" } = $1;
} elsif (/label\s*\=\s*(\w+)/) {
$linklabels{ "$a $b" } = $1;
}
}
}
......@@ -180,9 +202,17 @@ foreach $i (keys %nodepos) {
$nodepos{ $i } = [$x,$y];
}
# Uhh, Zoom Zip..
foreach $i (keys %nodepos) {
($x, $y) = ($nodepos{ $i }[0], $nodepos{ $i }[1]);
$x *= $zoom;
$y *= $zoom;
$nodepos{ $i } = [$x,$y];
}
# start constructing the image
$im = new GD::Image($xbig + 40, $ybig + 50);
$im = new GD::Image(($xbig + 60) * $zoom, ($ybig + 70) * $zoom);
$nodeicon = GD::Image->newFromPng("$ICONDIR/nodeicon.png") || warn "nodeicon.png not found";
$lanicon = GD::Image->newFromPng("$ICONDIR/lanicon.png") || warn "lanicon.png not found";
......@@ -190,6 +220,7 @@ $lanicon = GD::Image->newFromPng("$ICONDIR/lanicon.png") || warn "lanicon.png n
%colors = ();
$colors{"black"} = $im->colorAllocate(0,0,0);
$colors{"darkblue"} = $im->colorAllocate(0,0,96);
$colors{"blue"} = $im->colorAllocate(0,0,192);
$colors{"paleblue"} = $im->colorAllocate(127,127,192);
$colors{"green"} = $im->colorAllocate(0,96,0);
......@@ -258,21 +289,77 @@ foreach $i (keys %nodes) {
# this is done in a second pass so no text is obscured by
# boxes.
foreach $i (@links) {
if (exists $linklabels{ $i }) {
($a, $b) = ($i =~ /(\w+)\s(\w+)/);
($x1, $y1) = ($nodepos{ $a }[0], $nodepos{ $a }[1]);
($x2, $y2) = ($nodepos{ $b }[0], $nodepos{ $b }[1]);
($x, $y) = ( ($x1 + $x2) / 2, ($y1 + $y2) / 2 );
my @lines = split " ", $linklabels{ $i };
$y -= (0.5 * (@lines * gdTinyFont->height));
my $linenum = 0;
foreach $j (@lines) {
$xpos = $x - (((length($j) - 0.5) * $fontw) / 2);
$im->string(gdTinyFont, $xpos + 1, $y,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos - 1, $y,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y - 1,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y + 1,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y,
$j, $colors{"darkblue"});
$y += gdTinyFont->height;
}
}
}
foreach $i (keys %nodes) {
($x, $y) = ($nodepos{ $i }[0], $nodepos{ $i }[1]);
$xpos = $x - (((length($i) - 0.5) * $fontw) / 2);
$im->string(gdSmallFont, $xpos + 1, $y + 20,
$i, $bgcolor);
$im->string(gdSmallFont, $xpos - 1, $y + 20,
$i, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 19,
$i, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 21,
$i, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 20,
$i, $colors{"black"});
# my $nm = $i;
my $nm = $nodes{$i}{"label"};
my @lines = split " ", $nm;
my $linenum = 0;
foreach $j (@lines) {
# warn "$j $x $y!";
if ($linenum++ == 0) {
$xpos = $x - (((length($j) - 0.5) * gdSmallFont->width) / 2);
$im->string(gdSmallFont, $xpos + 1, $y + 20,
$j, $bgcolor);
$im->string(gdSmallFont, $xpos - 1, $y + 20,
$j, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 19,
$j, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 21,
$j, $bgcolor);
$im->string(gdSmallFont, $xpos, $y + 20,
$j, $colors{"black"});
$y += gdSmallFont->height;
} else {
$xpos = $x - (((length($j) - 0.5) * gdTinyFont->width) / 2);
$im->string(gdTinyFont, $xpos + 1, $y + 20,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos - 1, $y + 20,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y + 19,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y + 21,
$j, $bgcolor);
$im->string(gdTinyFont, $xpos, $y + 20,
$j, $colors{"black"});
$y += gdTinyFont->height;
}
}
}
#write it to stdout
......
......@@ -15,6 +15,6 @@ my $TB = "@prefix@";
#
# Run the real thing, and never return.
#
exec "$TB/bin/vistopology", @ARGV;
exec "$TB/bin/dbvistopology", @ARGV;
die("webvistopology: Could not exec vistopology: $!");
die("webvistopology: Could not exec dbvistopology: $!");
......@@ -27,6 +27,11 @@ if (!isset($eid) ||
USERERROR("You must provide an Experiment ID.", 1);
}
# if they dont exist, or are non-numeric, use defaults.
# note: one can use is_numeric in php4 instead of ereg.
if (!isset($zoom) || !ereg("^[0-9]{1,50}.?[0-9]{0,50}$", $zoom)) { $zoom = 1; }
if (!isset($detail) || !ereg("^[0-9]{1,50}$", $detail)) { $detail = 0; }
#
# Check to make sure this is a valid PID/EID tuple.
#
......@@ -72,7 +77,28 @@ if (strcmp($expstate, $TB_EXPTSTATE_ACTIVE) == 0 ||
strcmp($expstate, $TB_EXPTSTATE_SWAPPED) == 0) {
echo "<br>
<center>
<img src='top2image.php3?pid=$pid&eid=$eid' align=center>
<img src='top2image.php3?pid=$pid&eid=$eid&zoom=$zoom&detail=$detail' align=center>
<h5>
zoom:
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=1.00&detail=$detail'>100%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=1.12&detail=$detail'>112%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=1.25&detail=$detail'>125%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=1.50&detail=$detail'>150%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=2.00&detail=$detail'>200%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=2.50&detail=$detail'>250%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=3.00&detail=$detail'>300%</a>
<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=4.00&detail=$detail'>400%</a>
<br>";
if ($detail == 0) {
if ($zoom < 1.5) {
echo "<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=1.50&detail=1'>More detail (and zoom)</a>";
} else {
echo "<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=$zoom&detail=1'>More detail</a>";
}
} else {
echo "<a href='shownsfile.php3?pid=$pid&eid=$eid&zoom=$zoom&detail=0'>Less detail</a>";
}
echo " </h5>
</center>\n";
}
......
......@@ -27,6 +27,14 @@ if (!isset($eid) ||
$exp_eid = $eid;
$exp_pid = $pid;
# if they dont exist, or are non-numeric, use defaults.
# note: one can use is_numeric in php4 instead of ereg.
if (!isset($zoom) || !ereg("^[0-9]{1,50}.?[0-9]{0,50}$", $zoom)) { $zoom = 1; }
if (!isset($detail) || !ereg("^[0-9]{1,50}$", $detail)) { $detail = 0; }
if ($zoom > 8.0) { $zoom = 8.0; }
if ($zoom <= 0.0) { $zoom = 1.0; }
#
# Check to make sure this is a valid PID/EID tuple.
#
......@@ -52,10 +60,14 @@ if (ISADMIN($uid)) {
$gid = $exp_pid;
}
# note that we've already ensured that $detail is numeric above.
if ($detail != 0) { $detailstring = "-d $detail"; } else { $detailstring = ""; }
#
# Spit out the image with a content header.
#
if ($fp = popen("$TBSUEXEC_PATH $uid $gid webvistopology $pid $eid", "r")) {
if ($fp = popen("$TBSUEXEC_PATH $uid $gid webvistopology $detailstring -z $zoom $pid $eid", "r")) {
header("Content-type: image/png");
fpassthru($fp);
}
......@@ -64,3 +76,6 @@ if ($fp = popen("$TBSUEXEC_PATH $uid $gid webvistopology $pid $eid", "r")) {
# No Footer!
#
?>
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