Commit 904d2b05 authored by Leigh Stoller's avatar Leigh Stoller

Another request fullfilled; allow templates to be instantiated but

not swapped in (equiv of plain experiment preload), and then swapped
in later. This fulfills flyspray request FS#100.
parent 2e2cfef9
......@@ -25,7 +25,7 @@ BIN_STUFF = power snmpit tbend tbprerun tbreport \
template_swapin template_swapout template_graph \
template_exprun template_delete template_metadata \
template_export template_control template_commit \
template_analyze template_linkgraph
template_analyze template_linkgraph template_instantiate
SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
batch_daemon exports_setup reload_daemon sched_reserve \
......@@ -59,7 +59,7 @@ LIBEXEC_STUFF = rmproj wanlinksolve wanlinkinfo \
webtemplate_swapin webtemplate_swapout webtemplate_exprun \
webtemplate_graph webtemplate_metadata webtemplate_export \
webtemplate_control webtemplate_commit webtemplate_analyze \
webtemplate_linkgraph
webtemplate_linkgraph webtemplate_instantiate
LIB_STUFF = libtbsetup.pm exitonwarn.pm libtestbed.pm snmpit_intel.pm \
snmpit_cisco.pm snmpit_lib.pm snmpit_apc.pm power_rpc27.pm \
......
......@@ -1246,7 +1246,7 @@ sub MetadataList($$)
#
sub NewInstance($$$)
{
my ($self, $eid, $creator) = @_;
my ($self, $eid, $creator, $description) = @_;
# Must be a real reference.
return undef
......@@ -1259,6 +1259,8 @@ sub NewInstance($$$)
$args{'pid'} = $self->pid();
$args{'eid'} = $eid;
$args{'uid'} = $creator;
$args{'description'} = $description
if (defined($description));
return Template::Instance->Create(\%args);
}
......@@ -1703,10 +1705,17 @@ sub LookupByExptidx($$)
sub Create($$)
{
my ($class, $argref) = @_;
my $description;
return undef
if (ref($class));
# must treat specially.
if (exists($argref->{'description'})) {
$description = DBQuoteSpecial($argref->{'description'});
delete($argref->{'description'});
}
my $query = "insert into experiment_template_instances set ".
join(",", map("$_='" . $argref->{$_} . "'", keys(%{$argref})));
......@@ -1714,6 +1723,8 @@ sub Create($$)
$query .= ", "
if (defined($argref) && scalar(keys%{$argref}));
$query .= "start_time=now(),continue_time=now() ";
$query .= ",description=$description"
if (defined($description));
my $query_result = DBQueryWarn($query);
return undef
......@@ -1741,6 +1752,7 @@ sub continue_time($) { return field($_[0], 'continue_time'); }
sub runtime($) { return field($_[0], 'runtime'); }
sub locked($) { return field($_[0], 'locked'); }
sub locker_pid($) { return field($_[0], 'locker_pid'); }
sub description($) { return field($_[0], 'description'); }
sub template($) { return ((!ref($_[0])) ? -1 : $_[0]->{'TEMPLATE'}); }
# The path is the path of the experiment.
......
......@@ -33,6 +33,7 @@ sub usage()
"-e <eid> <guid/vers>\n".
"switches and arguments:\n".
"-b - batchmode; insert into batch queue\n".
"-p - preload only; do not swapin\n".
"-w - wait for template to be instantiated\n".
"-q - be less chatty\n".
"-E <str> - A pithy sentence describing the instance\n".
......@@ -47,12 +48,13 @@ sub usage()
"<guid/vers> - GUID and version to swapin\n");
exit(-1);
}
my $optlist = "qwe:S:L:na:l:se:x:bE:t:r:f";
my $optlist = "qwe:S:L:na:l:se:x:bE:t:r:fp";
my %options = ();
my $quiet = 0;
my $waitmode = 0;
my $batchmode = 0;
my $foreground = 0;
my $preload = 0;
my $description;
my $paramfile;
my $guid;
......@@ -82,7 +84,6 @@ my $EVhandle;
my $exptidx;
my $template;
my $instance;
my $run;
my $logname;
my $template_tag;
my @ExptStates = ();
......@@ -99,7 +100,7 @@ my $replay_run; # Replay starting with a particular run in instance.
# Programs we need
my $checkquota = "$TB/sbin/checkquota";
my $batchexp = "$TB/bin/batchexp";
my $swapexp = "$TB/bin/swapexp";
my $swapin = "$TB/bin/template_swapin";
my $endexp = "$TB/bin/endexp";
my $dbcontrol = "$TB/sbin/opsdb_control";
my $archcontrol = "$TB/bin/archive_control";
......@@ -276,7 +277,7 @@ if (defined($paramfile)) {
# Generate a new template instance record.
# We will finish updating it later.
#
$instance = $template->NewInstance($eid, $dbuid);
$instance = $template->NewInstance($eid, $dbuid, $description);
if (!defined($instance)) {
fatal(-1, "Could not insert new experiment instance record!");
}
......@@ -508,9 +509,6 @@ $args{'template_tag'} = $template_tag;
$instance->Update(0, \%args) == 0
or fatal(-1, "Could not update experiment instance record!");
# Event connect now that experiment is created.
SetupEventHandler();
my $workdir = $experiment->WorkDir();
my $userdir = $experiment->UserDir();
......@@ -560,97 +558,26 @@ print "Writing program agent info ...\n";
$instance->WriteProgramAgents() == 0
or fatal(-1, "Could not write program agent info");
#
# Now do the swapin (or it gets queued if a batch experiment).
#
@arguments = ($swapexp, "-q", "-x", "-s", "in", $pid, $eid);
system(@arguments);
fatal($? >> 8, "Could not instantiate the experiment")
if ($?);
#
# We will spew forth info to the user each time the batch daemon tries to
# swap it in.
#
if ($batchmode) {
if (! $preload) {
#
# Spin waiting for the state to change in swapexp. We are waiting for
# it to swapin or go back to swapped.
# Now do the swapin (or it gets queued if a batch experiment).
#
my $queued = 0;
while (1) {
@ExptStates = ();
event_poll_blocking($EVhandle, 500);
next
if (! @ExptStates);
foreach my $state (@ExptStates) {
print "$state\n";
if ($state eq EXPTSTATE_ACTIVATING()) {
print "Experiment is starting a swapin attempt ...\n";
}
elsif ($state eq EXPTSTATE_ACTIVE()) {
print "Experiment swapped in!\n";
goto done;
}
elsif ($state eq EXPTSTATE_QUEUED()) {
# Failed to swapin; still queued in the batch system.
if (! $queued) {
print "Experiment has entered the batch system\n";
$queued = 1;
}
else {
print "Experiment swapin attempt failed.\n";
}
}
elsif ($state eq EXPTSTATE_SWAPPED()) {
# Dumped out of the batch system for some reason.
print "Experiment has been removed from the batch queue.\n";
#
# We are done; remove record of this attempt and exit.
#
fatal(1, "Experiment has been removed from the batch queue");
}
}
system("$swapin -w -f -e $eid $guid/$version");
if ($?) {
fatal(-1, "Could not swapin instance $instance!");
}
done:
}
#
# Lets commit the experiment archive now that it is active. The experiment is
# already running, but thats not a big deal.
#
system("$archcontrol -t instantiate commit $pid $eid");
if ($?) {
fatal(-1, "Could not commit archive!");
}
#
# All instances currently start with a default run.
#
$run = $instance->NewRun($eid, $description);
if (!defined($run)) {
fatal(-1, "Could not create new experiment run for $instance!");
}
#
# And the bindings for the default run ...
#
foreach my $name (keys(%parameters)) {
my $value = $parameters{$name};
$instance->NewRunBinding($name, $value) == 0
or fatal(-1, "Error inserting run binding into DB!");
else {
#
# Lets commit the experiment archive now. The experiment might already
# be running, but thats not a big deal.
#
system("$archcontrol -t instantiate commit $pid $eid");
if ($?) {
fatal(-1, "Could not commit archive!");
}
}
$instance->StartRun(Template::STARTRUN_FLAGS_FIRSTRUN()) == 0
or fatal(-1, "Could not update start time in instance record!");
# Stop the web interface from spewing.
TBExptCloseLogFile($pid, $eid)
if (defined($logname) && !$batchmode);
......@@ -712,6 +639,9 @@ sub ParseArgs()
if (defined($options{"f"})) {
$foreground = 1;
}
if (defined($options{"p"})) {
$preload = 1;
}
if (defined($options{"b"})) {
$batchmode = 1;
}
......@@ -786,7 +716,7 @@ sub ParseArgs()
if (defined($options{"E"})) {
if (! TBcheck_dbslot($options{"E"},
"experiment_templates", "description",
"experiment_template_instances", "description",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper template description!");
}
......@@ -809,54 +739,6 @@ sub ParseArgs()
}
}
#
# Subscribe to experiment state change events.
#
sub SetupEventHandler()
{
my $port = @BOSSEVENTPORT@;
my $URL = "elvin://localhost:$port";
# Connect to the event system, and subscribe the the events we want
$EVhandle = event_register($URL, 0);
if (!$EVhandle) {
tbdie("Unable to register with event system\n");
}
my $tuple = address_tuple_alloc();
if (!$tuple) {
tbdie("Could not allocate an address tuple\n");
}
%$tuple = ( objtype => libdb::TBDB_TBEVENT_EXPTSTATE(),
objname => "$pid/$eid",
expt => "$pid/$eid",
host => $BOSSNODE,
);
if (!event_subscribe($EVhandle, \&EventHandler, $tuple)) {
tbdie("Could not subscribe to events\n");
}
}
#
# Callback for above.
#
sub EventHandler($$$) {
my ($handle,$notification,undef) = @_;
my $objname = event_notification_get_objname($handle,$notification);
my $eventtype = event_notification_get_eventtype($handle,$notification);
print "$objname, $eventtype\n";
return
if ($objname ne "$pid/$eid");
push(@ExptStates, $eventtype);
}
#
# Cleanup the mess.
#
......
This diff is collapsed.
......@@ -336,7 +336,9 @@ if ($expstate) {
}
else {
if ($expstate == $TB_EXPTSTATE_SWAPPED) {
WRITESUBMENUBUTTON("Swap Experiment In",
WRITESUBMENUBUTTON(($instance ?
"Swap Instance In" :
"Swap Experiment In"),
"swapexp.php3?inout=in&pid=$exp_pid&eid=$exp_eid");
}
elseif ($expstate == $TB_EXPTSTATE_ACTIVE ||
......
......@@ -101,7 +101,7 @@ if (! TBExptAccessCheck($uid, $exp_pid, $exp_eid, $TB_EXPT_MODIFY)) {
# Template Instance Experiments get special treatment in this page.
$instance = TemplateInstance::LookupByExptidx($exptidx);
if ($instance && $inout != "out") {
if ($instance && ($inout != "out" && $inout != "in")) {
PAGEARGERROR("Invalid action for template instance");
}
......@@ -169,7 +169,7 @@ if (!$confirmed) {
echo "<font color=red><br>forcibly</br></font> ";
}
if ($instance) {
echo "terminate template instance";
echo "$action template instance";
}
else {
echo "$action experiment";
......@@ -236,7 +236,8 @@ if ($instance) {
$guid = $instance->guid();
$version = $instance->vers();
STARTBUSY("Terminating template instance!");
STARTBUSY(($inout == "out" ? "Terminating" : "Starting") .
" template instance!");
}
#
......@@ -256,7 +257,7 @@ $retval = SUEXEC($uid, "$exp_pid,$unix_gid",
($force ?
"webidleswap $args $exp_pid $exp_eid" :
($instance ?
"webtemplate_swapout -e $exp_eid $guid/$version" :
"webtemplate_swap$inout -e $exp_eid $guid/$version" :
"webswapexp -s $inout $exp_pid $exp_eid")),
SUEXEC_ACTION_IGNORE);
......
......@@ -269,6 +269,22 @@ function SPITFORM($template, $formfields, $parameters, $errors)
</td>
</tr>\n";
#
# Preload?
#
echo "<tr>
<td class='pad4' colspan=2>
<input type=checkbox name='formfields[preload]'
value='Yep'";
if (isset($formfields[preload]) &&
strcmp($formfields[preload], "Yep") == 0) {
echo " checked='1'";
}
echo ">\n";
echo "Do Not Swap In</td>
</tr>\n";
#
# Run linktest, and level.
#
......@@ -341,6 +357,7 @@ if (! $template->AccessCheck($uid, $TB_EXPT_UPDATE)) {
#
if (!isset($swapin)) {
$defaults[eid] = $template->tid();
$defaults[preload] = "no";
$defaults[exp_swappable] = "1";
$defaults[exp_noswap_reason] = "";
$defaults[exp_idleswap] = "1";
......@@ -624,6 +641,13 @@ if (isset($formfields[batched]) && $formfields[batched] == "Yep") {
$batchmode = 1;
}
#
# Preload?
#
if (isset($formfields[preload]) && $formfields[preload] == "Yep") {
$command_options .= " -p";
}
#
# LinkTest
#
......@@ -697,7 +721,8 @@ STARTBUSY("Starting template instantiation!");
# Run the backend script.
#
$retval = SUEXEC($uid, "$pid,$unix_gid",
"webtemplate_swapin $command_options -e $eid $guid/$version",
"webtemplate_instantiate ".
"$command_options -e $eid $guid/$version",
SUEXEC_ACTION_IGNORE);
CLEARBUSY();
......
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