Commit 7e0cfdd4 authored by Leigh Stoller's avatar Leigh Stoller

A bunch of little tweaks and fixes, mostly related to the archives.

parent 1ad18f51
......@@ -473,6 +473,7 @@ CREATE TABLE experiment_runs (
idx int(10) unsigned NOT NULL auto_increment,
runid varchar(32) NOT NULL default '',
description tinytext,
archive_tag varchar(32) default NULL,
start_time datetime default NULL,
stop_time datetime default NULL,
PRIMARY KEY (exptidx,idx)
......
......@@ -3372,3 +3372,9 @@ last_net_act,last_cpu_act,last_ext_act);
alter table experiment_template_parameters add \
metadata_vers smallint(5) unsigned NOT NULL default '0';
4.61: Add archive_tag slot to experiment runs so we can find the
corresponding spot in the archive.
alter table experiment_runs add \
archive_tag varchar(32) NULL after description;
......@@ -333,6 +333,8 @@ CREATE TABLE experiment_runs (
runid varchar(32) NOT NULL default '',
-- A short description; not sure I really want this.
description tinytext,
-- The tag for the commit at the end of the run.
archive_tag varchar(32) default NULL,
-- Timestamps
start_time datetime default NULL,
stop_time datetime default NULL,
......
......@@ -101,6 +101,8 @@ sub pid($) { return ((! ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}->{'pid'}); }
sub gid($) { return ((! ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}->{'gid'}); }
sub eid($) { return ((! ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}->{'eid'}); }
sub tid($) { return ((! ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}->{'tid'}); }
sub archive_idx($) {
return ((! ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}->{'archive_idx'}); }
#
# Lookup a template given an experiment index.
......@@ -1276,11 +1278,8 @@ sub Start($)
return $self->Update(1);
}
#
# Finalize a template instance record.
#
sub Finalize($;$)
# Set the stop time ...
sub Stop($;$)
{
my ($self, $argref) = @_;
......@@ -1296,21 +1295,37 @@ sub Finalize($;$)
my $runidx = $self->runidx();
return -1
if (defined($runidx) && FinalizeCurrentRun($self) < 0);
if (defined($runidx) && StopCurrentRun($self) < 0);
# And then the instance.
my $query = "update experiment_template_instances set stop_time=now() ";
DBQueryWarn("update experiment_template_instances set stop_time=now() ".
"where idx='$idx'")
or return -1;
return Refresh($self);
}
if (defined($argref) && scalar(keys%{$argref})) {
$query .= ",";
$query .= join(",",
map("$_='" . $argref->{$_} . "'", keys(%{$argref})));
}
$query .= " where idx='$idx'";
#
# Finalize.
#
sub Finalize($;$)
{
my ($self, $argref) = @_;
# Must be a real reference.
return -1
if (! DBQueryWarn($query));
if (! ref($self));
my $idx = $self->idx();
#
# Do the Run record first
#
my $runidx = $self->runidx();
return -1
if (defined($runidx) && FinalizeCurrentRun($self) < 0);
return Refresh($self);
}
......@@ -1506,6 +1521,31 @@ sub DeleteCurrentRun($)
return Refresh($self);
}
#
# Stop the current experiment run,
#
sub StopCurrentRun($)
{
my ($self) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $idx = $self->idx();
my $runidx = $self->runidx();
my $exptidx = $self->exptidx();
return -1
if (!defined($runidx));
DBQueryWarn("update experiment_runs set stop_time=now() ".
"where exptidx='$exptidx' and idx='$runidx'")
or return -1;
return Refresh($self);
}
#
# Finalize the current experiment run record.
#
......@@ -1524,7 +1564,21 @@ sub FinalizeCurrentRun($)
return -1
if (!defined($runidx));
DBQueryWarn("update experiment_runs set stop_time=now() ".
#
# Grab the current archive tag. This will correspond to the commit
# done at the end of the run.
#
my $query_result =
DBQueryWarn("select r.archive_tag from experiment_stats as s ".
"left join experiment_resources as r on ".
" r.idx=s.rsrcidx ".
"where s.exptidx='$exptidx'");
return -1
if (!$query_result || !$query_result->numrows);
my ($archive_tag) = $query_result->fetchrow_array();
DBQueryWarn("update experiment_runs set archive_tag='$archive_tag' ".
"where exptidx='$exptidx' and idx='$runidx'")
or return -1;
......
......@@ -209,6 +209,14 @@ sub ArchiveCreate(;$$$)
" file://$repodir/$view/trunk ".
" file://$repodir/$view/tags/${tag}-branch")
== 0 or goto bad;
# Create a tag in the history directory for the commit. The
# history directory has just the commit tags, so its easy to go
# back in time.
mysystem("$SVN copy $svnopt -m 'ArchiveCreate' ".
" file://$repodir/$view/trunk ".
" file://$repodir/$view/history/${tag}")
== 0 or goto bad;
# Now check it out. This creates the $checkouts/$view directory.
mysystem("cd $checkouts; ".
......@@ -831,6 +839,14 @@ sub ArchiveFork($$;$$$)
" file://$repodir/$newview/trunk ".
" file://$repodir/$newview/tags/${newtag}-branch")
== 0 or goto bad;
# Create a tag in the history directory for the commit. The
# history directory has just the commit tags, so its easy to go
# back in time.
mysystem("$SVN copy $svnopt -m 'ArchiveFork Branch' ".
" file://$repodir/$newview/trunk ".
" file://$repodir/$newview/history/${newtag}")
== 0 or goto bad;
# Now check it out. This creates the checkouts/$newview directory.
mysystem("cd $checkouts; ".
......
......@@ -238,32 +238,17 @@ fatal(-1, "Could not add NS file to template store")
if ($template->AddInputFile($inputfile) < 0);
#
# Grab archive index for new templates.
# Grab archive index for new templates.
#
if (!$modify) {
libArchive::TBExperimentArchiveInfo($pid, $eid, \$archive_idx, undef)
>= 0 or fatal(-1, "Could not get archive index for new template!");
# Do a commit point on the template archive since it does not actually
# change after it is created (instances are branches).
libArchive::TBCommitExperimentArchive($pid, $eid, "TemplateCreate")
>= 0 or fatal(-1, "Failed to commit experiment archive!");
}
else {
#
# Grab the archive index for the parent; the archive is shared.
#
libArchive::TBExperimentArchiveInfo($pid,
$parent_template->eid(),
\$archive_idx, undef)
>= 0 or fatal(-1, "Could not get archive index for parent!");
# Do a commit point on the template archive since it does not actually
# change after it is created (instances are branches).
libArchive::TBCommitExperimentArchive($pid,
$parent_template->eid(),
"TemplateCreate")
>= 0 or fatal(-1, "Failed to commit experiment archive!");
$archive_idx = $parent_template->archive_idx();
}
# And update the record.
......@@ -273,6 +258,15 @@ $args{'archive_idx'} = $archive_idx;
$template->Update(\%args) == 0
or fatal(-1, "Could not update template record!");
#
# When creating a template, the archive is created (or forked) in batchexp
# but it is not committed. We need to do that now cause this experiment
# is never actually swapped in. Instead each instance is a new fork, and if
# the archive were not committed, it would not look correct.
#
libArchive::TBCommitExperimentArchive($pid, $eid, "TemplateCreate")
>= 0 or fatal(-1, "Failed to commit experiment archive!");
#
# Copy the virt_parameters table to the formal parameters table.
# I am not sure about the need for this table yet, but the only way
......
......@@ -34,7 +34,7 @@ sub usage()
"-a <action> - start or stop\n".
"-w - wait for template to be instantiated\n".
"-q - be less chatty\n".
"-E <str> - A pithy sentence describing the template\n".
"-E <str> - A pithy sentence describing the run\n".
"-r <runid> - A token ... we will make on up for you\n".
"-p <file> - XML file of parameter bindings\n".
"-e <eid> - The instance name\n".
......@@ -230,17 +230,19 @@ if (defined($paramfile)) {
if ($donebad);
}
#
# Finalize running experiment.
#
$instance->FinalizeCurrentRun() == 0
or fatal(-1, "Could not finalize experiment run for $instance!");
# This sets the stop time.
$instance->StopCurrentRun() == 0
or fatal(-1, "Could not stop experiment run for $instance!");
#
# Commit the archive.
#
system("$archcontrol -t $runid commit $pid $eid");
# This has to be done after the archive commit, so we can find the tag.
$instance->FinalizeCurrentRun() == 0
or fatal(-1, "Could not finalize experiment run for $instance!");
goto done
if ($action eq "stop");
......
......@@ -35,6 +35,7 @@ sub usage()
"-b - batchmode; insert into batch queue\n".
"-w - wait for template to be instantiated\n".
"-q - be less chatty\n".
"-E <str> - A pithy sentence describing the instance\n".
"-p <file>- XML file of parameter bindings\n".
"-S <str> - Instance cannot be swapped; must provide reason\n".
"-L <str> - Instance cannot be IDLE swapped; must provide reason\n".
......@@ -46,12 +47,13 @@ sub usage()
"<guid/vers> - GUID and version to swapin\n");
exit(-1);
}
my $optlist = "qwe:S:L:na:l:se:p:b";
my $optlist = "qwe:S:L:na:l:se:p:bE:";
my %options = ();
my $quiet = 0;
my $waitmode = 0;
my $batchmode = 0;
my $foreground = 0;
my $description;
my $paramfile;
my $guid;
my $version;
......@@ -462,7 +464,7 @@ if ($batchmode) {
#
# All instances currently start with a default run.
#
$instance->NewRun($eid) == 0
$instance->NewRun($eid, $description) == 0
or fatal(-1, "Could not insert experiment new run record!");
#
......@@ -607,6 +609,15 @@ sub ParseArgs()
}
$paramfile = $inputfile;
}
if (defined($options{"E"})) {
if (! TBcheck_dbslot($options{"E"},
"experiment_templates", "description",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper template description!");
}
$description = $options{"E"};
}
}
#
......
......@@ -35,6 +35,7 @@ sub usage()
"-b - batchmode; insert into batch queue\n".
"-w - wait for template to be instantiated\n".
"-q - be less chatty\n".
"-E <str> - A pithy sentence describing the instance\n".
"-p <file>- XML file of parameter bindings\n".
"-S <str> - Instance cannot be swapped; must provide reason\n".
"-L <str> - Instance cannot be IDLE swapped; must provide reason\n".
......@@ -46,12 +47,13 @@ sub usage()
"<guid/vers> - GUID and version to swapin\n");
exit(-1);
}
my $optlist = "qwe:S:L:na:l:se:p:b";
my $optlist = "qwe:S:L:na:l:se:p:bE:";
my %options = ();
my $quiet = 0;
my $waitmode = 0;
my $batchmode = 0;
my $foreground = 0;
my $description;
my $paramfile;
my $guid;
my $version;
......@@ -462,7 +464,7 @@ if ($batchmode) {
#
# All instances currently start with a default run.
#
$instance->NewRun($eid) == 0
$instance->NewRun($eid, $description) == 0
or fatal(-1, "Could not insert experiment new run record!");
#
......@@ -607,6 +609,15 @@ sub ParseArgs()
}
$paramfile = $inputfile;
}
if (defined($options{"E"})) {
if (! TBcheck_dbslot($options{"E"},
"experiment_templates", "description",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper template description!");
}
$description = $options{"E"};
}
}
#
......
......@@ -234,6 +234,10 @@ if ($waitmode) {
POSIX::setsid();
}
# This sets the stop time.
$instance->Stop() == 0
or fatal(-1, "Could not stop experiment instance!");
#
# Now do the swapout.
#
......@@ -251,7 +255,7 @@ fatal($? >> 8, "Could not terminate template instance")
# Reminder; instance records are not deleted!
$instance->Finalize() == 0
or fatal(-1, "Could not finalize experiment instance record!");
or fatal(-1, "Could not finalize experiment instance!");
exit(0);
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002, 2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2002, 2005, 2006 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -115,8 +115,10 @@ elseif (isset($exptidx) && $exptidx != "") {
# Need the pid/eid/gid. Access the stats table since we want to provide
# cvs access to terminated experiments via the archive.
$query_result =
DBQueryFatal("select pid,eid,gid,archive_idx from experiment_stats ".
"where exptidx='$exptidx'");
DBQueryFatal("select s.pid,s.eid,s.gid,s.archive_idx,a.archived ".
" from experiment_stats as s ".
"left join archives as a on a.idx=s.archive_idx ".
"where s.exptidx='$exptidx'");
if (!mysql_num_rows($query_result)) {
USERERROR("Experiment '$exptidx' is not a valid experiment", 1);
}
......@@ -124,12 +126,13 @@ elseif (isset($exptidx) && $exptidx != "") {
$pid = $row[0];
$eid = $row[1];
$gid = $row[2];
$repoidx = $row[3];
$repoidx = $row[3];
$archived = $row[4];
# If a current experiment, check usual permissions.
if (TBValidExperiment($pid, $eid)) {
# Lets do group level check since it might not be a current experiment.
if (!$archived) {
if (! ISADMIN($uid) &&
! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) {
! TBProjAccessCheck($uid, $pid, $gid, $TB_PROJECT_READINFO)) {
USERERROR("Not enough permission to view '$pid/$eid'", 1);
}
$repodir = "/usr/testbed/exparchive/$repoidx/repo/";
......
......@@ -936,6 +936,8 @@ function PAGEFOOTER($view = NULL) {
# Plug the home site from all others.
echo "\n<p><a href=\"www.emulab.net/netemu.php3\"></a>\n";
# This has to be after all the tooltip definitions.
echo "<script type='text/javascript' src='js/wz_tooltip.js'></script>";
echo "</body></html>\n";
}
......
......@@ -465,7 +465,12 @@ class Template
$vers = $this->vers();
$query_result =
DBQueryFatal("select * from experiment_template_instances as i ".
DBQueryFatal("select i.*,r.archive_tag ".
" from experiment_template_instances as i ".
"left join experiment_stats as s on ".
" s.exptidx=i.exptidx ".
"left join experiment_resources as r on ".
" r.idx=s.rsrcidx ".
"where (i.parent_guid='$guid' and ".
" i.parent_vers='$vers') ".
"order by i.start_time");
......@@ -481,10 +486,10 @@ class Template
echo "<tr>
<th align=center>Expand</th>
<th>EID</th>
<th>IDX</th>
<th>UID</th>
<th>Start Time</th>
<th>Stop Time</th>
<th align=center>Show</th>
<th align=center>Archive</th>
</tr>\n";
......@@ -499,6 +504,7 @@ class Template
$stop = $row['stop_time'];
$exptidx = $row['exptidx'];
$idx = $row['idx'];
$tag = $row['archive_tag'];
if (! isset($stop)) {
$stop = "&nbsp";
......@@ -521,17 +527,21 @@ class Template
echo " </td>
<td>$eid</td>\n";
echo " <td>$uid</td>
<td>$start</td>
<td>$stop</td>\n";
echo " <td align=center>".
MakeLink("instance",
"guid=$guid&version=$vers&exptidx=$exptidx",
"$idx");
"<img border=0 alt='Show' src='greenball.gif'>");
echo " <td align=center>
<a href=cvsweb/cvswebwrap.php3/$exptidx/history/$tag/".
"?exptidx=$exptidx>
<img border=0 alt='i' src='greenball.gif'></a></td>";
echo " </td>
<td>$uid</td>
<td>$start</td>
<td>$stop</td>
<td align=center>
<a href=cvsweb/cvswebwrap.php3/$exptidx/?exptidx=$exptidx>
<img border=0 alt='i' src='greenball.gif'></a></td>
</tr>\n";
if ($expandit) {
......@@ -835,18 +845,26 @@ class TemplateInstance
#
# Show an instance.
#
function Show($withruns) {
function Show($detailed) {
$exptidx = $this->exptidx();
$runidx = $this->runidx();
$runidx = $this->runidx();
$guid = $this->guid();
$vers = $this->vers();
$pid = $this->pid();
$uid = $this->uid();
$start = $this->start_time();
$stop = $this->stop_time();
$template= $this->template();
$pcount = $template->ParameterCount();
if ($detailed && $pcount) {
echo "<table border=0 bgcolor=#000 color=#000 class=stealth ".
" cellpadding=0 cellspacing=0 align=center>\n";
echo "<tr valign=top>";
echo "<td class=stealth align=center>\n";
}
echo "<center>
<h3>Template Instance</h3>
<h3>Template Details</h3>
</center>\n";
echo "<table align=center cellpadding=2 cellspacing=2 border=1>\n";
......@@ -857,66 +875,22 @@ class TemplateInstance
ShowItem("ID", $exptidx);
ShowItem("Project", MakeLink("project", "pid=$pid", $pid));
ShowItem("Creator", MakeLink("user", "target_uid=$uid", $uid));
ShowItem("Started", $start_time);
ShowItem("Stopped", (isset($stop_time) ? $stop_time : "&nbsp"));
ShowItem("Started", $start);
ShowItem("Stopped", (isset($stop) ? $stop : "&nbsp"));
ShowItem("Current Run", (isset($runidx) ? $runidx : "&nbsp"));
echo "</table>\n";
if ($withruns) {
$query_result =
DBQueryFatal("select * from experiment_runs ".
"where exptidx='$exptidx'");
if (mysql_num_rows($query_result)) {
echo "<center>
<h3>Instance History (Runs)</h3>
</center>
<table align=center border=1
cellpadding=5 cellspacing=2>\n";
echo "<tr>
<th align=center>Expand</th>
<th align=center>Archive</th>
<th>RunID</th>
<th>ID</th>
<th>Start Time</th>
<th>Stop Time</th>
<th>Description</th>
</tr>\n";
if ($detailed && $pcount) {
echo "</td>";
echo "<td align=center class=stealth> &nbsp &nbsp &nbsp </td>\n";
echo "<td class=stealth align=center>\n";
$this->ShowBindings();
echo "</tr>";
echo "</table>\n";
}
while ($rrow = mysql_fetch_array($query_result)) {
$runidx = $rrow['idx'];
$runid = $rrow['runid'];
$start = $rrow['start_time'];
$stop = $rrow['stop_time'];
$exptidx = $rrow['exptidx'];
$description = $rrow['description'];
if (! isset($stop)) {
$stop = "&nbsp";
}
echo "<tr>\n";
echo " <td align=center>".
MakeLink("run",
"guid=$guid&version=$vers".
"&exptidx=$exptidx&runidx=$runidx",
"<img border=0 alt='i' src='greenball.gif'>");
echo " </td>
<td align=center>
<a href=cvsweb/cvswebwrap.php3".
"/$exptidx/history/$runid/?exptidx=$exptidx>
<img border=0 alt='i'
src='greenball.gif'></a></td>
<td>$runid</td>
<td>$runidx</td>
<td>$start</td>
<td>$stop</td>
<td>$description</td>
</tr>\n";
}
echo "</table>\n";
}
if ($detailed) {
$this->ShowRunList(1);
}
}
......@@ -934,7 +908,7 @@ class TemplateInstance
return 0;
echo "<center>
<h3>Template Instance Bindings</h3>
<h3>Instance Bindings</h3>
</center>
<table align=center border=1 cellpadding=5 cellspacing=2>\n";
......@@ -982,7 +956,7 @@ class TemplateInstance
echo "<table align=center border=1 cellpadding=5 cellspacing=2>\n";
echo "<tr>
<th align=center>Expand</th>
<th align=center>Show</th>
<th align=center>Archive</th>
<th>RunID</th>
<th>ID</th>
......@@ -997,11 +971,33 @@ class TemplateInstance
$start = $rrow['start_time'];
$stop = $rrow['stop_time'];
$exptidx = $rrow['exptidx'];
$tag = $rrow['archive_tag'];
$description = $rrow['description'];
$onmouseover = "";
if (! isset($stop)) {
$stop = "&nbsp";
}
if (isset($description) && $description != "") {
$onmouseover = MakeMouseOver($description);
if (strlen($description) > 30) {
$description = substr($description, 0, 30) . " <b>...</b>";
}
}
else {
$description = "&nbsp ";
}
if (isset($tag) && $tag != "") {
$archive_link =
"<a href=cvsweb/cvswebwrap.php3".
"/$exptidx/history/$tag/?exptidx=$exptidx>".
"<img border=0 alt='i' src='greenball.gif'></a>";
}
else {
$archive_link = "&nbsp ";
}
echo "<tr>\n";
echo " <td align=center>".
......@@ -1010,16 +1006,12 @@ class TemplateInstance
"&exptidx=$exptidx&runidx=$runidx",
"<img border=0 alt='i' src='greenball.gif'>");
echo " </td>
<td align=center>
<a href=cvsweb/cvswebwrap.php3".
"/$exptidx/history/$runid/?exptidx=$exptidx>
<img border=0 alt='i'
src='greenball.gif'></a></td>
<td align=center>$archive_link</td>
<td>$runid</td>
<td>$runidx</td>
<td>$start</td>
<td>$stop</td>
<td>$description</td>
<td $onmouseover>$description</td>
</tr>\n";
}
echo "</table>\n";
......@@ -1060,6 +1052,7 @@ class TemplateInstance
$row = mysql_fetch_array($query_result);
$start = $row['start_time'];
$stop = $row['stop_time'];
$description = $row['description'];
if (!isset($stop))
$stop = "&nbsp";
......@@ -1081,6 +1074,21 @@ class TemplateInstance
ShowItem("Started", $start);
ShowItem("Stopped", $stop);
if (isset($description) && $description != "") {
echo "<tr>
<td align=center colspan=2>
Description
</td>
</tr>
<tr>
<td colspan=2 align=center class=left>
<textarea readonly
rows=5 cols=50>" .
ereg_replace("\r", "", $description) .
"</textarea>
</td>
</tr>\n";
}
echo "</table>\n";
$query_result =
......
......@@ -86,7 +86,7 @@ function SPITFORM($instance, $formfields, $parameters, $errors)
echo "<tr>
<td colspan=2>
Use this text area to (optionally) describe your experiment:
Use this text area for an (optional) description:
</td>
</tr>
<tr>
......
......@@ -211,8 +211,6 @@ echo "</tr>\n";
echo "</table>\n";
echo "</center>\n";
echo "<script type='text/javascript' src='js/wz_tooltip.js'></script>";
#
# Standard Testbed Footer
#
......
......@@ -220,6 +220,23 @@ function SPITFORM($template, $formfields, $parameters, $errors)
echo "</table></td></tr>";
}
#
# Description
#
echo "<tr>
<td colspan=2>
Use this text area for an (optional) description:
</td>
</tr>
<tr>
<td colspan=2 align=center class=left>
<textarea name=\"formfields[description]\"
rows=5 cols=80>" .
ereg_replace("\r", "", $formfields[description]) .
"</textarea>
</td>
</tr>\n";
#
# Batch Experiment?
#
......@@ -501,6 +518,19 @@ if (count($parameter_masterlist)) {
$command_options .= " -p $parameter_xmlfile";
}