Commit 79ae0bfe authored by Leigh Stoller's avatar Leigh Stoller

Next checkpoint of graphing code. On a currently active template

instance there are graphs on the instance show page and on the
individual run show pages. On the run pages, the graphs select just
the packets between start and stop of the run. I also added drop down
menus to select particular source and destination vnodes.
parent 28f917c6
......@@ -7,8 +7,7 @@
use English;
use strict;
use Getopt::Std;
use POSIX qw(isatty setsid);
use POSIX qw(strftime);
use Date::Parse;
use Errno qw(EDQUOT);
use Data::Dumper;
......@@ -46,6 +45,8 @@ my $runidx;
my $guid;
my $version;
my $graphtype;
my $srclan;
my $dstlan;
my $srcvnode;
my $dstvnode;
......@@ -165,6 +166,7 @@ if (! keys(%runlist)) {
if ($instance->Instantiated()) {
my $experiment = Experiment->Lookup($instance->pid(), $instance->eid());
my $eid = $instance->eid();
fatal(-1, "Could not get experiment object from $instance!")
if (!defined($experiment));
......@@ -173,8 +175,51 @@ if ($instance->Instantiated()) {
if (! $experiment->dpdb() || !$experiment->dpdbname());
my $dbname = $experiment->dpdbname();
my $optargs = "";
system("$dbcontrol graphdb $dbname $graphtype") == 0 or
#
# For a specific run, figure out the start and end times of the run
# and pass those along as options to the graphing code.
#
if (defined($runidx)) {
my $rowref = $runlist{$runidx};
my $start = $rowref->{"start_time"};
my $stop = $rowref->{"stop_time"};
if (defined($stop)) {
$optargs = "-r " . str2time($start) . ":" . str2time($stop);
}
else {
$optargs = "-r " . str2time($start) . ":0";
}
}
if (defined($srcvnode)) {
my $query_result =
DBQueryFatal("select ip from virt_lans ".
"where vname='$srclan' and vnode='$srcvnode' and ".
" pid='$pid' and eid='$eid'");
if ($query_result->numrows) {
my ($ip) = $query_result->fetchrow_array();
$optargs .= " -s $ip";
}
}
if (defined($dstvnode)) {
my $query_result =
DBQueryFatal("select ip from virt_lans ".
"where vname='$dstlan' and vnode='$dstvnode' and ".
" pid='$pid' and eid='$eid'");
if ($query_result->numrows) {
my ($ip) = $query_result->fetchrow_array();
$optargs .= " -t $ip";
}
}
# SENDMAIL($TBOPS, "foo", "$dbname $graphtype $optargs");
system("$dbcontrol graphdb $dbname $graphtype $optargs") == 0 or
fatal(-1, "Failed to generate requested graph!");
}
exit(0);
......@@ -244,33 +289,26 @@ sub ParseArgs()
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper run index!");
}
# real check.
if ($runidx =~ /^([\w]*)$/) {
$runidx = $1;
}
else {
tbdie("Bad data in argument: $runidx");
}
}
else {
tbdie("You must supply the -r option!");
}
# These are really linkname/vnode ... so we can find exact IP addr.
if (defined($options{"s"})) {
$srcvnode = $options{"s"};
my $tmp = $options{"s"};
if ($srcvnode =~ /^([-\w]+)$/) {
$srcvnode = $1;
if ($tmp =~ /^([-\w]+)\/([-\w]+)$/) {
$srclan = $1;
$srcvnode = $2;
}
else {
tbdie("Bad srcvnode name: $srcvnode!");
}
}
if (defined($options{"t"})) {
$dstvnode = $options{"s"};
my $tmp = $options{"t"};
if ($dstvnode =~ /^([-\w]+)$/) {
$dstvnode = $1;
if ($tmp =~ /^([-\w]+)\/([-\w]+)$/) {
$dstlan = $1;
$dstvnode = $2;
}
else {
tbdie("Bad dstvnode name: $dstvnode!");
......
......@@ -772,10 +772,12 @@ sub DelTempDB(@)
#
sub GraphDB(@)
{
my ($dbname, $which, $filename) = @_;
usage()
if (@_ < 2 || @_ > 3);
if (@_ < 2);
my $dbname = shift(@_);
my $which = shift(@_);
my @optargs = ();
#
# Untaint args.
......@@ -792,22 +794,22 @@ sub GraphDB(@)
else {
die("Bad data in which: $which");
}
# Check the rest of the args with a generic test.
foreach my $arg (@_) {
# Note different taint check (allow /).
if (defined($filename)) {
if ($filename =~ /^([-\w\.\/]+)$/) {
$filename = $1;
if ($arg =~ /^([-\w\.\/\:]+)$/) {
$arg = $1;
}
else {
tbdie("Bad data in filename: $filename");
}
tbdie("Bad data in argument: $arg");
}
else {
$filename = "";
push(@optargs, $arg);
}
print "Graphing DB '$dbname' from mysql database on $CONTROL.\n"
if ($debug);
my $retval = DoOpsStuff("graphdb $dbname $which $filename");
my $retval = DoOpsStuff("graphdb $dbname $which @optargs");
if ($retval) {
fatal("$OPSDBPROXY failed on $CONTROL!");
}
......
......@@ -555,10 +555,55 @@ sub SaveGraph($$)
sub GraphDB(@)
{
my ($dbname, $which, $filename) = @_;
usage()
if (@_ < 2);
my $dbname = shift(@_);
my $which = shift(@_);
my $filename;
my $start;
my $stop;
my $srcip;
my $dstip;
# Parse the rest of the options.
while (@_) {
my $arg = shift(@_);
if ($arg eq "-f") {
usage()
if (@_ == 0);
$filename = shift(@_);
}
elsif ($arg eq "-r") {
usage()
if (@_ == 0);
$arg = shift(@_);
if ($arg =~ /^(\d*):(\d*)$/) {
$start = $1;
if ($2) {
$stop = $2;
}
}
else {
usage();
}
}
elsif ($arg eq "-s") {
usage()
if (@_ < 2 || @_ > 3);
if (@_ == 0);
$srcip = shift(@_);
}
elsif ($arg eq "-t") {
usage()
if (@_ == 0);
$dstip = shift(@_);
}
else {
usage();
}
}
my $exists = DBExists($dbname);
return -1
......@@ -614,11 +659,49 @@ sub GraphDB(@)
if ($which eq "pps" || $which eq "bps") {
my $query_result;
my $timeclause;
my $ipclause;
my $whereclause = "";
if (defined($start) && defined($stop)) {
$timeclause = "(timestamp >= FROM_UNIXTIME('$start') and ".
"timestamp <= FROM_UNIXTIME('$stop')) ";
}
elsif (defined($start)) {
$timeclause = "(timestamp >= FROM_UNIXTIME('$start')) ";
}
elsif (defined($stop)) {
$timeclause = "(timestamp <= FROM_UNIXTIME('$stop')) ";
}
if (defined($srcip) && defined($dstip)) {
$ipclause = "(ip_src=INET_ATON('$srcip') ".
"and ip_dst=INET_ATON('$dstip'))";
}
elsif (defined($srcip)) {
$ipclause = "(ip_src=INET_ATON('$srcip'))";
}
elsif (defined($dstip)) {
$ipclause = "(ip_dst=INET_ATON('$dstip'))";
}
if (defined($timeclause) && defined($ipclause)) {
$whereclause = "where $timeclause and $ipclause ";
}
elsif (defined($timeclause)) {
$whereclause = "where $timeclause ";
}
elsif (defined($ipclause)) {
$whereclause = "where $ipclause ";
}
if ($which eq "pps") {
$query_result =
DBQueryFatal("select UNIX_TIMESTAMP(timestamp),count(*) ".
" from event ".
" from event as e ".
"left join iphdr as i on ".
" i.sid=e.sid and i.cid=e.cid ".
$whereclause . " " .
"group by timestamp order by timestamp");
}
else {
......@@ -627,8 +710,12 @@ sub GraphDB(@)
" from event as e ".
"left join iphdr as i on ".
" i.sid=e.sid and i.cid=e.cid ".
$whereclause . " " .
"group by timestamp order by timestamp");
}
return 0
if (! $query_result->numrows);
my ($tstart,$first) = $query_result->fetchrow_array();
@x_data = (0);
......
......@@ -34,3 +34,27 @@ function IframeDocument(id)
}
return oDoc;
}
function GraphChange_cb(html) {
grapharea = getObjbyName('grapharea');
if (grapharea) {
grapharea.innerHTML = html;
}
}
function GraphChange(which) {
var arg0 = "all";
var arg1 = "all";
var srcvnode = getObjbyName('trace_srcvnode');
if (srcvnode) {
arg0 = srcvnode.options[srcvnode.selectedIndex].value;
}
var dstvnode = getObjbyName('trace_dstvnode');
if (dstvnode) {
arg1 = dstvnode.options[dstvnode.selectedIndex].value;
}
x_GraphShow(which, arg0, arg1, GraphChange_cb);
return false;
}
......@@ -6,6 +6,9 @@
#
include("defs.php3");
include_once("template_defs.php");
require("Sajax.php");
sajax_init();
sajax_export("GraphShow");
#
# Only known and logged in users ...
......@@ -46,11 +49,6 @@ if (!TBvalid_integer($runidx)) {
PAGEARGERROR("Invalid characters in run ID!");
}
#
# Standard Testbed Header after argument checking.
#
PAGEHEADER("Experiment Run");
#
# Check to make sure this is a valid template and user has permission.
#
......@@ -72,6 +70,31 @@ if (! $instance->ValidRun($runidx)) {
USERERROR("The run $runidx is not a valid experiment run!", 1);
}
#
# For the Sajax Interface
#
function GraphShow($which, $arg0, $arg1)
{
global $template, $instance, $runidx;
ob_start();
$instance->ShowGraphArea($which, $runidx, $arg0, $arg1);
$html = ob_get_contents();
ob_end_clean();
return $html;
}
#
# See if this request is to the above function. Does not return
# if it is. Otherwise return and continue on.
#
sajax_handle_client_request();
#
# Standard Testbed Header after argument checking.
#
PAGEHEADER("Experiment Run");
echo "<font size=+2>Experiment Run<b> " .
MakeLink("instance",
"guid=$guid&version=$version&exptidx=$exptidx",
......@@ -79,9 +102,20 @@ echo "<font size=+2>Experiment Run<b> " .
"</b></font>\n";
echo "<br><br>\n";
$instance->ShowRun($runidx);
echo "<script type='text/javascript' language='javascript'>\n";
sajax_show_javascript();
echo "</script>\n";
#
# Throw up graph stuff.
#
echo "<center>\n";
echo "<br>";
$instance->ShowGraphArea("pps", $runidx);
echo "</center>\n";
#
# Standard Testbed Footer
#
......
......@@ -6,6 +6,9 @@
#
include("defs.php3");
include_once("template_defs.php");
require("Sajax.php");
sajax_init();
sajax_export("GraphShow");
#
# Only known and logged in users ...
......@@ -39,11 +42,6 @@ if (!TBvalid_integer($exptidx)) {
PAGEARGERROR("Invalid characters in instance ID!");
}
#
# Standard Testbed Header after argument checking.
#
PAGEHEADER("Template Instance");
#
# Check to make sure this is a valid template and user has permission.
#
......@@ -62,6 +60,31 @@ if (!$instance) {
"template $guid/$version!", 1);
}
#
# For the Sajax Interface
#
function GraphShow($which, $arg0, $arg1)
{
global $template, $instance;
ob_start();
$instance->ShowGraphArea($which, -1, $arg0, $arg1);
$html = ob_get_contents();
ob_end_clean();
return $html;
}
#
# See if this request is to the above function. Does not return
# if it is. Otherwise return and continue on.
#
sajax_handle_client_request();
#
# Standard Testbed Header after argument checking.
#
PAGEHEADER("Template Instance");
echo "<font size=+2>Template Instance <b>" .
MakeLink("template",
"guid=$guid&version=$version", "$guid/$version") .
......@@ -70,6 +93,18 @@ echo "<br><br>\n";
$instance->Show(1);
echo "<script type='text/javascript' language='javascript'>\n";
sajax_show_javascript();
echo "</script>\n";
#
# Throw up graph stuff.
#
echo "<center>\n";
echo "<br>";
$instance->ShowGraphArea("pps");
echo "</center>\n";
#
# Standard Testbed Footer
#
......
......@@ -31,12 +31,42 @@ if (!$instance) {
USERERROR("The instance $exptidx is not a valid instance!", 1);
}
# Optional runidx for graphing just a specific run.
$runarg = "";
$vnodes = "";
if (isset($runidx) && $runidx != "") {
if (!TBvalid_integer($runidx)) {
PAGEARGERROR("Invalid characters in run index!");
}
else {
$runarg = "-r $runidx";
}
}
# Optional src and dst arguments.
if (isset($srcvnode) && $srcvnode != "") {
if (! preg_match("/^[-\w\/]*$/", $srcvnode)) {
PAGEARGERROR("Invalid characters in src vnode!");
}
else {
$vnodes .= " -s " . escapeshellarg($srcvnode);
}
}
if (isset($dstvnode) && $dstvnode != "") {
if (! preg_match("/^[-\w\/]*$/", $dstvnode)) {
PAGEARGERROR("Invalid characters in dst vnode!");
}
else {
$vnodes .= " -t " . escapeshellarg($dstvnode);
}
}
#
# Spit out the image with a content header.
#
$eid = $instance->eid();
$pid = $instance->pid();
$runidx = $instance->runidx();
$guid = $instance->guid();
$vers = $instance->vers();
$which = "pps";
......@@ -57,7 +87,7 @@ if (!TBExptGroup($pid, $eid, $gid)) {
TBGroupUnixInfo($pid, $gid, $unix_gid, $unix_name);
if ($fp = popen("$TBSUEXEC_PATH $uid $unix_name webtemplate_linkgraph " .
"-i $exptidx -r $runidx $guid/$vers $which", "r")) {
"-i $exptidx $runarg $vnodes $guid/$vers $which", "r")) {
header("Content-type: image/gif");
fpassthru($fp);
}
......
......@@ -1161,8 +1161,14 @@ class TemplateInstance
if (!isset($stop))
$stop = "&nbsp";
echo "<center>\n";
echo "<table border=0 bgcolor=#000 color=#000 class=stealth ".
" cellpadding=0 cellspacing=0>\n";
echo "<tr valign=top>";
echo "<td class=stealth align=center>\n";
echo "<center>
<h3>Experiment Run</h3>
<h3>Details</h3>
</center>\n";
echo "<table align=center cellpadding=2 cellspacing=2 border=1>\n";
......@@ -1194,14 +1200,17 @@ class TemplateInstance
</tr>\n";
}
echo "</table>\n";
echo "</td>\n";
$query_result =
DBQueryFatal("select * from experiment_run_bindings ".
"where exptidx='$exptidx' and runidx='$runidx'");
if (mysql_num_rows($query_result)) {
echo "<td align=center class=stealth> &nbsp &nbsp &nbsp </td>\n";
echo "<td align=center class=stealth>\n";
echo "<center>
<h3>Experiment Run Bindings</h3>
<h3>Bindings</h3>
</center>
<table align=center border=1 cellpadding=5 cellspacing=2>\n";
......@@ -1223,7 +1232,10 @@ class TemplateInstance
</tr>\n";
}
echo "</table>\n";
echo "</td>\n";
}
echo "</tr>\n";
echo "</table>\n";
}
#
......@@ -1269,6 +1281,117 @@ class TemplateInstance
}
return 0;
}
#
# Show graph stuff, either for entire instance or for a run. Very hacky.
#
function ShowGraph($graphtype = "pps",
$runidx = -1, $src = "all", $dst = "all" ) {
$exptidx = $this->exptidx();
$runarg = ($runidx >= 0 ? "&runidx=$runidx" : "");
$srcarg = "";
$dstarg = "";
# Make the link unique to force reload on the client side.
$now = time();
$pid = $this->pid();
$eid = $this->eid();
#
# Lets check args!
#
if (! preg_match("/^[\w]*$/", $graphtype) ||
! preg_match("/^[-\d]*$/", $runidx) ||
! preg_match("/^[-\w\/]*$/", $src) ||
! preg_match("/^[-\w\/]*$/", $dst)) {
return "";
}
# Pass along the src/dst args to the graphing page.
if ($src != "" && $src != "all")
$srcarg = "&srcvnode=$src";
if ($dst != "" && $dst != "all")
$dstarg = "&dstvnode=$dst";
#
# Grab a list of vnode names so that user can select a specific
# source and destination.
#
$query_result =
DBQueryFatal("select vname,vnode from virt_lans ".
"where pid='$pid' and eid='$eid' and trace_db!=0");
$html = "";
$html .= "<div style='display: block; overflow: auto; ".
" position: relative; height: 450px; ".
" width: 90%; border: 2px solid black;'>\n";
$html .= " <div id='loading'><br>";
$html .= " <center>\n";
$html .= " <img id='busy' src='busy.gif'><span> Working ...</span>";
$html .= " </center>\n";
$html .= " </div>\n";
$html .= " <img border=0 ";
$html .= " onLoad=\"ClearLoadingIndicators('');\" ";
$html .= " src='linkgraph_image.php?exptidx=$exptidx";
$html .= "&graphtype=$graphtype&now=${now}${runarg}";
$html .= "${srcarg}${dstarg}'>\n";
$html .= "</div>\n";
$html .= "<button name=pps type=button value=1";
$html .= " onclick=\"GraphChange('pps');\">";
$html .= "Packets</button>\n";
$html .= "<button name=bps type=button value=1";
$html .= " onclick=\"GraphChange('bps');\">";
$html .= "Bytes</button>\n";
$html .= "&nbsp &nbsp &nbsp &nbsp ";
$html .= "<select id=trace_srcvnode>";
$html .= " <option value='all'>Source &nbsp</option>\n";
$html .= " <option value='all'>All &nbsp</option>\n";
while ($row = mysql_fetch_array($query_result)) {
$vname = $row["vname"];
$vnode = $row["vnode"];
$selected = "";
if ($src == "$vname/$vnode")
$selected = "selected";
$html .= " <option $selected value='$vname/$vnode'>";
$html .= "$vname-$vnode </option>\n";
}
$html .= "</select>";
mysql_data_seek($query_result, 0);
$html .= "&nbsp ";
$html .= "<select id=trace_dstvnode>";
$html .= " <option value='all'>Destination &nbsp</option>\n";
$html .= " <option value='all'>All &nbsp</option>\n";
while ($row = mysql_fetch_array($query_result)) {
$vname = $row["vname"];
$vnode = $row["vnode"];
$selected = "";
if ($dst == "$vname/$vnode")
$selected = "selected";
$html .= " <option $selected value='$vname/$vnode'>";
$html .= "$vname-$vnode </option>\n";
}
$html .= "</select>";
echo $html;
return 0;
}
function ShowGraphArea($graphtype = "pps",
$runidx = -1, $src = "all", $dst = "all") {
echo "<div align=center width=\"100%\" id=\"grapharea\">\n";
$this->ShowGraph($graphtype, $runidx, $src, $dst);
echo "</div>\n";
}
}
#
......
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