Commit 4ce9c421 authored by Leigh Stoller's avatar Leigh Stoller

Support for capturing the trace data that is stored in the pcal files

into per-experiment databases on ops. Additional support for reconsituting
those databases back into temporary databases on ops, for post processing.

* This revision relies on the "snort" port (/usr/ports/security/snort)
  to read the pcap files and load them into a database. The schema is
  probably not ideal, but its better then nothing. See the file
  ops:/usr/local/share/examples/snort/create_mysql for the schema.

* For simplicity, I have hooked into loghole, which already had all
  the code for downloading the trace data. I added some new methods to
  the XMLRPC server for loghole to use, to get the users DB password
  and the name of the per-experiment database. There is a new slot in
  the traces table that indicates that the trace should be snorted to
  its DB. In case you forgot, at the end of a run or when the instance
  is swapped out, loghole is run to download the trace data.

* For reconsituting, there are lots of additions to opsdb_control and
  opsdb_control.proxy to create "temporary" databases and load them
  from a dump file that is stored in the archive. I've added a button
  to the Template Record page, inappropriately called "Analyze" since
  right now all it does is reconsitute the trace data into a DB on
  ops.

  Currently, the only indication of what has been done (the name of
  the DBs created on ops) is the log email that the user gets. A
  future project is tell the user this info in the web interface.

* To turn on database capturing of trace data, do this in your NS
  file:

	set link0 ...
	$link0 trace
	$link0 trace_snaplen 128
	$link0 trace_db 1

   the increase in snaplen is optional, but a good idea if you want
   snort to undertand more then just ip headers.

* Also some changes to the parser to allow plain experiments to take
  advantage of all this stuff. To simple get yourself a per-experiment
  DB, put this in your NS file:

	tb-set-dpdb 1

  however, anytime you turn trace_db on for a link or lan, you
  automatically get a per-experiment DB.

* To capture the trace data to the DB, you can run loghole by hand:

	loghole sync -s

  the -s option turns on the "post-process" phase of loghole.
parent 112d4c23
......@@ -123,6 +123,8 @@ sub noidleswap_reason($){ return field($_[0], 'noidleswap_reason');}
sub idleswap_timeout($) { return field($_[0], 'idleswap_timeout');}
sub autoswap_timeout($) { return field($_[0], 'autoswap_timeout');}
sub prerender_pid($) { return field($_[0], 'prerender_pid');}
sub dpdb($) { return field($_[0], 'dpdb');}
sub dpdbname($) { return field($_[0], 'dpdbname');}
#
# Lookup an experiment given an experiment index.
......
......@@ -175,7 +175,8 @@ my %experiment_fields = ("multiplex_factor" => 1,
"elabinelab_eid" => 1,
"elabinelab_cvstag" => 1,
"security_level" => 1,
"delay_capacity" => 1);
"delay_capacity" => 1,
"dpdb" => 1);
# New parsing code state machine control.
my $PARSING_NOTYET = 0;
......
......@@ -588,6 +588,7 @@ CREATE TABLE experiment_template_instances (
stop_time datetime default NULL,
runidx int(10) unsigned default NULL,
template_tag varchar(64) default NULL,
export_time datetime default NULL,
PRIMARY KEY (idx),
KEY exptidx (exptidx),
KEY parent_guid (parent_guid,parent_vers),
......@@ -2341,6 +2342,7 @@ CREATE TABLE traces (
trace_type tinytext,
trace_expr tinytext,
trace_snaplen int(11) NOT NULL default '0',
trace_db tinyint(1) NOT NULL default '0',
PRIMARY KEY (node_id,idx),
KEY pid (pid,eid)
) TYPE=MyISAM;
......@@ -2718,6 +2720,7 @@ CREATE TABLE virt_lans (
trace_expr tinytext,
trace_snaplen int(11) NOT NULL default '0',
trace_endnode tinyint(1) NOT NULL default '0',
trace_db tinyint(1) NOT NULL default '0',
KEY pid (pid,eid,vname),
KEY vnode (pid,eid,vnode)
) TYPE=MyISAM;
......
......@@ -620,6 +620,7 @@ REPLACE INTO table_regex VALUES ('virt_lans','trace_type','text','regex','^(head
REPLACE INTO table_regex VALUES ('virt_lans','trace_expr','text','redirect','default:text',1,255,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_snaplen','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_endnode','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_db','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','vname','text','redirect','virt_nodes:vname',0,0,NULL);
......@@ -700,6 +701,7 @@ REPLACE INTO table_regex VALUES ('experiments','autoswap_timeout','int','redirec
REPLACE INTO table_regex VALUES ('virt_lans','protocol','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','is_accesspoint','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','linktest_level','int','redirect','default:tinyint',0,4,NULL);
REPLACE INTO table_regex VALUES ('experiments','dpdb','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','vname','text','redirect','virt_lans:vname',0,0,NULL);
......
......@@ -3571,3 +3571,18 @@ last_net_act,last_cpu_act,last_ext_act);
alter table experiment_templates add \
child_vers smallint(5) unsigned default NULL after child_guid;
4.78: Add trace_db flags to virt_lans and traces tables.
alter table virt_lans add \
trace_db tinyint(1) NOT NULL default '0';
alter table traces add \
trace_db tinyint(1) NOT NULL default '0';
**** Skip this stuff below if you just did 4.41 above.
Add timestamp the experiment_template_instances to note when the
last export was done.
alter table experiment_template_instances add \
export_time datetime default NULL;
......@@ -294,6 +294,8 @@ CREATE TABLE experiment_template_instances (
runidx int(10) unsigned default NULL,
-- The tag for the template at the time of instantiation.
template_tag varchar(64) default NULL,
-- Date of last export.
export_time datetime default NULL,
PRIMARY KEY (idx),
KEY (exptidx),
KEY (parent_guid,parent_vers),
......
......@@ -24,7 +24,8 @@ BIN_STUFF = power snmpit tbend tbprerun tbreport \
node_attributes archive_control template_create \
template_swapin template_swapout template_graph \
template_exprun template_delete template_metadata \
template_export template_control template_commit
template_export template_control template_commit \
template_analyze
SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
batch_daemon exports_setup reload_daemon sched_reserve \
......@@ -55,7 +56,7 @@ LIBEXEC_STUFF = rmproj wanlinksolve wanlinkinfo \
webnodeattributes webarchive_control webtemplate_create \
webtemplate_swapin webtemplate_swapout webtemplate_exprun \
webtemplate_graph webtemplate_metadata webtemplate_export \
webtemplate_control webtemplate_commit
webtemplate_control webtemplate_commit webtemplate_analyze
LIB_STUFF = libtbsetup.pm exitonwarn.pm libtestbed.pm snmpit_intel.pm \
snmpit_cisco.pm snmpit_lib.pm snmpit_apc.pm power_rpc27.pm \
......
......@@ -2283,6 +2283,26 @@ sub CopyDataStore($$$)
return 0;
}
#
# Update the export time.
#
sub UpdateExportTime($)
{
my ($self) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $idx = $self->idx();
DBQueryWarn("update experiment_template_instances set export_time=now() ".
"where idx='$idx'")
or return -1;
return Refresh($self);
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -3345,7 +3345,8 @@ sub SetUpTracing($$$$$)
#
# First see if this member of the lan wanted tracing.
#
my ($traced, $endnode, $trace_type, $trace_expr, $trace_snaplen) =
my ($traced, $endnode, $trace_type, $trace_expr,
$trace_snaplen, $trace_db) =
virtlantraceinfo($lan, $member);
return
......@@ -3362,11 +3363,12 @@ sub SetUpTracing($$$$$)
DBQueryFatal("insert into traces ".
" (node_id, idx, iface0, iface1, pid, eid, linkvname, ".
" vnode, trace_type, trace_expr, trace_snaplen) ".
" vnode, trace_type, trace_expr, trace_snaplen, trace_db) ".
"values ".
" ('$pnode', 0, '$iface0', '$iface1', '$pid', '$eid', ".
" '$lan', '$vnode', ".
" '$trace_type', '$trace_expr', $trace_snaplen)");
" '$trace_type', '$trace_expr', $trace_snaplen, ".
" '$trace_db')");
}
#
......@@ -4083,6 +4085,7 @@ sub LoadVirtLans()
$rowref->{"trace_type"},
$rowref->{"trace_expr"},
$rowref->{"trace_snaplen"},
$rowref->{"trace_db"},
];
#
......
......@@ -58,7 +58,7 @@ sub CheckCopyArgs();
sub CopyInArchive();
sub fatal($);
my $optlist = "iE:g:e:p:S:L:a:l:sfwqt:nzc:bx:y:m"; # Enough options?
my $optlist = "iE:g:e:p:S:L:a:l:sfwqt:nzc:bx:y:"; # Enough options?
my $batchmode= 1;
my $frontend = 0;
my $waitmode = 0;
......@@ -70,7 +70,6 @@ my $savestate= 0;
my $template_mode = 0; # New stuff; experiment templates.
my $instance_idx = 0; # New stuff; experiment templates.
my $archive_eid; # New stuff; experiment templates.
my $dpdb = 0; # A per-experiment DB on ops.
# All of these are for experiment dup and branch. Really mucks things up.
# These globals are set when we parse the -c argument, but used later
my $copybranch = 0; # A branch instead of a duplicate
......@@ -298,7 +297,6 @@ $args{'batchstate'} = $batchstate;
$args{'linktest_level'} = $linktest;
$args{'savedisk'} = $savestate;
$args{'instance_idx'} = $instance_idx;
$args{'dpdb'} = $dpdb;
# These are special; the library will DBQuote them.
$args{'expt_name'} = $description;
$args{'noswap_reason'} = $noswap_reason;
......@@ -948,9 +946,6 @@ sub ParseArgs()
if (defined($options{"q"})) {
$quiet = 1;
}
if (defined($options{"m"})) {
$dpdb = 1;
}
if (defined($options{"z"})) {
$zeemode = 1;
$zeeopt = "-p";
......
......@@ -65,6 +65,7 @@ Queue instproc init {link type node} {
$self set trace_expr {}
$self set trace_snaplen 0
$self set trace_endnode 0
$self set trace_mysql 0
#
# These are NS variables for queues (with NS defaults).
......@@ -332,6 +333,35 @@ Link instproc trace_snaplen {len} {
$fromqueue set trace_snaplen $len
}
Lan instproc trace_mysql {onoff} {
var_import ::GLOBALS::dpdb
$self instvar nodelist
$self instvar linkq
foreach nodeport $nodelist {
set linkqueue $linkq($nodeport)
$linkqueue set trace_mysql $onoff
}
if {$onoff} {
set dpdb 1
}
}
Link instproc trace_mysql {onoff} {
var_import ::GLOBALS::dpdb
$self instvar toqueue
$self instvar fromqueue
$toqueue set trace_mysql $onoff
$fromqueue set trace_mysql $onoff
if {$onoff} {
set dpdb 1
}
}
Lan instproc trace_endnode {onoff} {
$self instvar nodelist
$self instvar linkq
......@@ -723,6 +753,7 @@ Link instproc updatedb {DB} {
lappend fields "trace_expr"
lappend fields "trace_snaplen"
lappend fields "trace_endnode"
lappend fields "trace_db"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $encap $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $node $port $ip $mustdelay]
......@@ -742,6 +773,7 @@ Link instproc updatedb {DB} {
lappend values [$linkqueue set trace_expr]
lappend values [$linkqueue set trace_snaplen]
lappend values [$linkqueue set trace_endnode]
lappend values [$linkqueue set trace_mysql]
}
$sim spitxml_data "virt_lans" $fields $values
......@@ -870,6 +902,7 @@ Lan instproc updatedb {DB} {
lappend fields "trace_expr"
lappend fields "trace_snaplen"
lappend fields "trace_endnode"
lappend fields "trace_db"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $encap $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $protocol $is_accesspoint $node $port $ip $mustdelay]
......@@ -889,6 +922,7 @@ Lan instproc updatedb {DB} {
lappend values [$linkqueue set trace_expr]
lappend values [$linkqueue set trace_snaplen]
lappend values [$linkqueue set trace_endnode]
lappend values [$linkqueue set trace_mysql]
}
$sim spitxml_data "virt_lans" $fields $values
......
......@@ -266,6 +266,9 @@ namespace eval GLOBALS {
variable elabinelab_eid {}
variable elabinelab_cvstag {}
# Does user want a per-experiment DB?
variable dpdb 0
# Security level. Defaults to 0 ("green")
# If explicit_firewall is set, then you cannot also give a security level.
# security_level_diskzap is the level at which we need to zap the disk
......
......@@ -397,6 +397,7 @@ Simulator instproc run {} {
var_import ::GLOBALS::sourcefile_list
var_import ::GLOBALS::optarray_order
var_import ::GLOBALS::optarray_count
var_import ::GLOBALS::dpdb
if {$ran == 1} {
perror "The Simulator 'run' statement can only be run once."
......@@ -637,6 +638,11 @@ Simulator instproc run {} {
lappend fields "security_level"
lappend values $security_level
}
if {$dpdb} {
lappend fields "dpdb"
lappend values $dpdb
}
$self spitxml_data "experiments" $fields $values
......
......@@ -1533,6 +1533,19 @@ proc tb-elab-in-elab {onoff} {
set elab_in_elab 0
}
}
#
# Mark this experiment as needing a per-experiment DB on ops.
#
proc tb-set-dpdb {onoff} {
var_import ::GLOBALS::dpdb
if {$onoff} {
set dpdb 1
} else {
set dpdb 0
}
}
#
# Change the default topography.
#
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use strict;
use Getopt::Std;
use POSIX qw(isatty setsid);
use POSIX qw(strftime);
use Errno qw(EDQUOT);
use Data::Dumper;
#
# Setup analysis of a template record.
#
# Exit codes are important; they tell the web page what has happened so
# it can say something useful to the user. Fatal errors are mostly done
# with die(), but expected errors use this routine. At some point we will
# use the DB to communicate the actual error.
#
# $status < 0 - Fatal error. Something went wrong we did not expect.
# $status = 0 - Everything okay.
# $status > 0 - Expected error. User not allowed for some reason.
#
sub usage()
{
print(STDERR
"Usage: template_export [-q] [-s] -i <exptidx> <guid/vers>\n".
"switches and arguments:\n".
"-q - be less chatty\n".
"-i <exptidx> - Experiment index to work on\n".
"<guid/vers> - GUID and version\n");
exit(-1);
}
my $optlist = "qi:d";
my %options = ();
my $quiet = 0;
my $debug = 0;
my $eid;
my $exptidx;
my $guid;
my $version;
#
# Configure variables
#
my $TB = "@prefix@";
my $EVENTSYS = @EVENTSYS@;
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $TBDOCBASE = "@TBDOCBASE@";
my $TBBASE = "@TBBASE@";
my $CONTROL = "@USERNODE@";
my $checkquota = "$TB/sbin/checkquota";
my $dbcontrol = "$TB/sbin/opsdb_control";
# Locals
my $dbuid;
my $template;
my $instance;
my $archive_tag;
# Protos
sub ParseArgs();
sub fatal($$);
sub cleanup();
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use libaudit;
use libtblog;
use Template;
# In libdb
my $projroot = PROJROOT();
#
# Turn off line buffering on output
#
$| = 1;
#
# Set umask for start/swap. We want other members in the project to be
# able to swap/end experiments, so the log and intermediate files need
# to be 664 since some are opened for append.
#
umask(0002);
#
# Untaint the path
#
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Verify user and get his DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
tbdie("You do not exist in the Emulab Database!");
}
# Now parse arguments.
ParseArgs();
# Temporary
libArchive::setdebug($debug);
#
# Grab template info and do access check.
#
$template = Template->Lookup($guid, $version);
if (!defined($template)) {
tbdie("Experiment template $guid/$version does not exist!");
}
if (! TBProjAccessCheck($dbuid,
$template->pid(), $template->gid(),
TB_PROJECT_READINFO)) {
tberror("You do not have permission to export template $guid/$version");
exit(1);
}
my $pid = $template->pid();
my $gid = $template->gid();
$instance = Template::Instance->LookupByExptidx($exptidx);
if (!defined($instance)) {
fatal(-1, "Could not get instance record for experiment $exptidx!");
}
if ($instance->ArchiveTag(\$archive_tag) < 0) {
fatal(-1, "Could not get current archive tag for instance $exptidx!");
}
if (system("$checkquota $dbuid") != 0) {
tberror("You are over your disk quota on $CONTROL; please cleanup!");
exit(1);
}
# Get the the runs.
my %runlist;
$instance->RunList(\%runlist) == 0
or fatal(-1, "Could not get runlist for $instance");
#
# It is an error to analyze an instance with no runs; it sorta implies
# the the initial run is still active.
#
if (! keys(%runlist)) {
tberror("There are no experiment runs in instance $instance!");
exit(1);
}
#
# Checkout to the project tree.
#
my $checkout = "$projroot/$pid/export/$guid/$version/$exptidx";
# Cleanup existing goo.
if (-e $checkout) {
system("/bin/rm -rf $checkout");
}
system("mkdir -p $checkout") == 0
or fatal(-1, "Could not mkdir $checkout");
# Use the logonly option to audit so that we get a record mailed.
LogStart(0);
#
# Now dump a checkout of the dbdata directory for each run, in its own
# directory.
#
foreach my $name (keys(%runlist)) {
my $rowref = $runlist{$name};
my $runidx = $rowref->{"idx"};
my $dir = "$checkout/run${runidx}";
my $subdir = "archive/dbdata";
my $tag = $rowref->{"archive_tag"};
my $dbdump = "$dir/dbdump.gz";
# This could happen if template is still instantiated (last run).
next
if (!defined($tag) || $tag eq "");
system("mkdir -p $dir") == 0
or fatal(-1, "Could not mkdir $dir");
print "Checking out files from archive using tag $tag ...\n";
libArchive::TBCheckoutExperimentArchivebyExptIDX($exptidx, $dir,
$tag, $subdir) == 0 or
fatal(-1, "Could not checkout $tag to $dir");
#
# Now we need to create a DB on ops to hold the DB dump.
#
my $dbname = "${guid},${version}," . $instance->idx() . ",$runidx";
if (system("$dbcontrol deltempdb $dbname")) {
fatal(-1, "$dbcontrol deltempdb failed!");
}
if (system("$dbcontrol addtempdb $pid $gid $dbname")) {
fatal(-1, "$dbcontrol addtempdb failed!");
}
#
# Load it up.
#
if (system("$dbcontrol loadtempdb $dbname $dbdump")) {
fatal(-1, "$dbcontrol loadtempdb failed!");
}
}
LogEnd();
exit(0);
#
# Parse command arguments. Once we return from getopts, all that are
# left are the required arguments.
#
sub ParseArgs()
{
if (! getopts($optlist, \%options)) {
usage();
}
if (@ARGV != 1) {
usage();
}
#
# Pick up guid/version first and untaint.
#
my $tmp = shift(@ARGV);
if ($tmp =~ /^([\w]*)\/([\d]*)$/) {
$guid = $1;
$version = $2;
}
else {
tbdie("Bad data in argument: $tmp");
}
if (defined($options{"i"})) {
$exptidx = $options{"i"};
if (! TBcheck_dbslot($exptidx, "default", "int",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper experiment index!");
}
# real check.
if ($exptidx =~ /^([\w]*)$/) {
$exptidx = $1;
}
else {
tbdie("Bad data in argument: $exptidx");
}
}
else {
tbdie("You must supply the -i option!");
}
if (defined($options{"q"})) {
$quiet = 1;
}
if (defined($options{"d"})) {
$debug = 2;
}
}
#
# Cleanup the mess.
#
sub cleanup()
{
if (defined($checkout) && -e $checkout) {
system("/bin/rm -rf $checkout");
}
}
sub fatal($$)
{
my ($errorstat, $msg) = @_;
tberror $msg;
tbinfo "Cleaning up and exiting with status $errorstat ...";
exit($errorstat);
}
......@@ -278,6 +278,11 @@ else {
}
}
#
# Note the time this export was done.
#
$instance->UpdateExportTime();
if ($spew) {
system("$TAR zcf - -C $checkout .");
cleanup();
......
......@@ -72,6 +72,7 @@ my $TBDOCBASE = "@TBDOCBASE@";
my $TBBASE = "@TBBASE@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $OPSDBSUPPORT= @OPSDBSUPPORT@;
# Locals
my $user_name;
......@@ -94,6 +95,7 @@ my $checkquota = "$TB/sbin/checkquota";
my $batchexp = "$TB/bin/batchexp";
my $swapexp = "$TB/bin/swapexp";
my $endexp = "$TB/bin/endexp";
my $dbcontrol = "$TB/sbin/opsdb_control";
# Protos
sub ParseArgs();
......@@ -109,6 +111,7 @@ use libdb;
use libtestbed;
use libtblog;
use Template;
use Experiment;
use event;
# Be careful not to exit on transient error
......@@ -272,7 +275,7 @@ my $copyid = $template->pid() . "," . $template->eid();
#
my @arguments =
($batchexp, "-x", $template->eid(), "-y", $instance->idx(), "-q", "-f",
"-m", "-p", $pid, "-e", $eid, "-g", $template->gid(),
"-p", $pid, "-e", $eid, "-g", $template->gid(),
"-E", "'Experiment Template Instantiation $guid/$version' ",
"-c" , $copyid);
......@@ -302,8 +305,28 @@ fatal($? >> 8, "Could not pre-instantiate the experiment")
# Need to kill the experiment if we fail after this point.
$exptcreated = 1;
if (! TBExptIDX($pid, $eid, \$exptidx)) {
fatal(-1, "Could not get experiment index for $pid,$eid!");
# Grab the experiment record for below.
my $experiment = Experiment->Lookup($pid, $eid);
if (!defined($experiment)) {
fatal(-1, "Experiment $pid/$eid could not be found after creation!");
}
$exptidx = $experiment->idx();
#
# Templates always get a DB; override the NS file setting of dpdb, and
# then call out to have it created.
#
if ($OPSDBSUPPORT) {
my %args = ();
$args{'dpdb'} = 1;
$experiment->Update(\%args) == 0
or fatal(-1, "Could not update experiment record!");
if (system("$dbcontrol addexpdb $pid $eid")) {
fatal(-1, "$dbcontrol addexpdb failed!");
}
}
#
......@@ -327,8 +350,8 @@ $instance->Update(0, \%args) == 0
# Event connect now that experiment is created.
SetupEventHandler();
my $workdir = TBExptWorkDir($pid, $eid);
my $userdir = TBExptUserDir($pid, $eid);
my $workdir = $experiment->WorkDir();
my $userdir = $experiment->UserDir();
#
# Now we stash the parameter file.
......@@ -441,7 +464,7 @@ foreach my $name (keys(%parameters)) {
# exp directory. Anyway, once that is done, add an environment
# variable the user can reference for finding files in the datastore.
#
my $instance_path = TBExptUserDir($pid, $eid);
my $instance_path = $userdir;
$instance->CopyDataStore($template_tag,
"$instance_path/template_datastore") == 0
or fatal(-1, "Could not copy datastore ($template_tag) to instance");
......
......@@ -72,6 +72,7 @@ my $TBDOCBASE = "@TBDOCBASE@";
my $TBBASE = "@TBBASE@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $OPSDBSUPPORT= @OPSDBSUPPORT@;
# Locals
my $user_name;
......@@ -94,6 +95,7 @@ my $checkquota = "$TB/sbin/checkquota";
my $batchexp = "$TB/bin/batchexp";
my $swapexp = "$TB/bin/swapexp";
my $endexp = "$TB/bin/endexp";
my $dbcontrol = "$TB/sbin/opsdb_control";
# Protos
sub ParseArgs();
......@@ -109,6 +111,7 @@ use libdb;
use libtestbed;
use libtblog;
use Template;
use Experiment;