Commit eee7afa9 authored by Leigh Stoller's avatar Leigh Stoller

Bunches of changes to the Templates code ... all of it barely tested.

parent dce80595
......@@ -458,10 +458,10 @@ CREATE TABLE experiment_resources (
CREATE TABLE experiment_run_bindings (
exptidx int(10) unsigned NOT NULL default '0',
runid varchar(32) NOT NULL default '',
runidx int(10) unsigned NOT NULL default '0',
name varchar(64) NOT NULL default '',
value tinytext NOT NULL,
PRIMARY KEY (exptidx,runid,name)
PRIMARY KEY (exptidx,runidx,name)
) TYPE=MyISAM;
--
......@@ -470,11 +470,12 @@ CREATE TABLE experiment_run_bindings (
CREATE TABLE experiment_runs (
exptidx int(10) unsigned NOT NULL default '0',
idx int(10) unsigned NOT NULL auto_increment,
runid varchar(32) NOT NULL default '',
description tinytext,
start_time datetime default NULL,
stop_time datetime default NULL,
PRIMARY KEY (exptidx,runid)
PRIMARY KEY (exptidx,idx)
) TYPE=MyISAM;
--
......@@ -580,9 +581,11 @@ CREATE TABLE experiment_template_instances (
uid varchar(8) NOT NULL default '',
start_time datetime default NULL,
stop_time datetime default NULL,
runidx int(10) unsigned default NULL,
PRIMARY KEY (exptidx),
KEY parent_guid (parent_guid,parent_vers),
KEY pid (pid,eid)
KEY pid (pid,eid),
KEY exptidx (exptidx, runidx)
) TYPE=MyISAM;
--
......
......@@ -3265,3 +3265,6 @@ last_net_act,last_cpu_act,last_ext_act);
update nodes set pxe_boot_path=NULL where pxe_boot_path is not NULL;
alter table node_types drop column pxe_boot_path;
alter table nodes drop column next_pxe_boot_path;
4.44: Changes to templates.sql. Skip this revision for now.
......@@ -252,9 +252,12 @@ CREATE TABLE experiment_template_instances (
-- A little bit of duplication ...
start_time datetime default NULL,
stop_time datetime default NULL,
-- The current experiment that is running (see below). One at a time!
runidx int(10) unsigned default NULL,
PRIMARY KEY (exptidx),
KEY (parent_guid,parent_vers),
KEY (pid,eid)
KEY (pid,eid),
KEY (exptidx, runidx)
) TYPE=MyISAM;
#
......@@ -290,6 +293,8 @@ CREATE TABLE experiment_template_instance_bindings (
CREATE TABLE experiment_runs (
-- The experiment index (into the current experiments table).
exptidx int(10) unsigned NOT NULL default '0',
-- Auto increment to generate unique per-exptidx IDs
idx int(10) unsigned NOT NULL auto_increment,
-- Run ID (a per-experiment unique identifier for this run)
runid varchar(32) NOT NULL default '',
-- A short description; not sure I really want this.
......@@ -297,7 +302,7 @@ CREATE TABLE experiment_runs (
-- Timestamps
start_time datetime default NULL,
stop_time datetime default NULL,
PRIMARY KEY (exptidx, runid)
PRIMARY KEY (exptidx, idx)
) TYPE=MyISAM;
#
......@@ -308,10 +313,9 @@ CREATE TABLE experiment_runs (
CREATE TABLE experiment_run_bindings (
-- The experiment index (into the current experiments table).
exptidx int(10) unsigned NOT NULL default '0',
-- Run ID (a per-experiment unique identifier for this run)
runid varchar(32) NOT NULL default '',
runidx int(10) unsigned NOT NULL default '0',
name varchar(64) NOT NULL default '',
value tinytext NOT NULL,
PRIMARY KEY (exptidx, runid, name)
PRIMARY KEY (exptidx, runidx, name)
) TYPE=MyISAM;
......@@ -211,6 +211,18 @@ sub FinalizeTemplateInstanceRecord($$$;$)
{
my ($guid, $vers, $exptidx, $args) = @_;
#
# Get the runidx and do it first.
#
my $runidx;
return -1
if (TemplateInstanceInfo($exptidx, \$runidx) < 0);
if (defined($runidx)) {
return -1
if (FinalizeTemplateExerimentRunRecord($exptidx, $runidx) < 0);
}
my $query = "update experiment_template_instances set stop_time=now() ";
if (defined($args) && scalar(keys%{$args})) {
......@@ -225,6 +237,25 @@ sub FinalizeTemplateInstanceRecord($$$;$)
return 0;
}
#
# Get info about a template run.
#
sub TemplateInstanceInfo($$)
{
my ($exptidx, $prunidx) = @_;
my $query_result =
DBQueryWarn("select runidx from experiment_template_instances ".
"where exptidx='$exptidx'");
return -1
if (! $query_result);
my ($runidx) = $query_result->fetchrow_array();
$$prunidx = $runidx;
return 0;
}
#
# Create a new template instance record from the args provided.
#
......@@ -256,6 +287,95 @@ sub DeleteTemplateInstanceBindingRecords($$$)
return 0;
}
#
# Create a new experiment run record from the args provided, and return the
# newly generated index for it.
#
# Usage: int NewTemplateExerimentRunRecord(\%args, \$idx)
#
sub NewTemplateExerimentRunRecord($$)
{
my ($args, $pidx) = @_;
my $query = "insert into experiment_runs set ".
join(",", map("$_='" . $args->{$_} . "'", keys(%{$args})));
# Append some default value stuff.
$query .= ",start_time=now()";
my $query_result = DBQueryWarn($query);
return -1
if (! $query_result);
# Grab the insert record.
$$pidx = $query_result->insertid;
return 0;
}
#
# Delete experiment run record, by its index number.
#
sub DeleteTemplateExerimentRunRecord($$)
{
my ($exptidx, $runidx) = @_;
DBQueryFatal("delete from experiment_run_bindings ".
"where exptidx='$exptidx' and runidx='$runidx'");
DBQueryFatal("delete from experiment_runs ".
"where exptidx='$exptidx' and idx='$runidx'");
return 0;
}
#
# Finalize an experiment run record.
#
# Usage: int FinalizeTemplateExerimentRunRecord($exptidx, $runidx)
#
sub FinalizeTemplateExerimentRunRecord($$)
{
my ($exptidx, $runidx) = @_;
my $query = "update experiment_runs set stop_time=now() ";
$query .= "where exptidx='$exptidx' and idx='$runidx'";
return -1
if (! DBQueryWarn($query));
return 0;
}
#
# Insert new experiment run binding records.
#
# Usage: int NewTemplateInstanceRecord(\%args)
#
sub NewExperimentRunBindingRecord($)
{
my ($args) = @_;
my $query = "insert into experiment_run_bindings set ".
join(",", map("$_='" . $args->{$_} . "'", keys(%{$args})));
return -1
if (! DBQueryWarn($query));
return 0;
}
#
# Delete template instance binding records
#
sub DeleteExperimentRunBindingRecords($$)
{
my ($exptidx, $runidx) = @_;
DBQueryFatal("delete from experiment_run_bindings ".
"where exptidx='$exptidx' and runidx='$runidx'");
return 0;
}
#
# Utility routine to get the pid,tid,gid of a template.
#
......
......@@ -211,6 +211,18 @@ sub FinalizeTemplateInstanceRecord($$$;$)
{
my ($guid, $vers, $exptidx, $args) = @_;
#
# Get the runidx and do it first.
#
my $runidx;
return -1
if (TemplateInstanceInfo($exptidx, \$runidx) < 0);
if (defined($runidx)) {
return -1
if (FinalizeTemplateExerimentRunRecord($exptidx, $runidx) < 0);
}
my $query = "update experiment_template_instances set stop_time=now() ";
if (defined($args) && scalar(keys%{$args})) {
......@@ -225,6 +237,25 @@ sub FinalizeTemplateInstanceRecord($$$;$)
return 0;
}
#
# Get info about a template run.
#
sub TemplateInstanceInfo($$)
{
my ($exptidx, $prunidx) = @_;
my $query_result =
DBQueryWarn("select runidx from experiment_template_instances ".
"where exptidx='$exptidx'");
return -1
if (! $query_result);
my ($runidx) = $query_result->fetchrow_array();
$$prunidx = $runidx;
return 0;
}
#
# Create a new template instance record from the args provided.
#
......@@ -256,6 +287,95 @@ sub DeleteTemplateInstanceBindingRecords($$$)
return 0;
}
#
# Create a new experiment run record from the args provided, and return the
# newly generated index for it.
#
# Usage: int NewTemplateExerimentRunRecord(\%args, \$idx)
#
sub NewTemplateExerimentRunRecord($$)
{
my ($args, $pidx) = @_;
my $query = "insert into experiment_runs set ".
join(",", map("$_='" . $args->{$_} . "'", keys(%{$args})));
# Append some default value stuff.
$query .= ",start_time=now()";
my $query_result = DBQueryWarn($query);
return -1
if (! $query_result);
# Grab the insert record.
$$pidx = $query_result->insertid;
return 0;
}
#
# Delete experiment run record, by its index number.
#
sub DeleteTemplateExerimentRunRecord($$)
{
my ($exptidx, $runidx) = @_;
DBQueryFatal("delete from experiment_run_bindings ".
"where exptidx='$exptidx' and runidx='$runidx'");
DBQueryFatal("delete from experiment_runs ".
"where exptidx='$exptidx' and idx='$runidx'");
return 0;
}
#
# Finalize an experiment run record.
#
# Usage: int FinalizeTemplateExerimentRunRecord($exptidx, $runidx)
#
sub FinalizeTemplateExerimentRunRecord($$)
{
my ($exptidx, $runidx) = @_;
my $query = "update experiment_runs set stop_time=now() ";
$query .= "where exptidx='$exptidx' and idx='$runidx'";
return -1
if (! DBQueryWarn($query));
return 0;
}
#
# Insert new experiment run binding records.
#
# Usage: int NewTemplateInstanceRecord(\%args)
#
sub NewExperimentRunBindingRecord($)
{
my ($args) = @_;
my $query = "insert into experiment_run_bindings set ".
join(",", map("$_='" . $args->{$_} . "'", keys(%{$args})));
return -1
if (! DBQueryWarn($query));
return 0;
}
#
# Delete template instance binding records
#
sub DeleteExperimentRunBindingRecords($$)
{
my ($exptidx, $runidx) = @_;
DBQueryFatal("delete from experiment_run_bindings ".
"where exptidx='$exptidx' and runidx='$runidx'");
return 0;
}
#
# Utility routine to get the pid,tid,gid of a template.
#
......
......@@ -252,7 +252,7 @@ Node instproc unknown {m args} {
Simulator instproc connect {src dst} {
}
Simulator instproc define_template_parameter {name args} {
Simulator instproc define-template-parameter {name args} {
}
LanNode instproc trace {args} {
......
......@@ -80,6 +80,7 @@ my $user_email;
my $dbuid;
my $logname;
my $exptidx;
my $runidx;
# For the END block below.
my $cleaning = 0;
my $exptcreated = 0;
......@@ -377,20 +378,52 @@ fatal($? >> 8, "Could not instantiate the experiment")
if ($?);
#
# Insert a template instance record.
# All instances currently start with a default run.
#
my %args = ();
$args{'exptidx'} = $exptidx;
$args{'runid'} = $eid;
if (libTemplates::NewTemplateExerimentRunRecord(\%args, \$runidx) < 0) {
fatal(-1, "Could not insert experiment run record!");
}
#
# Insert a template instance record (now that we have the runidx).
#
%args = ();
$args{'parent_guid'} = $guid;
$args{'parent_vers'} = $version;
$args{'pid'} = $pid;
$args{'eid'} = $eid;
$args{'uid'} = $dbuid;
$args{'exptidx'} = $exptidx;
$args{'runidx'} = $runidx;
if (libTemplates::NewTemplateInstanceRecord(\%args) < 0) {
fatal(-1, "Could not insert experiment instance record!");
}
#
# And the bindings for the default run ...
#
if ($paramfile) {
foreach my $name (keys(%parameters)) {
my $value = $parameters{$name};
my %args = ();
$args{'exptidx'} = $exptidx;
$args{'runidx'} = $runidx;
$args{'name'} = $name;
$args{'value'} = (defined($value) ? DBQuoteSpecial($value) : "");
$args{'value'} =~ s/^\'(.*)\'$/$1/;
libTemplates::NewExperimentRunBindingRecord(\%args) == 0
or tbdie("Error inserting run binding into DB!");
}
}
# Stop the web interface from spewing.
TBExptCloseLogFile($pid, $eid)
if (defined($logname));
......@@ -533,6 +566,9 @@ sub cleanup()
exit(-1)
if ($?);
libTemplates::DeleteTemplateExerimentRunRecord($exptidx, $runidx)
if (defined($runidx));
libTemplates::DeleteTemplateInstanceBindingRecords($guid,
$version, $exptidx);
libTemplates::DeleteTemplateInstanceRecord($guid, $version, $exptidx);
......
......@@ -80,6 +80,7 @@ my $user_email;
my $dbuid;
my $logname;
my $exptidx;
my $runidx;
# For the END block below.
my $cleaning = 0;
my $exptcreated = 0;
......@@ -377,20 +378,52 @@ fatal($? >> 8, "Could not instantiate the experiment")
if ($?);
#
# Insert a template instance record.
# All instances currently start with a default run.
#
my %args = ();
$args{'exptidx'} = $exptidx;
$args{'runid'} = $eid;
if (libTemplates::NewTemplateExerimentRunRecord(\%args, \$runidx) < 0) {
fatal(-1, "Could not insert experiment run record!");
}
#
# Insert a template instance record (now that we have the runidx).
#
%args = ();
$args{'parent_guid'} = $guid;
$args{'parent_vers'} = $version;
$args{'pid'} = $pid;
$args{'eid'} = $eid;
$args{'uid'} = $dbuid;
$args{'exptidx'} = $exptidx;
$args{'runidx'} = $runidx;
if (libTemplates::NewTemplateInstanceRecord(\%args) < 0) {
fatal(-1, "Could not insert experiment instance record!");
}
#
# And the bindings for the default run ...
#
if ($paramfile) {
foreach my $name (keys(%parameters)) {
my $value = $parameters{$name};
my %args = ();
$args{'exptidx'} = $exptidx;
$args{'runidx'} = $runidx;
$args{'name'} = $name;
$args{'value'} = (defined($value) ? DBQuoteSpecial($value) : "");
$args{'value'} =~ s/^\'(.*)\'$/$1/;
libTemplates::NewExperimentRunBindingRecord(\%args) == 0
or tbdie("Error inserting run binding into DB!");
}
}
# Stop the web interface from spewing.
TBExptCloseLogFile($pid, $eid)
if (defined($logname));
......@@ -533,6 +566,9 @@ sub cleanup()
exit(-1)
if ($?);
libTemplates::DeleteTemplateExerimentRunRecord($exptidx, $runidx)
if (defined($runidx));
libTemplates::DeleteTemplateInstanceBindingRecords($guid,
$version, $exptidx);
libTemplates::DeleteTemplateInstanceRecord($guid, $version, $exptidx);
......
......@@ -60,6 +60,7 @@ my $user_email;
my $dbuid;
my $logname;
my $exptidx;
my $runidx;
# For the END block below.
my $cleaning = 0;
my $exptcreated = 0;
......@@ -141,6 +142,10 @@ if (! TBExptIDX($pid, $eid, \$exptidx)) {
fatal(-1, "Could not get experiment index for $pid,$eid!");
}
if (! libtemplates::TemplateInstanceInfo($exptidx, \$runidx)) {
fatal(-1, "Could not get experiment run index for $exptidx!");
}
#
# Make sure UID is allowed to create experiments in this project.
#
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
include("template_defs.php");
#
# Only known and logged in users ...
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Verify page arguments.
#
if (!isset($exptidx) ||
strcmp($exptidx, "") == 0) {
USERERROR("You must provide an instance ID", 1);
}
if (!isset($runidx) ||
strcmp($runidx, "") == 0) {
USERERROR("You must provide an run ID", 1);
}
if (!isset($guid) ||
strcmp($guid, "") == 0) {
USERERROR("You must provide a template ID", 1);
}
if (!isset($version) ||
strcmp($version, "") == 0) {
USERERROR("You must provide a template version number", 1);
}
if (!TBvalid_guid($guid)) {
PAGEARGERROR("Invalid characters in GUID!");
}
if (!TBvalid_integer($version)) {
PAGEARGERROR("Invalid characters in version!");
}
if (!TBvalid_integer($exptidx)) {
PAGEARGERROR("Invalid characters in instance ID!");
}
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.
#
if (! TBValidExperimentTemplate($guid, $version)) {
USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1);
}
if (! TBIsTemplateInstanceExperiment($exptidx)) {
USERERROR("The instance $exptidx is not a valid instance in ".
"template $guid/$version!", 1);
}
if (! TBValidExperimentRun($exptidx, $runidx)) {
USERERROR("The run $runidx is not a valid experiment run!", 1);
}
#
# Verify Permission.
#
if (! TBExptTemplateAccessCheck($uid, $guid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1);
}
echo "<font size=+2>Experiment Run<b> " .
MakeLink("instance",
"guid=$guid&version=$version&exptidx=$exptidx",
"$guid/$version/$exptidx") .
"</b></font>\n";
echo "<br><br>\n";
SHOWEXPERIMENTRUN($exptidx, $runidx);
#
# Standard Testbed Footer
#
PAGEFOOTER();
?>
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
include("template_defs.php");
#
# Only known and logged in users ...
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);
#
# Verify page arguments.
#
if (!isset($exptidx) ||
strcmp($exptidx, "") == 0) {
USERERROR("You must provide an instance ID", 1);
}
if (!isset($guid) ||
strcmp($guid, "") == 0) {
USERERROR("You must provide a template ID", 1);
}
if (!isset($version) ||
strcmp($version, "") == 0) {
USERERROR("You must provide a template version number", 1);
}
if (!TBvalid_guid($guid)) {
PAGEARGERROR("Invalid characters in GUID!");
}
if (!TBvalid_integer($version)) {
PAGEARGERROR("Invalid characters in version!");
}
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.
#
if (! TBValidExperimentTemplate($guid, $version)) {
USERERROR("The experiment template $guid/$version is not a valid ".
"experiment template!", 1);
}
if (! TBIsTemplateInstanceExperiment($exptidx)) {
USERERROR("The instance $exptidx is not a valid instance in ".
"template $guid/$version!", 1);
}
#
# Verify Permission.
#
if (! TBExptTemplateAccessCheck($uid, $guid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view experiment template ".
"$guid/$version!", 1);
}
echo "<font size=+2>Template Instance <b>" .
MakeLink("template",
"guid=$guid&version=$version", "$guid/$version") .
"</b></font>\n";
echo "<br><br>\n";
SHOWTEMPLATEINSTANCE($guid, $version, $exptidx, 1);
#
# Standard Testbed Footer
#
PAGEFOOTER();
?>
......@@ -75,7 +75,8 @@ $panic_date = $row["panic_date"];
$lockdown = $row["lockdown"];
# Template Instance Experiments get special treatment in this page.
$isinstance = $EXPOSETEMPLATES && TBIsTemplateInstanceExperiment($expindex);
$isinstance = ($EXPOSETEMPLATES &&
TBIsTemplateInstanceExperiment($expindex) ? 1 : 0);
if ($isinstance) {
$tag = "Template Instance";
TBPidEid2Template($pid, $eid, &$guid, &$version);
......@@ -183,6 +184,12 @@ if ($expstate) {
"modifyexp.php3?pid=$exp_pid&eid=$exp_eid");
}
}
if ($isinstance && $expstate == $TB_EXPTSTATE_ACTIVE) {
WRITESUBMENUBUTTON("Start Experiment Run",
"template_exprun.php?action=start&guid=$guid".
"&version=$version&exptidx=$expindex");
}
if ($expstate == $TB_EXPTSTATE_ACTIVE) {
WRITESUBMENUBUTTON("Modify Traffic Shaping",
......
......@@ -136,6 +136,12 @@ function MakeLink($which, $args, $text)
elseif ($which == "metadata") {
$page = "template_metadata.php";
}
elseif ($which == "instance") {
$page = "instance_show.php";
}
elseif ($which == "run") {
$page = "experimentrun_show.php";
}
return "<a href=${page}?${args}>$text</a>";
}
......@@ -477,6 +483,7 @@ function SHOWTEMPLATEHISTORY($guid, $version)