Commit a382994d authored by Leigh B. Stoller's avatar Leigh B. Stoller

Split the experiment stats table into two parts. The first is the

per-experiment instantiation with aggregate data like the number of
swapins, the dates and the like. The other part is the per
swapin/modify stats. These are number of pnodes, links, lans,
etc. Long term, I think we want more precise swapin stats, and with
experiment modify in the mix, we need to have multiple stat records
per experiment, but do not need to duplicate all the stuff in the
other table just mentioned.

To reduce the amount the table size, we cross reference the tables by
index only instead of with pid,eid and the like. We use exptidx to
link experiments, experiment_stats, and the new experiment_resources
table. experiment_resources and stats are linked by another index in
the resources table, which indicates which is the current resource
row. On a modify, a new resource record is created, and the stats
record updated to point to the new (latest) resource record.

Web Changes: Improve showstats and showexpstats. Make them user
accessible so that mere users can see stats for themselves and for
their projects. No ability for mere users (PIs) to look at another
person's stats. Generally, these two pages need more work, but now
they are more useful. I added Show Stats to the user info and project
info pages to display per-usr/proj stats. Add more info in the
showstats display, but the showexpstats display is still not pretty
printed; just the raw tables.

Rename a few fields, add some indexes, and otherwise make some minor
changes that are sure to annoy everyone.
parent eebecbf6
......@@ -98,7 +98,7 @@ use Exporter;
TBDB_STATS_PRELOAD TBDB_STATS_START TBDB_STATS_TERMINATE
TBDB_STATS_SWAPIN TBDB_STATS_SWAPOUT TBDB_STATS_SWAPMODIFY
TBDB_STATS_FLAGS_IDLESWAP
TBDB_STATS_FLAGS_IDLESWAP TBDB_STATS_FLAGS_PREMODIFY
TBDB_EXPT_WORKDIR
TBSetNodeEventState TBGetNodeEventState
......@@ -158,6 +158,7 @@ my $DBNAME = "@TBDBNAME@";
my $TBOPS = "@TBOPSEMAIL@";
my $EVENTSYS = "@EVENTSYS@";
my $BOSSNODE = "@BOSSNODE@";
my $TESTMODE = @TESTMODE@;
my $TBOPSPID = "emulab-ops";
my $SCRIPTNAME = "Unknown";
......@@ -453,8 +454,9 @@ sub TBDB_STATS_START() { "start"; }
sub TBDB_STATS_TERMINATE() { "destroy"; }
sub TBDB_STATS_SWAPIN() { "swapin"; }
sub TBDB_STATS_SWAPOUT() { "swapout"; }
sub TBDB_STATS_SWAPMODIFY() { "swapmodify"; }
sub TBDB_STATS_SWAPMODIFY() { "swapmod"; }
sub TBDB_STATS_FLAGS_IDLESWAP() { 0x01; }
sub TBDB_STATS_FLAGS_PREMODIFY(){ 0x02; }
#
# Auth stuff.
......@@ -3129,12 +3131,14 @@ sub GatherSwapStats($$$$$;$)
local $DBQUERY_MAXTRIES = 5;
my $query_result =
DBQueryWarn("select gid,idx from experiments ".
"where pid='$pid' and eid='$eid'");
DBQueryWarn("select e.gid,e.idx,s.rsrcidx,s.lastrsrc ".
" from experiments as e ".
"left join experiment_stats as s on e.idx=s.exptidx ".
"where e.pid='$pid' and e.eid='$eid'");
if (!$query_result || !$query_result->numrows) {
return;
}
my ($gid,$idx) = $query_result->fetchrow_array;
my ($gid,$exptidx,$rsrcidx,$lastrsrc) = $query_result->fetchrow_array;
#
# A non-zero ecode indicates error. If op is a preload/swapin/start/modify
......@@ -3146,12 +3150,28 @@ sub GatherSwapStats($$$$$;$)
DBQueryWarn("update experiment_stats set ".
" swap_errors=swap_errors+1, ".
" swap_exitcode=$ecode ".
"where pid='$pid' and eid='$eid' and idx=$idx");
"where pid='$pid' and eid='$eid' and exptidx=$exptidx");
if ($mode eq TBDB_STATS_SWAPIN ||
$mode eq TBDB_STATS_START ||
$mode eq TBDB_STATS_PRELOAD ||
$mode eq TBDB_STATS_SWAPMODIFY) {
$mode eq TBDB_STATS_PRELOAD) {
goto logit;
}
#
# If a modify failed, we need to revert back to the old
# stats record since the current one is bogus.
#
if ($mode eq TBDB_STATS_SWAPMODIFY) {
if (defined($lastrsrc)) {
DBQueryWarn("update experiment_stats set ".
" rsrcidx=$lastrsrc,lastrsrc=NULL ".
"where pid='$pid' and eid='$eid' and ".
" exptidx=$exptidx");
DBQueryWarn("delete from experiment_resources ".
"where idx=$rsrcidx");
$rsrcidx = $lastrsrc;
}
goto logit;
}
}
......@@ -3162,7 +3182,31 @@ sub GatherSwapStats($$$$$;$)
if ($mode eq TBDB_STATS_TERMINATE) {
DBQueryWarn("update experiment_stats ".
"set destroyed=now() ".
"where pid='$pid' and eid='$eid' and idx=$idx");
"where pid='$pid' and eid='$eid' and exptidx=$exptidx");
}
#
# Preswap. Need to generate a new resource record.
#
if ($mode eq TBDB_STATS_SWAPMODIFY &&
$flags & TBDB_STATS_FLAGS_PREMODIFY) {
$query_result =
DBQueryWarn("insert into experiment_resources ".
" (idx, tstamp, exptidx) ".
"values (0, now(), $exptidx)");
if (! $query_result ||
! $query_result->insertid) {
print STDERR
"*** WARNING $0:\n".
" Failed to insert a new resource record for $pid/$eid\n";
}
$lastrsrc = $rsrcidx;
$rsrcidx = $query_result->insertid;
DBQueryWarn("update experiment_stats set ".
" rsrcidx=$rsrcidx,lastrsrc=$lastrsrc ".
"where pid='$pid' and eid='$eid' and ".
" exptidx=$exptidx");
return;
}
#
......@@ -3175,11 +3219,13 @@ sub GatherSwapStats($$$$$;$)
if ($mode eq TBDB_STATS_SWAPOUT) {
$query_result =
DBQueryWarn("select pnodes,vnodes, ".
DBQueryWarn("select r.pnodes,r.vnodes, ".
" UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(swapin_last) ".
" from experiment_stats ".
"where pid='$pid' and eid='$eid' and idx=$idx");
" UNIX_TIMESTAMP(s.swapin_last) ".
" from experiment_stats as s ".
"left join experiment_resources as r on ".
" r.idx=s.rsrcidx ".
"where s.exptidx=$exptidx");
if ($query_result && $query_result->numrows) {
($pnodes,$vnodes,$duration) = $query_result->fetchrow_array;
......@@ -3194,7 +3240,8 @@ sub GatherSwapStats($$$$$;$)
if ($flags & TBDB_STATS_FLAGS_IDLESWAP) {
DBQueryWarn("update experiment_stats ".
"set idle_swaps=idle_swaps+1 ".
"where pid='$pid' and eid='$eid' and idx=$idx");
"where pid='$pid' and eid='$eid' and ".
" exptidx=$exptidx");
}
}
......@@ -3216,7 +3263,7 @@ sub GatherSwapStats($$$$$;$)
" allexpt_vnode_duration+($vnodes * ${duration}), ".
" allexpt_pnode_duration=".
" allexpt_pnode_duration+($pnodes * ${duration}) ".
"where pid='$pid'");
"where pid='$pid'");
DBQueryWarn("update group_stats ".
"set expt${mode}_count=expt${mode}_count+1, ".
" expt${mode}_last=now(), ".
......@@ -3257,7 +3304,8 @@ sub GatherSwapStats($$$$$;$)
"set ${tmp}_count=${tmp}_count+1, ".
" ${tmp}_last=now(), ".
" swapin_duration=swapin_duration+${duration} ".
"where pid='$pid' and eid='$eid' and idx=$idx");
"where pid='$pid' and eid='$eid' and ".
" exptidx=$exptidx");
}
}
......@@ -3280,8 +3328,8 @@ sub GatherSwapStats($$$$$;$)
if ($query_result) {
my $pnodes = $query_result->numrows;
DBQueryWarn("update experiment_stats set pnodes=$pnodes ".
"where pid='$pid' and eid='$eid' and idx=$idx");
DBQueryWarn("update experiment_resources set pnodes=$pnodes ".
"where idx=$rsrcidx");
}
}
......@@ -3298,7 +3346,7 @@ sub GatherSwapStats($$$$$;$)
logit:
DBQueryWarn("insert into testbed_stats ".
"(idx, tstamp, exptidx, action, exitcode) ".
"values (0, now(), $idx, '$mode', $ecode)");
"values (0, now(), $exptidx, '$mode', $ecode)");
}
#
......@@ -3316,25 +3364,32 @@ sub GatherAssignStats($$%)
local $DBQUERY_MAXTRIES = 5;
#
# Need the exptidx for the insert.
#
my $result =
DBQueryFatal("select idx from experiments ".
"where pid='$pid' and eid='$eid'");
my $query_result =
DBQueryWarn("select e.gid,e.idx,s.rsrcidx from experiments as e ".
"left join experiment_stats as s on e.idx=s.exptidx ".
"where e.pid='$pid' and e.eid='$eid'");
if (!$query_result || !$query_result->numrows) {
return;
}
my ($gid,$exptidx,$rsrcidx) = $query_result->fetchrow_array;
my ($idx) = $result->fetchrow_array;
if (defined($idx) && $idx) {
foreach my $key (keys(%stats)) {
$val = $stats{$key};
# experiment records not inserted in testmode, but I use testmode
# at home when doing development too.
if (!defined($rsrcidx)) {
return
if ($TESTMODE);
die("*** $0:\n".
" No stat record for record for $pid/$eid\n");
}
foreach my $key (keys(%stats)) {
$val = $stats{$key};
push (@updates, "$key=$val");
}
DBQueryFatal("update experiment_stats ".
"set " . join(",", @updates) . " ".
"where pid='$pid' and eid='$eid' and idx=$idx");
push (@updates, "$key=$val");
}
DBQueryFatal("update experiment_resources ".
"set " . join(",", @updates) . " ".
"where idx=$rsrcidx");
}
# _Always_ make sure that this 1 is at the end of the file...
......
......@@ -165,6 +165,33 @@ CREATE TABLE eventlist (
KEY vnode (vnode)
) TYPE=MyISAM;
--
-- Table structure for table 'experiment_stats'
--
CREATE TABLE experiment_resources (
idx int(10) unsigned NOT NULL auto_increment,
exptidx int(10) unsigned NOT NULL default '0',
tstamp datetime default NULL,
vnodes smallint(5) unsigned default '0',
pnodes smallint(5) unsigned default '0',
wanodes smallint(5) unsigned default '0',
simnodes smallint(5) unsigned default '0',
jailnodes smallint(5) unsigned default '0',
delaynodes smallint(5) unsigned default '0',
linkdelays smallint(5) unsigned default '0',
walinks smallint(5) unsigned default '0',
links smallint(5) unsigned default '0',
lans smallint(5) unsigned default '0',
shapedlinks smallint(5) unsigned default '0',
shapedlans smallint(5) unsigned default '0',
minlinks tinyint(3) unsigned default '0',
maxlinks tinyint(3) unsigned default '0',
PRIMARY KEY (idx),
KEY exptidx (exptidx)
) TYPE=MyISAM;
--
-- Table structure for table 'experiment_stats'
--
......@@ -173,7 +200,9 @@ CREATE TABLE experiment_stats (
pid varchar(12) NOT NULL default '',
eid varchar(32) NOT NULL default '',
creator varchar(8) NOT NULL default '',
idx int(10) unsigned NOT NULL default '0',
exptidx int(10) unsigned NOT NULL default '0',
rsrcidx int(10) unsigned NOT NULL default '0',
lastrsrc int(10) unsigned default NULL,
gid varchar(16) NOT NULL default '',
created datetime default NULL,
destroyed datetime default NULL,
......@@ -181,8 +210,8 @@ CREATE TABLE experiment_stats (
swapin_last datetime default NULL,
swapout_count smallint(5) unsigned default '0',
swapout_last datetime default NULL,
swapmodify_count smallint(5) unsigned default '0',
swapmodify_last datetime default NULL,
swapmod_count smallint(5) unsigned default '0',
swapmod_last datetime default NULL,
swap_errors smallint(5) unsigned default '0',
swap_exitcode tinyint(3) unsigned default '0',
idle_swaps smallint(5) unsigned default '0',
......@@ -202,8 +231,9 @@ CREATE TABLE experiment_stats (
minlinks tinyint(3) unsigned default '0',
maxlinks tinyint(3) unsigned default '0',
batch tinyint(3) unsigned default '0',
PRIMARY KEY (eid,pid,idx),
KEY idx (idx)
PRIMARY KEY (eid,pid,exptidx),
KEY exptidx (exptidx),
KEY rsrcidx (rsrcidx)
) TYPE=MyISAM;
--
......@@ -317,8 +347,8 @@ CREATE TABLE group_stats (
exptswapin_last datetime default NULL,
exptswapout_count int(11) unsigned default '0',
exptswapout_last datetime default NULL,
exptswapmodify_count int(11) unsigned default '0',
exptswapmodify_last datetime default NULL,
exptswapmod_count int(11) unsigned default '0',
exptswapmod_last datetime default NULL,
allexpt_duration int(11) unsigned default '0',
allexpt_vnodes int(11) unsigned default '0',
allexpt_vnode_duration int(11) unsigned default '0',
......@@ -941,8 +971,8 @@ CREATE TABLE project_stats (
exptswapin_last datetime default NULL,
exptswapout_count int(11) unsigned default '0',
exptswapout_last datetime default NULL,
exptswapmodify_count int(11) unsigned default '0',
exptswapmodify_last datetime default NULL,
exptswapmod_count int(11) unsigned default '0',
exptswapmod_last datetime default NULL,
allexpt_duration int(11) unsigned default '0',
allexpt_vnodes int(11) unsigned default '0',
allexpt_vnode_duration int(11) unsigned default '0',
......@@ -1233,8 +1263,8 @@ CREATE TABLE user_stats (
exptswapin_last datetime default NULL,
exptswapout_count int(11) unsigned default '0',
exptswapout_last datetime default NULL,
exptswapmodify_count int(11) unsigned default '0',
exptswapmodify_last datetime default NULL,
exptswapmod_count int(11) unsigned default '0',
exptswapmod_last datetime default NULL,
allexpt_duration int(11) unsigned default '0',
allexpt_vnodes int(11) unsigned default '0',
allexpt_vnode_duration int(11) unsigned default '0',
......
......@@ -402,7 +402,6 @@ REPLACE INTO state_triggers VALUES ('*','ALWAYSUP','SHUTDOWN','ISUP');
REPLACE INTO testsuite_preentables VALUES ('comments','drop');
REPLACE INTO testsuite_preentables VALUES ('iface_counters','drop');
REPLACE INTO testsuite_preentables VALUES ('lastlogin','drop');
REPLACE INTO testsuite_preentables VALUES ('login','drop');
REPLACE INTO testsuite_preentables VALUES ('loginmessage','drop');
REPLACE INTO testsuite_preentables VALUES ('node_idlestats','drop');
......@@ -432,6 +431,7 @@ REPLACE INTO testsuite_preentables VALUES ('group_stats','clean');
REPLACE INTO testsuite_preentables VALUES ('project_stats','clean');
REPLACE INTO testsuite_preentables VALUES ('user_stats','clean');
REPLACE INTO testsuite_preentables VALUES ('experiment_stats','clean');
REPLACE INTO testsuite_preentables VALUES ('experiment_resources','clean');
REPLACE INTO testsuite_preentables VALUES ('testbed_stats','clean');
--
......
......@@ -423,3 +423,96 @@ last_net_act,last_cpu_act,last_ext_act);
alter table os_info add column max_concurrent int(11) default NULL;
alter table images drop column max_concurrent;
1.143: Split the experiment stats table into two parts. The first is
the per-experiment instantiation with aggregate data like the
number of swapins, the dates and the like. The other part is
the per swapin/modify stats. These are number of pnodes, links,
lans, etc. Long term, I think we want more precise swapin
stats, and with experiment modify in the mix, we need to have
multiple stat records per experiment, but do not need to
duplicate all the stuff in the other table just mentioned.
To reduce the amount the table size, we cross reference the
tables by index only instead of with pid,eid and the like. We use
exptidx to link experiments, experiment_stats, and the new
experiment_resources table. experiment_resources and stats are
linked by another index in the resources table, which indicates
which is the current resource row. On a modify, a new resource
record is created, and the stats record updated to point to the
new (latest) resource record.
DROP TABLE IF EXISTS experiment_resources;
CREATE TABLE experiment_resources (
idx int(10) unsigned NOT NULL auto_increment,
exptidx int(10) unsigned NOT NULL default '0',
tstamp datetime default NULL,
vnodes smallint(5) unsigned default '0',
pnodes smallint(5) unsigned default '0',
wanodes smallint(5) unsigned default '0',
simnodes smallint(5) unsigned default '0',
jailnodes smallint(5) unsigned default '0',
delaynodes smallint(5) unsigned default '0',
linkdelays smallint(5) unsigned default '0',
walinks smallint(5) unsigned default '0',
links smallint(5) unsigned default '0',
lans smallint(5) unsigned default '0',
shapedlinks smallint(5) unsigned default '0',
shapedlans smallint(5) unsigned default '0',
minlinks tinyint(3) unsigned default '0',
maxlinks tinyint(3) unsigned default '0',
PRIMARY KEY (idx),
KEY exptidx (exptidx)
) TYPE=MyISAM;
Be clear about what index is what:
alter table experiment_stats change idx exptidx
int(10) unsigned NOT NULL default '0';
alter table experiment_stats drop index idx;
alter table experiment_stats add index(exptidx);
alter table experiment_stats add rsrcidx
int(10) unsigned NOT NULL default '0' after exptidx;
alter table experiment_stats add index(rsrcidx);
alter table experiment_stats add lastrsrc
int(10) unsigned default NULL after rsrcidx;
Change a few names cause I picked bad ones initially:
alter table experiment_stats change swapmodify_count swapmod_count
smallint(5) unsigned default '0';
alter table experiment_stats change swapmodify_last swapmod_last
datetime default NULL;
alter table group_stats change exptswapmodify_count exptswapmod_count
int(11) unsigned default '0';
alter table group_stats change exptswapmodify_last exptswapmod_last
datetime default NULL;
alter table project_stats change exptswapmodify_count exptswapmod_count
int(11) unsigned default '0';
alter table project_stats change exptswapmodify_last exptswapmod_last
datetime default NULL;
alter table user_stats change exptswapmodify_count exptswapmod_count
int(11) unsigned default '0';
alter table user_stats change exptswapmodify_last exptswapmod_last
datetime default NULL;
To populate the new table from the old table:
insert into experiment_resources (idx, exptidx, tstamp, vnodes,
pnodes, wanodes, simnodes, jailnodes, delaynodes,
linkdelays, walinks, links, lans, shapedlinks,
shapedlans, minlinks, maxlinks)
select 0, exptidx, created, vnodes, pnodes, wanodes,
simnodes, jailnodes, delaynodes, linkdelays, walinks,
links, lans, shapedlinks, shapedlans, minlinks,
maxlinks from experiment_stats order by exptidx;
Now we have to insert the newly created resource idx into the
stats table to link them up.
my $query_result =
DBQueryFatal("select idx,exptidx from experiment_resources");
while (($idx,$exptidx) = $query_result->fetchrow_array()) {
DBQueryFatal("update experiment_stats set rsrcidx=$idx ".
"where exptidx=$exptidx");
}
......@@ -116,7 +116,7 @@ if (! TBProjAccessCheck($dbuid, $pid, $gid, TB_PROJECT_CREATEEXPT)) {
# Create an experiment record. The pid/eid has to be unique, so lock the
# table for the check/insert.
#
DBQueryFatal("lock tables experiments write, experiment_stats write");
DBQueryFatal("lock tables experiments write");
$query_result =
DBQueryFatal("SELECT pid,eid FROM experiments ".
......@@ -142,25 +142,35 @@ if (! DBQueryWarn("INSERT INTO experiments ".
die("*** $0:\n".
" Database error inserting record for $pid/$eid!\n");
}
# Need the idx.
if (! ($query_result =
DBQueryWarn("select idx from experiments ".
"where pid='$pid' and eid='$eid'"))) {
DBQueryWarn("unlock tables");
fatal("Database error inserting experiment stats record for $pid/$eid!\n");
}
my ($idx) = $query_result->fetchrow_array;
# Insert stats record.
DBQueryWarn("INSERT INTO experiment_stats ".
"(eid, pid, creator, idx, gid, created, batch) ".
"VALUES ('$eid', '$pid', '$dbuid', $idx, '$gid', now(), ".
($immediate ? 0 : 1) . ")");
if (! DBQueryWarn("unlock tables")) {
fatal("Unexpected DB Error!");
}
#
# Create an experiment_resources record for the above record.
#
if (! DBQueryWarn("insert into experiment_resources (idx, tstamp, exptidx) ".
"select 0, now(), idx from experiments ".
"where pid='$pid' and eid='$eid'")) {
DBQueryWarn("unlock tables");
fatal("DB error inserting experiment resources record for $pid/$eid!\n");
}
#
# Now create an experiment_stats record to match.
#
if (! DBQueryWarn("insert into experiment_stats ".
"(eid, pid, creator, gid, created, batch, exptidx,rsrcidx) ".
"select '$eid', '$pid', '$dbuid', '$gid', now(), ".
($immediate ? 0 : 1) .
", e.idx,r.idx from experiments as e ".
"left join experiment_resources as r on e.idx=r.exptidx ".
"where pid='$pid' and eid='$eid'")) {
DBQueryWarn("unlock tables");
fatal("DB error inserting experiment stats record for $pid/$eid!\n");
}
#
# Create a directory structure for the experiment.
#
......@@ -246,20 +256,30 @@ sub fatal($)
print STDOUT "*** $0:\n";
print STDOUT " $mesg\n";
#
# Generally, we do not delete the stats/resource record, but if we
# failed at this point, no point in keeping the record. Just a
# waste of space since the testbed_stats log indicates there was a
# failure and why (sorta, via the exit code).
#
if (($query_result =
DBQueryWarn("select idx from experiments ".
"where pid='$pid' and eid='$eid'"))) {
my ($idx) = $query_result->fetchrow_array;
if (defined($idx) && $idx) {
DBQueryWarn("DELETE from experiment_stats ".
"WHERE eid='$eid' and pid='$pid' and exptidx=$idx");
DBQueryWarn("DELETE from experiment_resources ".
"WHERE eid='$eid' and pid='$pid' and exptidx=$idx");
}
}
#
# Clear the record and cleanup.
#
TBExptDestroy($pid, $eid);
#
# Generally, we do not delete the stats record, but if we failed
# at this point, no point in keeping the record. Just a waste of
# space.
#
if (defined($idx) && $idx) {
DBQueryWarn("DELETE from experiment_stats ".
"WHERE eid='$eid' and pid='$pid' and idx=$idx");
}
exit(-1);
}
......
......@@ -345,6 +345,9 @@ elsif ($inout eq "in") {
elsif ($inout eq "modify") {
my $modifyError = "";
GatherSwapStats($pid, $eid, $dbuid,
TBDB_STATS_SWAPMODIFY, 0, TBDB_STATS_FLAGS_PREMODIFY);
print "Backing up old experiment state ... " . TBTimeStamp() . "\n";
if (TBExptBackupVirtualState($pid, $eid, $$)) {
fatal("*** $0:\n".
......
......@@ -277,12 +277,12 @@ function WRITESIDEBAR() {
$TBBASE, "nodecontrol_list.php3");
WRITESIDEBARBUTTON("Node Up/Down Status",
$TBDOCBASE, "updown.php3");
WRITESIDEBARBUTTON("View Testbed Stats",
$TBBASE, "showstats.php3");
if (ISADMIN($login_uid)) {
WRITESIDEBARBUTTON("Edit Site Variables",
$TBBASE, "editsitevars.php3");
WRITESIDEBARBUTTON("View Testbed Stats",
$TBBASE, "showstats.php3");
}
if ($login_status & CHECKLOGIN_CVSWEB) {
......@@ -567,12 +567,12 @@ function PAGEFOOTER() {
<td colspan=2 class=contentbody>
<center>
<font size=-1>
[&nbsp;<a href=http://www.cs.utah.edu/flux/>
The&nbsp;Flux&nbsp;Research&nbsp;Group</a>&nbsp;]
[&nbsp;<a href=http://www.cs.utah.edu/>
School&nbsp;of&nbsp;Computing</a>&nbsp;]
[&nbsp;<a href=http://www.utah.edu/>
The&nbsp;University&nbsp;of&nbsp;Utah</a>&nbsp;]
[<a href=http://www.cs.utah.edu/flux/>
The&nbsp;Flux&nbsp;Research&nbsp;Group</a>]
[<a href=http://www.cs.utah.edu/>
School&nbsp;of&nbsp;Computing</a>]
[<a href=http://www.utah.edu/>
The&nbsp;University&nbsp;of&nbsp;Utah</a>]
</font>
<br>
<!-- begin copyright -->
......@@ -585,7 +585,7 @@ function PAGEFOOTER() {
<p align=right>
<font size=-2>
Problems?
Contact $TBMAILADDR;
Contact $TBMAILADDR.
</font>
</p>
<!-- end copyright -->\n";
......@@ -594,15 +594,7 @@ function PAGEFOOTER() {
if ($TBMAINSITE) {
echo "<p>
<a href=\"$TBDOCBASE/netemu.php3\"></a>\n";#
if (! isset($SSL_PROTOCOL)) {
echo "<a href=http://www.addme.com>
<img width=8 height=2
src='http://www.addme.com/link8.gif'
alt='Add Me!' border=0>
</a>\n";
}
<a href=\"$TBDOCBASE/netemu.php3\"></a>\n";
}
echo "</body></html>\n";
}
......
......@@ -7,6 +7,11 @@
include("defs.php3");
include("showstuff.php3");
#
# This page needs more work to make user friendly and flexible.
# Its a hack job at the moment.
#
#
# Standard Testbed Header
#
......@@ -19,30 +24,37 @@ $uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Only admins
#
if (! $isadmin) {
USERERROR("You do not have permission to view this page!", 1);
}
#
# Right now we show just the last N records entered, unless the user
# requested a specific record.
#
if (isset($record) && strcmp($record, "")) {
$wclause = "";
if (! $isadmin) {
$wclause = "and s.creator='$uid'";
}
$query_result =
DBQueryFatal("select * from experiment_stats ".
"where idx=$record");
DBQueryFatal("select s.*,r.* from experiment_stats as s ".
"left join experiment_resources as r on ".
" r.exptidx=s.exptidx ".
"where s.exptidx=$record $wclause ".
"order by r.idx desc");
if (mysql_num_rows($query_result) == 0) {
USERERROR("No such experiment record $record in the system!", 1);
}
}
else {
$wclause = "";
if (! $isadmin) {
$wclause = "where s.creator='$uid'";
}
$query_result =
DBQueryFatal("select * from experiment_stats ".
"order by idx desc limit 100");
DBQueryFatal("select s.*,r.* from experiment_stats as s ".
"left join experiment_resources as r on ".
" r.exptidx=s.exptidx ".
"$wclause ".
"order by s.exptidx desc,r.idx asc limit 200");
if (mysql_num_rows($query_result) == 0) {
USERERROR("No experiment records in the system!", 1);
......
......@@ -66,46 +66,43 @@ SHOWEXPLIST("PROJ",$pid);
SHOWGROUPMEMBERS($pid, $pid, 0);
#
# A list of project Groups (if more than just the default).
# A list of project Groups
#
echo "<center>
<h3>Project Groups</h3>\n";
SUBPAGESTART();
SUBMENUSTART("Project Options");
WRITESUBMENUBUTTON("Create Subgroup",
"newgroup_form.php3?pid=$pid");
WRITESUBMENUBUTTON("Show Project History",
"showstats.php3?showby=project&which=$pid");
SUBMENUEND();
$query_result =
DBQueryFatal("SELECT * FROM groups WHERE pid='$pid'");
if (mysql_num_rows($query_result)) {
echo "<center>
<h3>Project Groups</h3>
</center>
<table align=center border=1>\n";
echo "<table align=center border=1>\n";
echo "<tr>
<th>GID</th>
<th>Desription</th>
<th>Leader</th>
</tr>\n";
while ($row = mysql_fetch_array($query_result)) {