Commit 5a4e9df8 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Okay, here is the current development approach for dealing with

ElabinElab experiments that wrap another experiment, either firewalled
or not. This instead of my security level stuff, that I decided was
too much of a pain the user, at least for now. New NS syntax:

	tb-set-inner-elab-eid two-simple

In the ElabinElab file, sets the name of an existing experiment in the
same project. Experiment is parsed, and after the parse we notice in
tbprerun that we have an inner eid, so we reparse the NS file, only
this time we pass in the maximum number of nodes needed by the inner
eid (tbprerun now computes min/max nodes at prerun time, instead of
later as first part of swapin). This number is used to allocatethe
appropriate number of inner experimental nodes. Why do it this way?
Cause the NS parser is the only tool we have for generating the virt
topology, and I do not want go down the path of inventing a new
frontend.

Anyway, after the reparse, we now have the proper number of nodes in
the wrapper experiment. Now its simply a matter of copying over the
type and fixnode info from the inner experiment to the outer
experiment.  Why? So that when the outer experiment is swapped in, it
gets the nodes (of the right type/fixnode) that the inner experiment
is going to want later, when it is swapped in by the inner emulab!

Another approach would be to make elabinelab and elabinelab_eid
options to batchexp (and thus the web form and XMLRPC interface) so
that we can avoid the double parse. I suspect people do not want more
crap on the web form, so I did not do it this way.
parent 12c44d00
......@@ -462,6 +462,28 @@ sub GenDefsFile($)
print TCL "set physnodes($node_id) \"$type\"\n";
}
#
# ElabInElab stuff.
#
my $maxnodes = 0;
if (defined($pid)) {
my $elabinelab = 0;
my $elabinelab_eid;
TBExptIsElabInElab($pid, $eid, \$elabinelab, \$elabinelab_eid)
or die("*** $0:\n".
" Failed to get ElabInElab attributes!");
if ($elabinelab && defined($elabinelab_eid)) {
if (! TBExptMinMaxNodes($pid, $elabinelab_eid, undef, \$maxnodes)) {
die("*** $0:\n".
" Could not get max nodes from DB!");
}
}
}
# Be sure to initialize this to something ...
print TCL "set elabinelab_maxpcs $maxnodes\n";
print TCL "}\n";
close(TCL);
}
......@@ -139,6 +139,9 @@ namespace eval TBCOMPAT {
# Experiment directory name.
variable expdir
# ElabInElab stuff. Do not initialize.
variable elabinelab_maxpcs
# Mapping of "resource classes" and "reservation types" to bootstrap
# values, where a resource class is a symbolic string provided by the user
# (e.g. Client, Server), and a reservation type is a resource name provided
......
......@@ -141,6 +141,39 @@ if (system("parse-ns $pid $gid $eid $nsfile")) {
TBDebugTimeStamp("parser finished");
print "Parser done! " . TBTimeStamp() . "\n";
#
# Need to know if wrapping an experiment.
#
my $elabinelab = 0;
my $elabinelab_eid;
TBExptIsElabInElab($pid, $eid, \$elabinelab, \$elabinelab_eid)
or fatal("Failed to get ElabInElab attributes!");
#
# If we are, and there is an inner experiment, rerun the parser so that
# we can pass in the proper info this time around. This is a side effect
# of allowing the elabinelab bit, and the elabinelab eid, to be specified
# in the NS file. If we did this on the command line, then we could skip
# this step, but I think ease of use is better if it can be in the NS file.
#
if ($elabinelab && defined($elabinelab_eid)) {
# Inner experiment better exist.
fatal("Inner experiment $elabinelab_eid does not exist!")
if (! ExpState($pid, $elabinelab_eid));
# Again, kill virtual state.
TBExptRemoveVirtualState($pid, $eid);
print "Re-Running parser ... " . TBTimeStamp() . "\n";
TBDebugTimeStamp("parser started");
if (system("parse-ns $pid $gid $eid $nsfile")) {
fatal("Parsing failed!");
}
TBDebugTimeStamp("parser finished");
print "Parser done! " . TBTimeStamp() . "\n";
}
#
# Put the nsfile into the DB, now that we know it parses okay.
#
......@@ -289,6 +322,49 @@ if ($security_level >= TBDB_SECLEVEL_ORANGE()) {
}
}
#
# If wrapping an experiment, copy over type/fixnode info to wrapper.
# We already made sure the experiment was created with enough nodes (see
# the parser) but now we have to make sure that the type/fixnode stuff will
# correspond to what the wrapped experiment really wants. It is a lot easier
# to do this here then in the parser.
#
if ($elabinelab && defined($elabinelab_eid)) {
my $outer_result;
my $inner_result;
my $maxnodes;
if (! ($inner_result =
DBQueryWarn("select type,fixed from virt_nodes ".
"where pid='$pid' and eid='$elabinelab_eid'"))) {
fatal("Could not get virt_node info for $pid/$elabinelab_eid!");
}
if (! ($outer_result =
DBQueryWarn("select vname from virt_nodes ".
"where pid='$pid' and eid='$eid' and ".
" inner_elab_role='node'"))) {
fatal("Could not get virt_node info for $pid/$eid!");
}
#
# Move over info for each real node in the inner experiment. Delay
# nodes will be extra nodes in the outer experiment, but those do
# not currently get type/fix info since the the user has no way to
# do that in the NS file.
#
while (my ($type,$fixed) = $inner_result->fetchrow_array()) {
my ($vname) = $outer_result->fetchrow_array();
fatal("Not enough nodes in outer experiment!")
if (!defined($vname));
DBQueryWarn("update virt_nodes set ".
" type='$type',fixed='$fixed' ".
"where pid='$pid' and eid='$eid' and vname='$vname'")
or fatal("Could not get virt_node info for $pid/$eid!");
}
}
#
# This stats stuff is not done in testmode.
#
......@@ -298,13 +374,8 @@ if (! $TESTMODE) {
# Want to move this to the stats records. Ditto for the security stuff,
# which was handled above.
#
my $elabinelab = 0;
my $elabinelab_eid;
my $elabinelab_exptidx;
TBExptIsElabInElab($pid, $eid, \$elabinelab, \$elabinelab_eid)
or fatal("Failed to get ElabInElab attributes!");
if ($elabinelab || $security_level) {
DBQueryWarn("update experiment_stats set ".
" elabinelab=$elabinelab, ".
......
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