Commit f1a659b8 authored by Leigh Stoller's avatar Leigh Stoller

Improve cross referencing between geni-cm and emulab datbases.

Add a datetime form to the shownodehistory we page so that a testbed
admin can plug in a specific date, and find out what that node was
doing at the time. Changes in the backend (node_history script) to
support this. Note that the table is hard to seach for such a case,
and so need to let node_history do its thing and then port process the
records list. Unfortunately, the timestamps are unsigned ints, but
perl does not handle those properly, so had to pull in Math::BigInt to
deal with it.

On the output page, include a link to the genihistory page if a node
was part of a slice.

On the genihistory page, add a new argument, slice_uuid, to look for
the records for a specific slice.
parent 7669c092
#
#
#
use strict;
use libinstall;
sub InstallUpdate($$)
{
my ($version, $phase) = @_;
#
# Need to run this after the protogeni SQL update and install
#
if ($PGENISUPPORT && $phase eq "post") {
require GeniDB;
my $genidbnum = GeniDB::DBConnect(GeniDB::GENICM_DBNAME());
return 0
if (! $genidbnum || $genidbnum < 0);
my $query_result
= GeniDB::DBQueryWarn("select uuid,exptidx from geni_slices");
return -1
if (!$query_result);
while (my ($uuid,$exptidx) = $query_result->fetchrow_array()) {
DBQueryWarn("update experiment_stats set slice_uuid='$uuid' ".
"where exptidx='$exptidx'")
or return -1;
}
$query_result
= GeniDB::DBQueryWarn("select distinct slice_uuid ".
"from aggregate_history");
return -1
if (!$query_result);
while (my ($slice_uuid) = $query_result->fetchrow_array()) {
DBQueryWarn("update experiment_stats set slice_uuid='$slice_uuid' ".
"where eid_uuid='$slice_uuid'")
or return -1;
}
$query_result
= GeniDB::DBQueryWarn("select distinct slice_uuid ".
"from sliver_history");
return -1
if (!$query_result);
while (my ($slice_uuid) = $query_result->fetchrow_array()) {
DBQueryWarn("update experiment_stats set slice_uuid='$slice_uuid' ".
"where eid_uuid='$slice_uuid'")
or return -1;
}
}
return 0;
}
1;
# Local Variables:
# mode:perl
# End:
......@@ -255,6 +255,7 @@ CREATE TABLE `sliver_history` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`slice_uuid` varchar(40) NOT NULL default '',
`slice_hrn` varchar(256) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
......@@ -278,6 +279,7 @@ CREATE TABLE `aggregate_history` (
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`type` varchar(40) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`slice_uuid` varchar(40) NOT NULL default '',
`slice_hrn` varchar(256) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
......
......@@ -5601,7 +5601,10 @@ sub GeniExperiment($;$)
}
$experiment = Experiment->Lookup($uuid);
$experiment->SetState(EXPTSTATE_SWAPPED());
$experiment->Update({"geniflags" => $Experiment::EXPT_GENIFLAGS_EXPT});
$experiment->Update({"geniflags" => $Experiment::EXPT_GENIFLAGS_EXPT});
$experiment->TableUpdate("experiment_stats",
"geniflags='$Experiment::EXPT_GENIFLAGS_EXPT', ".
"slice_uuid='$uuid'");
# XXX watch for "placeholder" slices.
$experiment->MarkNonlocal($urn,
(defined($creator) ? $creator->urn() : undef),
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2009, 2010 University of Utah and the Flux Group.
# Copyright (c) 2009, 2010, 2012 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniUsage;
......@@ -39,6 +39,7 @@ sub NewSliver($$$$)
my $sliver_hrn = $sliver->hrn();
my $slice_uuid = $slice->uuid();
my $slice_hrn = $slice->hrn();
my $exptidx = $slice->exptidx();
my $owner_uuid = $owner->uuid();
my $owner_hrn = $owner->hrn();
my $resource_uuid = $sliver->resource_uuid();
......@@ -55,6 +56,8 @@ sub NewSliver($$$$)
push(@insert_data, "resource_uuid='$resource_uuid'");
push(@insert_data, "resource_type='$resource_type'");
push(@insert_data, "created=now()");
push(@insert_data, "exptidx=$exptidx")
if (defined($exptidx));
if (defined($sliver->component_uuid())) {
my $component = $sliver->GetComponent();
......@@ -122,6 +125,7 @@ sub NewAggregate($$$$)
my $aggregate_type = $aggregate->type();
my $slice_uuid = $slice->uuid();
my $slice_hrn = $slice->hrn();
my $exptidx = $slice->exptidx();
my $owner_uuid = $owner->uuid();
my $owner_hrn = $owner->hrn();
......@@ -135,6 +139,8 @@ sub NewAggregate($$$$)
push(@insert_data, "creator_uuid='$owner_uuid'");
push(@insert_data, "creator_hrn=" . DBQuoteSpecial($owner_hrn));
push(@insert_data, "created=now()");
push(@insert_data, "exptidx=$exptidx")
if (defined($exptidx));
# Insert into DB.
if (!DBQueryWarn("insert into aggregate_history set " .
......
#
# Add more cross referencing between geni and emulab DBs.
#
use strict;
use GeniDB;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
DBSetDefault($dbhandle);
if (!DBSlotExists("aggregate_history", "exptidx")) {
DBQueryFatal("ALTER TABLE aggregate_history ADD ".
" `exptidx` int(11) NOT NULL default '0' ".
"after type");
}
if (!DBSlotExists("sliver_history", "exptidx")) {
DBQueryFatal("ALTER TABLE sliver_history ADD ".
" `exptidx` int(11) NOT NULL default '0' ".
"after hrn");
}
return 0;
}
1;
# Local Variables:
# mode:perl
# End:
......@@ -938,6 +938,8 @@ CREATE TABLE `experiment_stats` (
`archive_idx` int(10) unsigned default NULL,
`last_error` int(10) unsigned default NULL,
`dpdbname` varchar(64) default NULL,
`geniflags` int(10) unsigned default NULL,
`slice_uuid` varchar(40) default NULL,
`nonlocal_id` varchar(128) default NULL,
`nonlocal_user_id` varchar(128) default NULL,
`nonlocal_type` tinytext,
......
#
# Add some geni state info to the experiment_stats table
#
use strict;
use libdb;
use EmulabConstants;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("experiment_stats", "geniflags")) {
DBQueryFatal("ALTER TABLE experiment_stats ADD ".
" `geniflags` int(10) unsigned default NULL ".
" after dpdbname");
}
if (!DBSlotExists("experiment_stats", "slice_idx")) {
DBQueryFatal("ALTER TABLE experiment_stats ADD ".
" `slice_uuid` varchar(40) default NULL ".
" after geniflags");
}
return 0;
}
# Local Variables:
# mode:perl
# End:
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# Copyright (c) 2005-2012 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Date::Parse;
use Time::Local;
use Math::BigInt;
#
# Drill down the node history data in the DB
......@@ -48,7 +51,7 @@ sub usage {
exit(1);
}
my $optlist = "ARS:aln:rswv";
my $optlist = "ARS:aln:rswvd:";
my $warnme = 0;
my $verbose = 0;
my $showall = 0;
......@@ -57,6 +60,7 @@ my $list = 0;
my $summary = 0;
my $raw = 0;
my $numrecs = 0;
my $datetime;
#
# Sort stuff. sortby value should correspond to record field format:
......@@ -131,6 +135,10 @@ if (defined($options{"r"})) {
if (defined($options{"s"})) {
$summary = 1;
}
if (defined($options{"d"})) {
$datetime = timelocal(strptime($options{"d"}));
$summary = 0;
}
if (defined($options{"w"})) {
$warnme = 1;
}
......@@ -159,7 +167,7 @@ if (@nodes == 1) {
my $orderby = " ORDER BY stamp ASC";
my $query_result =
DBQueryFatal("SELECT node_id,stamp,op,uid,pid,eid ".
DBQueryFatal("SELECT node_id,stamp,op,uid,pid,eid,experiment_stats.exptidx ".
"FROM node_history,experiment_stats ".
"WHERE node_history.exptidx=experiment_stats.exptidx ".
"$querymod $orderby");
......@@ -169,6 +177,7 @@ my @records;
while (my %row = $query_result->fetchhash()) {
my $pideid = "$row{pid}/$row{eid}";
my $exptidx = $row{"exptidx"};
my $node = $row{node_id};
my $stamp = $row{stamp};
my $uid = $row{uid};
......@@ -178,10 +187,10 @@ while (my %row = $query_result->fetchhash()) {
# from the epoch til now.
#
if (!defined($nodeinfo{$node})) {
$nodeinfo{$node} = [ "", $epoch, "root" ];
$nodeinfo{$node} = [ "", undef, $epoch, "root" ];
}
my ($opideid, $ostamp, $ouid) = @{$nodeinfo{$node}};
my ($opideid, $oidx, $ostamp, $ouid) = @{$nodeinfo{$node}};
my $elapsed = $stamp - $ostamp;
#
......@@ -194,7 +203,7 @@ while (my %row = $query_result->fetchhash()) {
if ($warnme);
# XXX possibly missing state in the DB, treat as move
}
$nodeinfo{$node} = [ $pideid, $stamp, $uid ];
$nodeinfo{$node} = [ $pideid, $exptidx, $stamp, $uid ];
}
#
......@@ -205,30 +214,30 @@ while (my %row = $query_result->fetchhash()) {
print STDERR "$node: mismatched alloc,free records: $opideid,$pideid\n"
if ($warnme);
}
$nodeinfo{$node} = [ "", $stamp, $uid ];
$nodeinfo{$node} = [ "", undef, $stamp, $uid ];
}
elsif ($row{op} eq "move") {
if (!$raw) {
# Moves from reloadpending to reloading are combined as reloading
if ($opideid eq "emulab-ops/reloadpending" &&
$pideid eq "emulab-ops/reloading") {
$nodeinfo{$node} = [ $pideid, $ostamp, $ouid ];
$nodeinfo{$node} = [ $pideid, $exptidx, $ostamp, $ouid ];
next;
}
}
$nodeinfo{$node} = [ $pideid, $stamp, $uid ];
$nodeinfo{$node} = [ $pideid, $exptidx, $stamp, $uid ];
}
# save off the record
push(@records, [ $node, $opideid, $ouid, $ostamp, $elapsed ]);
push(@records, [ $node, $opideid, $oidx, $ouid, $ostamp, $elapsed ]);
}
# Include the current state of nodes in a final record
my $stamp = time();
for $node (keys(%nodeinfo)) {
my ($opideid, $ostamp, $ouid) = @{$nodeinfo{$node}};
my ($opideid, $oidx, $ostamp, $ouid) = @{$nodeinfo{$node}};
my $elapsed = $stamp - $ostamp;
push(@records, [ $node, $opideid, $ouid, $ostamp, $elapsed ]);
push(@records, [ $node, $opideid, $oidx, $ouid, $ostamp, $elapsed ]);
}
# Prune the list based on date range (someday)
......@@ -255,7 +264,7 @@ if ($numrecs && $numrecs < $#records) {
# and printing (if desired).
#
for my $rec (@records) {
my ($node, $pideid, $uid, $stamp, $elapsed) = @{$rec};
my ($node, $pideid, $exptidx, $uid, $stamp, $elapsed) = @{$rec};
if (!defined($nodestats{$node})) {
$nodestats{$node} = [ 0, 0, 0, 0 ];
......@@ -282,23 +291,58 @@ for my $rec (@records) {
my $end = ctime($stamp + $elapsed);
chomp($end);
print "$node: $pideid from $start til $end ($elapsed sec)\n"
if ($datetime) {
my $d = Math::BigInt->new($datetime);
my $s = Math::BigInt->new($stamp);
my $e = Math::BigInt->new($elapsed);
$e->badd($s);
my $c1 = $s->bcmp($d);
my $c2 = $e->bcmp($d);
next
if ($c1 < 0 && $c2 <= 0);
if ($c1 <= 0 && $c2 > 0) {
print "$node: $pideid($exptidx) from $start til $end ".
"($elapsed sec)\n"
if ($isalloced);
last;
}
}
print "$node: $pideid($exptidx) from $start til $end ($elapsed sec)\n"
if (!$showalloconly || $isalloced);
} else {
my ($pid, $eid);
if ($pideid eq "") {
$pid = $eid = "<FREE>";
$exptidx = 0;
} else {
($pid, $eid) = split("/", $pideid);
}
print "$node REC $stamp $elapsed $uid $pid $eid\n"
if ($datetime) {
my $d = Math::BigInt->new($datetime);
my $s = Math::BigInt->new($stamp);
my $e = Math::BigInt->new($elapsed);
$e->badd($s);
my $c1 = $s->bcmp($d);
my $c2 = $e->bcmp($d);
next
if ($c1 < 0 && $c2 <= 0);
if ($c1 <= 0 && $c2 > 0) {
print "$node REC $stamp $elapsed $uid $pid $eid $exptidx\n";
last;
}
}
print "$node REC $stamp $elapsed $uid $pid $eid $exptidx\n"
if (!$showalloconly || $isalloced);
}
}
}
print scalar(@records) . " records\n"
if ($list && $verbose);
if (0 && $list && $verbose);
#
# Print out summary information
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006-2011 University of Utah and the Flux Group.
# Copyright (c) 2006-2012 University of Utah and the Flux Group.
# All rights reserved.
#
#
......@@ -1306,6 +1306,7 @@ class ExperimentStats
function pid_idx() { return $this->field('pid_idx'); }
function gid_idx() { return $this->field('gid_idx'); }
function archive_idx() { return $this->field('archive_idx'); }
function slice_uuid() { return $this->field('slice_uuid'); }
function Project() {
return Project::Lookup($this->pid_idx());
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
......@@ -21,6 +21,7 @@ $isadmin = ISADMIN();
# Verify Page Arguments.
#
$optargs = OptionalPageArguments("showtype", PAGEARG_STRING,
"slice_uuid", PAGEARG_STRING,
"index", PAGEARG_INTEGER);
$showtypes = array();
......@@ -51,8 +52,17 @@ if (! $isadmin) {
if (isset($showtypes["aggregates"])) {
$myindex = $index;
$dblink = GetDBLink("cm");
$clause = ($myindex ? "and idx<$myindex " : "");
$clause = "";
if ($myindex) {
$clause = "and idx<$myindex ";
}
elseif (isset($slice_uuid)) {
if (!preg_match("/^\w+\-\w+\-\w+\-\w+\-\w+$/", $slice_uuid)) {
USERERROR("Invalid slice uuid", 1);
}
$clause = "and slice_uuid='$slice_uuid' ";
}
$query_result =
DBQueryFatal("select * from aggregate_history ".
"where `type`='Aggregate' $clause ".
......@@ -127,8 +137,17 @@ if (isset($showtypes["aggregates"])) {
if (isset($showtypes["tickets"])) {
$myindex = $index;
$dblink = GetDBLink("cm");
$clause = ($myindex ? "where idx<$myindex " : "");
$clause = "";
if ($myindex) {
$clause = "where idx<$myindex ";
}
elseif (isset($slice_uuid)) {
if (!preg_match("/^\w+\-\w+\-\w+\-\w+\-\w+$/", $slice_uuid)) {
USERERROR("Invalid slice uuid", 1);
}
$clause = "where slice_uuid='$slice_uuid' ";
}
$query_result =
DBQueryFatal("select * from ticket_history ".
"$clause ".
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006-2011 University of Utah and the Flux Group.
# Copyright (c) 2006-2012 University of Utah and the Flux Group.
# All rights reserved.
#
include_once("osinfo_defs.php");
......@@ -1308,8 +1308,9 @@ class Node
# Show history.
#
function ShowNodeHistory($node = null,
$showall = 0, $count = 20, $reverse = 1) {
$showall = 0, $count = 20, $reverse = 1, $date = null) {
global $TBSUEXEC_PATH;
global $PROTOGENI;
$atime = 0;
$ftime = 0;
$rtime = 0;
......@@ -1334,6 +1335,9 @@ function ShowNodeHistory($node = null,
if ($count) {
$opt .= " -n $count";
}
if ($date) {
$opt = " -d " . escapeshellarg($date);
}
if ($fp = popen("$TBSUEXEC_PATH nobody nobody ".
" webnode_history $opt $node_id", "r")) {
if (!$showall) {
......@@ -1358,8 +1362,11 @@ function ShowNodeHistory($node = null,
echo "<tr>
$nodestr
<th>Pid</th>
<th>Eid</th>
<th>Allocated By</th>
<th>Eid</th>";
if ($PROTOGENI) {
echo "<th>Slice</th>";
}
echo " <th>Allocated By</th>
<th>Allocation Date</th>
<th>Duration</th>
</tr>\n";
......@@ -1400,27 +1407,46 @@ function ShowNodeHistory($node = null,
$durstr = sprintf("%s%ds", $durstr, $duration);
$uid = $results[4];
$pid = $results[5];
$slice = "--";
if ($pid == "FREE") {
$pid = "--";
$eid = "--";
$uid = "--";
} else {
$eid = $results[6];
if ($results[7]) {
$experiment_stats = ExperimentStats::Lookup($results[7]);
if ($experiment_stats &&
$experiment_stats->slice_uuid()) {
$url = CreateURL("genihistory",
"slice_uuid",
$experiment_stats->slice_uuid());
$slice = "<a href='$url'>" .
"<img src=\"greenball.gif\" border=0></a>";
}
}
}
if ($node_id == "") {
echo "<tr>
<td>$nodeid</td>
<td>$pid</td>
<td>$eid</td>
<td>$uid</td>
<td>$eid</td>";
if ($PROTOGENI) {
echo "<td>$slice</td>";
}
echo "<td>$uid</td>
<td>$datestr</td>
<td>$durstr</td>
</tr>\n";
} else {
echo "<tr>
<td>$pid</td>
<td>$eid</td>
<td>$uid</td>
<td>$eid</td>";
if ($PROTOGENI) {
echo "<td>$slice</td>";
}
echo "<td>$uid</td>
<td>$datestr</td>
<td>$durstr</td>
</tr>\n";
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
......@@ -14,7 +14,7 @@ $this_user = CheckLoginOrDie();
$uid = $this_user->uid();
$isadmin = ISADMIN();
if (! ($isadmin || OPSGUY())) {
if (! ($isadmin || OPSGUY() || STUDLY())) {
USERERROR("Cannot view node history.", 1);
}
......@@ -24,6 +24,7 @@ if (! ($isadmin || OPSGUY())) {
$optargs = OptionalPageArguments("showall", PAGEARG_BOOLEAN,
"reverse", PAGEARG_BOOLEAN,
"count", PAGEARG_INTEGER,
"datetime", PAGEARG_STRING,
"node", PAGEARG_NODE);
#
......@@ -40,6 +41,9 @@ if (!isset($count)) {
if (!isset($reverse)) {
$reverse = 1;
}
if (!isset($datetime)) {
$datetime = "";
}
$node_id = (isset($node) ? $node->node_id() : "");
$opts="node_id=$node_id&count=$count&reverse=$reverse";
......@@ -80,7 +84,35 @@ if ($count != 0) {
echo "all";
}
ShowNodeHistory((isset($node) ? $node : null), $showall, $count, $reverse);
#
# Spit out a date form.
#
if ($datetime == "") {
$datetime = "mm/dd/yy HH:MM";
}
if ($node_id != "") {
echo "<br>";
echo "<form action=shownodehistory.php3?$opts method=post>
<b>Show Datetime:</b>
<input type=text
name=datetime
size=20
value=\"$datetime\">
<b><input type=submit name=search value=Search></b>\n";
echo "</form><br><br>\n";
}
if ($node_id != "" && $datetime != "" && $datetime != "mm/dd/yy HH:MM") {
if (strtotime($datetime)) {
ShowNodeHistory($node, 1, 1, 0, $datetime);
}
else {
USERERROR("Invalid date specified", 1);
}
}
else {
ShowNodeHistory((isset($node) ? $node : null), $showall, $count, $reverse);
}
#
# Standard Testbed Footer
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006-2010 University of Utah and the Flux Group.
# Copyright (c) 2006-2012 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -114,6 +114,7 @@ $url_mapping["cvswebwrap"] = "cvsweb/cvswebwrap.php3";
$url_mapping["profile"] = "profile.php";
$url_mapping["submitpub"] = "submitpub.php";
$url_mapping["showslice"] = "showslice.php";
$url_mapping["genihistory"] = "genihistory.php";
$url_mapping["showmanifest"] = "showmanifest.php";
#
......
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