showexp.php3 24.6 KB
Newer Older
Leigh Stoller's avatar
Leigh Stoller committed
1
<?php
Leigh Stoller's avatar
Leigh Stoller committed
2
#
3
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
23
#
Leigh Stoller's avatar
Leigh Stoller committed
24
include("defs.php3");
25
require("Sajax.php");
26
include("showstuff.php3");
27
include_once("node_defs.php");
Leigh Stoller's avatar
Leigh Stoller committed
28
include_once("template_defs.php");
29 30 31
chdir("apt");
include_once("instance_defs.php");
chdir("..");
32
sajax_init();
33
sajax_export("GetExpState", "Show", "ModifyAnno", "FreeNodeHtml");
Leigh Stoller's avatar
Leigh Stoller committed
34

35
#
36
# Only known and logged in users can look at experiments.
37
#
38 39 40 41
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();

Leigh Stoller's avatar
Leigh Stoller committed
42
#
Leigh Stoller's avatar
Leigh Stoller committed
43
# Verify page arguments.
44 45 46 47
#
$reqargs = RequiredPageArguments("experiment", PAGEARG_EXPERIMENT);
$optargs = OptionalPageArguments("sortby",     PAGEARG_STRING,
				 "showclass",  PAGEARG_STRING);
48

49
if (!isset($sortby)) {
50
    if ($experiment->pid() == $TBOPSPID)
51 52 53 54
	$sortby = "rsrvtime-down";
    else
	$sortby = "";
}
55 56
if (!isset($showclass))
     $showclass = null;
57

58 59 60 61
# Need these below.
$exp_eid = $eid = $experiment->eid();
$exp_pid = $pid = $experiment->pid();
$tag = "Experiment";
Leigh Stoller's avatar
Leigh Stoller committed
62

63
#
Leigh Stoller's avatar
Leigh Stoller committed
64
# Verify Permission.
65
#
66
if (!$experiment->AccessCheck($this_user, $TB_EXPT_READINFO)) {
Leigh Stoller's avatar
Leigh Stoller committed
67
    USERERROR("You do not have permission to view experiment $exp_eid!", 1);
Leigh Stoller's avatar
Leigh Stoller committed
68 69
}

70 71 72 73 74 75 76 77 78 79 80 81
# Template Instance Experiments get special treatment in this page.
$instance = NULL;
if ($EXPOSETEMPLATES) {
     $instance = TemplateInstance::LookupByExptidx($experiment->idx());

     if (! is_null($instance)) {
	 $tag = "Instance";
	 $guid = $instance->guid();
	 $vers = $instance->vers();
     }
}

82 83 84
#
# For the Sajax Interface
#
85 86 87
$USER_VIS_URL = "http://$USERNODE/exp-vis/$pid/$eid/";
$HAVE_USER_VIS = 0;
$whocares = null;
88
if ($EXP_VIS && CHECKURL($USER_VIS_URL, $whocares)) {
89 90 91
  $HAVE_USER_VIS = 1;
}

92 93
function FreeNodeHtml()
{
94 95 96
    global $this_user, $experiment;
    
    return ShowFreeNodes($this_user, $experiment->Group());
97 98
}

99 100
function GetExpState($a, $b)
{
101
    global $experiment;
102

103
    return $experiment->state();
104
}
105

106 107 108 109 110 111 112 113
function ModifyAnno($newtext)
{
    global $this_user, $instance;

    $instance->SetAnnotation($this_user, $newtext);
    return 0;
}

114
function Show($which, $arg1, $arg2)
115
{
116
    global $experiment, $instance, $uid, $TBSUEXEC_PATH, $TBADMINGROUP;
117
    global $USER_VIS_URL;
118 119
    $pid  = $experiment->pid();
    $eid  = $experiment->eid();
120 121 122 123
    $html = "";

    if ($which == "settings") {
	ob_start();
124
	$experiment->Show();
125 126 127
	$html = ob_get_contents();
	ob_end_clean();
    }
128 129 130 131 132 133 134 135
    if ($which == "anno") {
	if (isset($instance)) {
	    ob_start();
	    $instance->ShowAnnotation(1);
	    $html = ob_get_contents();
	    ob_end_clean();
	}
    }
136
    elseif ($which == "details") {
137
	$showevents = $arg1;
138 139 140 141 142
	$output = array();
	$retval = 0;
	$html   = "";

        # Show event summary and firewall info.
143
        $flags = ($showevents ? "-e -a" : "-b -e -f");
144 145

	$result = exec("$TBSUEXEC_PATH $uid $TBADMINGROUP ".
146
		       "webtbreport $flags $pid $eid",
147 148
		       $output, $retval);

149 150
	$html = "<pre><div align=left id=\"showexp_details\" ".
	    "class=\"showexp_codeblock\">";
151 152 153 154
	for ($i = 0; $i < count($output); $i++) {
	    $html .= htmlentities($output[$i]);
	    $html .= "\n";
	}
155 156
	$html .= "</div></pre>\n";

157 158 159 160 161 162
	$html .= "<button name=showevents type=button value=1";
	$html .= " onclick=\"ShowEvents();\">";
	$html .= "Show Events</button>\n";
	
	$html .= "&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ";

163 164
	$html .= "<button name=savedetails type=button value=1";
	$html .= " onclick=\"SaveDetails();\">";
165
	$html .= "Save to File</button>\n";
166
    }
167 168 169 170 171 172
    elseif ($which == "graphs") {
	$graphtype = $arg1;

	if (!isset($graphtype) || !$graphtype)
	    $graphtype = "pps";
	
173
	$exptidx = $experiment->idx();
174 175 176 177 178 179 180 181
	# Make the link unique to force reload on the client side.
	$now     = time();
	
	$html  = "";
	$html .= "<div style='display: block; overflow: auto; ".
	         "     position: relative; height: 450px; ".
	         "     width: 90%; border: 2px solid black;'>\n";
	$html .= "  <img border=0 ";
Leigh Stoller's avatar
Leigh Stoller committed
182
	$html .= "       src='linkgraph_image.php?instance=$exptidx";
183 184 185 186 187 188 189 190 191 192
	$html .= "&graphtype=$graphtype&now=$now'>\n";
	$html .= "</div>\n";

	$html .= "<button name=pps type=button value=1";
	$html .= " onclick=\"GraphChange('pps');\">";
	$html .= "Packets</button>\n";
	$html .= "<button name=bps type=button value=1";
	$html .= " onclick=\"GraphChange('bps');\">";
	$html .= "Bytes</button>\n";
    }
193
    elseif ($which == "vis") {
194 195 196
	$zoom   = $arg1;
	$detail = $arg2;
	
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
	if ($zoom == 0) {
            # Default is whatever we have; to avoid regen of the image.
	    $query_result =
		DBQueryFatal("select zoom,detail from vis_graphs ".
			     "where pid='$pid' and eid='$eid'");

	    if (mysql_num_rows($query_result)) {
		$row    = mysql_fetch_array($query_result);
		$zoom   = $row['zoom'];
		$detail = $row['detail'];
	    }
	    else {
		$zoom   = 1.15;
		$detail = 1;
	    }
	}
	else {
            # Sanity check but lets not worry about throwing an error.
	    if (!TBvalid_float($zoom))
		$zoom = 1.25;
	    if (!TBvalid_integer($detail))
		$detail = 1;
    	}

	$html = ShowVis($pid, $eid, $zoom, $detail);

	$zoomout = sprintf("%.2f", $zoom / 1.25);
	$zoomin  = sprintf("%.2f", $zoom * 1.25);

	$html .= "<button name=viszoomout type=button value=$zoomout";
	$html .= " onclick=\"VisChange('$zoomout', $detail);\">";
	$html .= "Zoom Out</button>\n";
	$html .= "<button name=viszoomin type=button value=$zoomin";
	$html .= " onclick=\"VisChange('$zoomin', $detail);\">";
	$html .= "Zoom In</button>\n";

	if ($detail) {
	    $html .= "<button name=hidedetail type=button value=0";
	    $html .= " onclick=\"VisChange('$zoom', 0);\">";
	    $html .= "Hide Details</button>\n";
	}
	else {
	    $html .= "<button name=showdetail type=button value=1";
	    $html .= " onclick=\"VisChange('$zoom', 1);\">";
	    $html .= "Show Details</button>\n";
	}
243 244 245 246
	$html .= "&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ";
	$html .= "<button name=fullscreenvis type=button value=1";
	$html .= " onclick=\"FullScreenVis();\">";
	$html .= "Full Screen</button>\n";
247 248
    }
    elseif ($which == "nsfile") {
249
	$nsdata = $experiment->NSFile();
250
	
251 252
	$html = "<pre><div align=left class=\"showexp_codeblock\">".
	    "$nsdata</div></pre>\n";
253 254 255 256 257

	$html .= "<button name=savens type=button value=1";
	$html .= " onclick=\"SaveNS();\">";
	$html .= "Save</button>\n";
    }
258 259
    elseif ($which == "uservis") {
	ob_start();
260
	$html .= "<iframe src=\"$USER_VIS_URL\" width=\"100%\" height=600 id=\"vis-iframe\"></iframe>";
261 262
	ob_end_clean();
    }
263 264 265 266 267 268 269 270
    return $html;
}

#
# Dump the visualization into its own iframe.
#
function ShowVis($pid, $eid, $zoom = 1.25, $detail = 1) {
    $html = "<div id=fee style='display: block; overflow: hidden; ".
271
	    "     position: relative; z-index:1010; height: 450px; ".
272
	    "     width: 90%; border: 2px solid black;'>\n".
273
            " <div id=myvisdiv style='position:relative;'>\n".
274
	    "   <img id=myvisimg border=0 style='cursor: move;' ".
275 276 277 278 279 280 281 282 283
	    "        onLoad=\"setTimeout('ShowVisInit();', 10);\" ".
	    "        src='top2image.php3?pid=$pid&eid=$eid".
	    "&zoom=$zoom&detail=$detail'>\n".
	    " </div>\n".
	    "</div>\n";

    return $html;
}

284 285 286 287 288 289 290
#
# See if this request is to the above function. Does not return
# if it is. Otherwise return and continue on.
#
sajax_handle_client_request();

# Faster to do this after the sajax stuff
291
include_once("template_defs.php");
292

293 294 295
#
# Need some DB info.
#
296 297 298 299 300 301 302
$expindex   = $experiment->idx();
$expstate   = $experiment->state();
$isbatch    = $experiment->batchmode();
$linktest_running = $experiment->linktest_pid();
$paniced    = $experiment->paniced();
$panic_date = $experiment->panic_date();
$lockdown   = $experiment->lockdown();
303
$geniflags  = $experiment->geniflags();
Leigh Stoller's avatar
Leigh Stoller committed
304 305 306 307

if (! ($experiment_stats = $experiment->GetStats())) {
    TBERROR("Could not get experiment stats object for $expindex", 1);
}
308
$rsrcidx    = $experiment_stats->rsrcidx();
Leigh Stoller's avatar
Leigh Stoller committed
309 310 311
if (! ($experiment_resources = $experiment->GetResources())) {
    TBERROR("Could not get experiment resources object for $expindex", 1);
}
312
$wireless   = $experiment_resources->wirelesslans();
313

314 315 316 317 318
#
# Standard Testbed Header.
#
PAGEHEADER("$tag ($pid/$eid)");

319 320 321 322 323 324 325
echo "<script type='text/javascript' src='showexp.js'></script>\n";
#
# This has to happen ...
#
$bodyclosestring = "<script type='text/javascript'>SET_DHTML();</script>\n";

echo "<script type='text/javascript' src='js/wz_dragdrop.js'></script>";
326 327 328 329 330
echo "<script type='text/javascript' language='javascript'>\n";
sajax_show_javascript();
echo "StartStateChangeWatch('$pid', '$eid', '$expstate');\n";
echo "</script>\n";

331 332 333 334
#
# Get a list of node types and classes in this experiment
#
$query_result =
335 336 337 338 339 340 341
    DBQueryFatal("select distinct v.type,t1.class,v.fixed,".
		 "   t2.type as ftype,t2.class as fclass from virt_nodes as v ".
		 "left join node_types as t1 on v.type=t1.type ".
		 "left join nodes as n on v.fixed is not null and ".
		 "     v.fixed=n.node_id ".
		 "left join node_types as t2 on t2.type=n.type ".
		 "where v.eid='$eid' and v.pid='$pid'");
342
while ($row = mysql_fetch_array($query_result)) {
343 344 345 346 347 348 349 350
    if (isset($row['ftype'])) {
	$classes[$row['fclass']] = 1;
	$types[$row['ftype']] = 1;
    }
    else {
	$classes[$row['class']] = 1;
	$types[$row['type']] = 1;
    }
351 352
}

353 354 355 356 357
if ($geniflags) {
    # We would not see this unless it was an active experiment.
    $aptinstance = Instance::LookupBySlice($experiment_stats->slice_uuid());
}

358
SUBPAGESTART();
359

360
SUBMENUSTART("$tag Options");
361

362 363 364 365 366 367
if (isset($aptinstance)) {
    WRITESUBMENUBUTTON("Go to Portal Page",
                       "$TBBASE/portal/status.php?uuid=" .
                       $aptinstance->uuid());
}
else {
368
if ($expstate && !$geniflags) {
369
    if ($experiment->logfile() && $experiment->logfile() != "") {
370
	WRITESUBMENUBUTTON("View Activity Logfile",
371
			   CreateURL("showlogfile", $experiment));
372
    }
373 374
    WRITESUBMENUDIVIDER();

375 376 377 378 379
    if (!$lockdown) {
        # Swap option.
	if ($isbatch) {
	    if ($expstate == $TB_EXPTSTATE_SWAPPED) {
		WRITESUBMENUBUTTON("Queue Batch Experiment",
380 381
				   CreateURL("swapexp", $experiment,
					     "inout", "in"));
382 383 384 385
	    }
	    elseif ($expstate == $TB_EXPTSTATE_ACTIVE ||
		    $expstate == $TB_EXPTSTATE_ACTIVATING) {
		WRITESUBMENUBUTTON("Stop Batch Experiment",
386 387
				   CreateURL("swapexp", $experiment,
					     "inout", "out"));
388 389 390
	    }
	    elseif ($expstate == $TB_EXPTSTATE_QUEUED) {
		WRITESUBMENUBUTTON("Dequeue Batch Experiment",
391 392
				   CreateURL("swapexp", $experiment,
					     "inout", "pause"));
393
	    }
394
	}
395
	else {
396
	    if (!$geniflags && $expstate == $TB_EXPTSTATE_SWAPPED) {
397 398 399
		WRITESUBMENUBUTTON(($instance ?
				    "Swap Instance In" :
				    "Swap Experiment In"),
400 401
				   CreateURL("swapexp", $experiment,
					     "inout", "in"));
402 403 404
	    }
	    elseif ($expstate == $TB_EXPTSTATE_ACTIVE ||
		    ($expstate == $TB_EXPTSTATE_PANICED && $isadmin)) {
405
		WRITESUBMENUBUTTON(($instance ?
406 407
				    "Terminate Instance" :
				    "Swap Experiment Out"),
408 409
				   CreateURL("swapexp", $experiment,
					     "inout", "out"));
410
	    }
411
	    elseif (!$geniflags && $expstate == $TB_EXPTSTATE_ACTIVATING) {
412 413 414
		WRITESUBMENUBUTTON(($instance ?
				   "Cancel Template Instantiation" :
  				   "Cancel Experiment Swapin"),
415 416
				   CreateURL("swapexp", $experiment,
					     "inout", "out"));
417
	    }
418
	}
419
    
420
	if (!$instance && !$geniflags && $expstate != $TB_EXPTSTATE_PANICED) {
421
	    WRITESUBMENUBUTTON("Terminate Experiment",
422
			       CreateURL("endexp", $experiment));
423
	}
424 425
	elseif ($instance && $expstate == $TB_EXPTSTATE_SWAPPED) {
	    WRITESUBMENUBUTTON("Terminate Instance",
426
			       CreateURL("endexp", $experiment));
427
	}
428

429
        # Batch experiments can be modifed only when paused.
430 431
	if (!$geniflags &&
	    !$instance && ($expstate == $TB_EXPTSTATE_SWAPPED ||
432
	    (!$isbatch && $expstate == $TB_EXPTSTATE_ACTIVE))) {
433
	    WRITESUBMENUBUTTON("Modify Experiment",
434
			       CreateURL("modifyexp", $experiment));
435
	}
436
    }
437

438
    if ($instance && $expstate == $TB_EXPTSTATE_ACTIVE) {
439
	if ($instance->runidx()) {
440
	    WRITESUBMENUBUTTON("Stop Current Run",
441 442
			       CreateURL("template_exprun", $instance,
					 "action", "stop"));
443
	    WRITESUBMENUBUTTON("Abort Current Run",
444 445
			       CreateURL("template_exprun", $instance,
					 "action", "abort"));
446
	}
447 448 449
	#WRITESUBMENUBUTTON("Modify Resources",
	#		   CreateURL("template_exprun", $instance,
	#			     "action", "modify"));
450

451
	WRITESUBMENUBUTTON("Start New Run",
452 453
			   CreateURL("template_exprun", $instance,
				     "action", "start"));
454

455 456
	if ($instance->pause_time()) {
	    WRITESUBMENUBUTTON("Continue Experiment RunTime",
457 458
			       CreateURL("template_exprun", $instance,
					 "action", "continue"));
459 460
	}
	else {
461
	    WRITESUBMENUBUTTON("Pause Runtime",
462 463
			       CreateURL("template_exprun", $instance,
					 "action", "pause"));
464 465
	}

466
	WRITESUBMENUBUTTON("Create New Template",
467
			   CreateURL("template_commit", $instance));
468
    }
469
    
470
    if (!$geniflags && $expstate == $TB_EXPTSTATE_ACTIVE) {
471
	WRITESUBMENUBUTTON("Modify Traffic Shaping",
472
			   CreateURL("delaycontrol", $experiment));
473
    }
474 475
}

476 477 478 479 480
if (!$geniflags) {
    WRITESUBMENUBUTTON("Modify Settings",
                       CreateURL("editexp", $experiment));
    WRITESUBMENUDIVIDER();
}
481

482
if (!$geniflags && $expstate == $TB_EXPTSTATE_ACTIVE) {
483 484 485
    if (!$geniflags) {
	WRITESUBMENUBUTTON("Link Tracing/Monitoring",
			   CreateURL("linkmon_list", $experiment));
486
    
487 488
	WRITESUBMENUBUTTON("Event Viewer",
			   CreateURL("showevents", $experiment));
489
    
490 491 492 493 494 495 496
        #
        # Admin and project/experiment leaders get this option.
        #
        if ($experiment->AccessCheck($this_user, $TB_EXPT_UPDATE)) {
                WRITESUBMENUBUTTON("Update All Nodes",
                                   CreateURL("updateaccounts", $experiment));
        }
497 498
    }
    # Reboot option
499
    if ($experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
500
	WRITESUBMENUBUTTON("Reboot All Nodes",
501
			   CreateURL("boot", $experiment));
502
    }
503
}
504

505 506
if (!$geniflags &&
    ($expstate == $TB_EXPTSTATE_ACTIVE ||
507 508
     $expstate == $TB_EXPTSTATE_ACTIVATING ||
     $expstate == $TB_EXPTSTATE_MODIFY_RESWAP) &&
509 510
    (STUDLY() || $EXPOSELINKTEST)) {
    WRITESUBMENUBUTTON(($linktest_running ?
511 512
			"Stop LinkTest" : "Run LinkTest"),
		       CreateURL("linktest", $experiment) . 
513 514
		       ($linktest_running ? "&kill=1" : ""));
}
515

516
if (!$geniflags && $expstate == $TB_EXPTSTATE_ACTIVE) {
517
    if (!$geniflags && STUDLY() && isset($classes['pcvm'])) {
518
	WRITESUBMENUBUTTON("Record Feedback Data",
519 520
			   CreateURL("feedback", $experiment) .
			   "&mode=record");
521 522
    }
}
523 524 525

if (($expstate == $TB_EXPTSTATE_ACTIVE ||
     $expstate == $TB_EXPTSTATE_SWAPPED) &&
526
    !$geniflags && STUDLY()) {
527
    WRITESUBMENUBUTTON("Clear Feedback Data",
528 529
		       CreateURL("feedback", $experiment) . "&mode=clear");
    if (isset($classes['pcvm'])) {
530
	    WRITESUBMENUBUTTON("Remap Virtual Nodes",
531
			       CreateURL("remapexp", $experiment));
532
    }
533
}
534
    
535 536 537
# Wireless maps if experiment includes wireless lans.
if ($wireless) {
    WRITESUBMENUBUTTON("Wireless Node Map",
538 539 540
		       "floormap.php3".
		       ($expstate == $TB_EXPTSTATE_ACTIVE ?
			"?pid=$exp_pid&eid=$exp_eid" : ""));
541 542
}

543 544
WRITESUBMENUDIVIDER();

545
# History
546
if (! ($instance || $geniflags)) {
547 548 549
    WRITESUBMENUBUTTON("Show History",
		       "showstats.php3?showby=expt&exptidx=$expindex");
}
550

551 552
if (!$geniflags) {
    WRITESUBMENUBUTTON("Duplicate Experiment",
553
		       "beginexp.php?copyid=$expindex");
554
    if (1) {
555 556 557 558
        $uuid = $experiment->uuid();
        WRITESUBMENUBUTTON("Create Profile from Experiment",
                           "portal/manage_profile.php?fromexp=$uuid");
    }
559 560
}
if ($EXPOSEARCHIVE && !$instance && !$geniflags) {
561
    WRITESUBMENUBUTTON("Experiment File Archive",
562
		       "archive_view.php3?experiment=$expindex");
563 564
}

565 566
# Blinky lights - but only if they have nodes of the correct type in their
# experiment
567
if (isset($classes['mote']) && $expstate == $TB_EXPTSTATE_ACTIVE) {
568
    WRITESUBMENUBUTTON("Show Blinky Lights",
569
		       CreateURL("moteleds", $experiment), "moteleds");
570 571
}

Leigh Stoller's avatar
Leigh Stoller committed
572
if ($isadmin) {
Leigh Stoller's avatar
Leigh Stoller committed
573 574 575 576
    if ($expstate == $TB_EXPTSTATE_ACTIVE ||
	$expstate == $TB_EXPTSTATE_PANICED) {

	if ($expstate == $TB_EXPTSTATE_ACTIVE && !$geniflags) {
577 578 579 580 581 582 583
	    SUBMENUSECTION("Beta-Test Options");
	    WRITESUBMENUBUTTON("Restart Experiment",
			       CreateURL("swapexp", $experiment,
					 "inout", "restart"));
	    WRITESUBMENUBUTTON("Replay Events",
			       CreateURL("replayexp", $experiment));
	}
584

585
	SUBMENUSECTION("Admin Options");
586

Leigh Stoller's avatar
Leigh Stoller committed
587
	if ($expstate == $TB_EXPTSTATE_ACTIVE && !$geniflags) {
588 589
	    WRITESUBMENUBUTTON("Send an Idle Info Request",
			       CreateURL("request_idleinfo", $experiment));
590
	
591 592 593
	    WRITESUBMENUBUTTON("Send a Swap Request",
			       CreateURL("request_swapexp", $experiment));
	}
Leigh Stoller's avatar
Leigh Stoller committed
594 595 596 597 598 599 600 601 602
	if ($expstate == $TB_EXPTSTATE_PANICED) {
	    WRITESUBMENUBUTTON("Clear Panic Mode",
			       CreateURL("panicbutton", $experiment,
					 "clear", 1));
	}
	else {
	    WRITESUBMENUBUTTON("Panic Mode (level 1)",
			       CreateURL("panicbutton", $experiment,
					 "level", 1));
603 604 605 606 607
	    if (! $geniflags) {
		WRITESUBMENUBUTTON("Panic Mode (level 2)",
				   CreateURL("panicbutton", $experiment,
					     "level", 2));
	    }
Leigh Stoller's avatar
Leigh Stoller committed
608 609 610 611
	    WRITESUBMENUBUTTON("Force Swap Out (Idle-Swap)",
			       CreateURL("swapexp", $experiment,
					 "inout", "out", "force", 1));
	}
612 613 614
	SUBMENUSECTIONEND();
    }
}
615
}    
616 617
SUBMENUEND_2A();

618 619 620 621 622 623 624 625 626 627 628 629 630
echo "<br>\n";
echo "<script>\n";
echo "function FreeNodeHtml_CB(stuff) {
         getObjbyName('showexpusagefreenodes').innerHTML = stuff;
         setTimeout('GetFreeNodeHtml()', 60000);
      }
      function GetFreeNodeHtml() {
         x_FreeNodeHtml(FreeNodeHtml_CB);
      }
      setTimeout('GetFreeNodeHtml()', 60000);
      </script>\n";
	  
echo "<div id=showexpusagefreenodes>\n";
631
echo   ShowFreeNodes($this_user, $experiment->Group());
632 633
echo "</div>\n";

634 635
echo "<br>
      <a href='shownsfile.php3?pid=$exp_pid&eid=$exp_eid'>
636
         <img border=1 alt='experiment vis'
Leigh Stoller's avatar
Leigh Stoller committed
637
              src='showthumb.php3?idx=$rsrcidx'></a>";
638 639

SUBMENUEND_2B();
640

Leigh Stoller's avatar
Leigh Stoller committed
641 642 643 644 645 646 647
#
# The center area is a form that can show NS file, Details, or Vis.
# IE complicates this, although in retrospect, I could have used plain
# input buttons instead of the fancy rendering kind of buttons, which do not
# work as expected (violates the html spec) in IE. 
#
echo "<script type='text/javascript' language='javascript'>
648
        var li_current = 'li_settings';
Leigh Stoller's avatar
Leigh Stoller committed
649
        function Show(which) {
650
	    li = getObjbyName(li_current);
651 652 653 654
            if (li) {
                li.style.backgroundColor = '#DDE';
                li.style.borderBottom = '1px solid #778';
            }
655 656 657

            li_current = 'li_' + which;
	    li = getObjbyName(li_current);
658 659 660 661 662
            if (li) {
                li.style.backgroundColor = 'white';
                li.style.borderBottom = '1px solid white';
                x_Show(which, 0, 0, Show_cb);
            }
Leigh Stoller's avatar
Leigh Stoller committed
663 664
            return false;
        }
665 666 667 668 669 670 671 672 673 674 675
        function Show_cb(html) {
	    visarea = getObjbyName('showexp_visarea');
            if (visarea) {
                visarea.innerHTML = html;
            }
        }
        function ShowVisInit() {
            ADD_DHTML(\"myvisdiv\");
        }
        function VisChange(zoom, detail) {
            x_Show('vis', zoom, detail, Show_cb);
Leigh Stoller's avatar
Leigh Stoller committed
676 677
            return false;
        }
678 679 680 681
        function GraphChange(which) {
            x_Show('graphs', which, 0, Show_cb);
            return false;
        }
682 683 684 685
        function ShowEvents() {
            x_Show('details', 1, 0, Show_cb);
            return false;
        }
686 687 688 689 690 691
        function SaveDetails() {
            window.open('spitreport.php?pid=$pid&eid=$eid',
                        '_blank','width=700,height=400,toolbar=no,".
                        "resizeable=yes,scrollbars=yes,status=yes,".
	                "menubar=yes');
        }
692 693
        function SaveNS() {
            window.open('spitnsdata.php3?pid=$pid&eid=$eid',
694
                        '_blank','width=700,height=400,toolbar=no,".
695 696 697
                        "resizeable=yes,scrollbars=yes,status=yes,".
	                "menubar=yes');
        }
698 699 700
        function FullScreenVis() {
	    window.location.replace('shownsfile.php3?pid=$pid&eid=$eid');
        }
701 702 703 704 705 706
        function ModifyAnno() {
            textarea = getObjbyName('annotation');
            x_ModifyAnno(textarea.value, ModifyAnno_cb);
        }
        function ModifyAnno_cb(val) {
        }
707
        function Setup() {
708 709 710
	    var urllocation = location.href; //find url parameter
	    if (urllocation && urllocation.indexOf('#') >= 0) {
                var which = urllocation.substr(urllocation.indexOf('#') + 1);
711 712 713 714 715

	        li = getObjbyName('li_' + which);
                if (!li) {
                    which = 'settings';
                }
716 717 718 719
                Show(which);
            }
            else {
	        li = getObjbyName(li_current);
720 721 722 723
                if (li) {
                    li.style.backgroundColor = 'white';
                    li.style.borderBottom = '1px solid white';
                }
724
            }
725
        }
Leigh Stoller's avatar
Leigh Stoller committed
726 727
      </script>\n";

728 729 730 731 732 733
#
# This is the topbar
#
echo "<div width=\"100%\" align=center>\n";
echo "<ul id=\"topnavbar\">\n";
echo "<li>
734 735
          <a href=\"#settings\" ".
               "class=topnavbar onfocus=\"this.hideFocus=true;\" ".
736 737 738
               "id=\"li_settings\" onclick=\"Show('settings');\">".
               "Settings</a></li>\n";
echo "<li>
739 740
          <a href=\"#vis\" ".
               "class=topnavbar onfocus=\"this.hideFocus=true;\" ".
741
               "id=\"li_vis\" onclick=\"Show('vis');\">".
742 743
               "Visualization</a></li>\n";
echo "<li>
744 745
          <a href=\"#nsfile\" ".
              "class=topnavbar onfocus=\"this.hideFocus=true;\"  ".
746
              "id=\"li_nsfile\" onclick=\"Show('nsfile');\">".
747 748
              "NS File</a></li>\n";
echo "<li>
749 750
          <a href=\"#details\" ".
              "class=topnavbar onfocus=\"this.hideFocus=true;\" ".
751
              "id=\"li_details\" onclick=\"Show('details');\">".
752
              "Details</a></li>\n";
753

754
if ($instance) {
755
    echo "<li>
756 757
              <a href=\"#anno\" ".
	          "class=topnavbar onfocus=\"this.hideFocus=true;\" ".
758
	          "id=\"li_anno\" onclick=\"Show('anno');\">".
759
                  "Annotation</a></li>\n";
760
}
761 762
if ($HAVE_USER_VIS) {
    echo "<li>
763 764
              <a href=\"#uservis\" ".
	          "class=topnavbar onfocus=\"this.hideFocus=true;\" ".
765 766 767
	          "id=\"li_uservis\" onclick=\"Show('uservis');\">".
                  "User Visualization</a></li>\n";
}
768
echo "</ul>\n";
769 770
echo "</div>\n";
echo "<div align=center id=topnavbarbottom>&nbsp</div>\n";
Leigh Stoller's avatar
Leigh Stoller committed
771

772 773 774 775
#
# Start out with details ...
#
echo "<div align=center width=\"100%\" id=\"showexp_visarea\">\n";
776
$experiment->Show();
777
echo "</div>\n";
778

779
if ($experiment->Firewalled() &&
Leigh Stoller's avatar
Leigh Stoller committed
780 781 782 783 784
    ($expstate == $TB_EXPTSTATE_ACTIVE ||
     $expstate == $TB_EXPTSTATE_PANICED ||
     $expstate == $TB_EXPTSTATE_ACTIVATING ||
     $expstate == $TB_EXPTSTATE_SWAPPING)) {
    echo "<center>\n";
785 786 787
    if ($paniced == 2) {
	#
	# Paniced due to failed swapout.
788
	# Only be semi-obnoxious (no blinking) since it was not their fault.
789 790 791 792 793 794 795 796 797 798 799 800
	#
	echo "<br><font size=+1 color=red>".
	     "Your experiment was cut off due to a failed swapout on $panic_date!".
	     "<br>".
	     "You will need to contact testbed operations to make further ".
  	     "changes (swap, terminate) to your experiment.</font>";
    }
    elseif ($paniced) {
	#
	# Paniced due to panic button.
  	# Full-on obnoxious is called for here!
	#
Leigh Stoller's avatar
Leigh Stoller committed
801 802 803 804 805 806 807
	echo "<br><font size=+1 color=red><blink>".
	     "Your experiment was cut off via the Panic Button on $panic_date!".
	     "<br>".
	     "You will need to contact testbed operations to make further ".
  	     "changes (swap, terminate) to your experiment.</blink></font>";
    }
    else {
808 809 810
	$panic_url = CreateURL("panicbutton", $experiment);
	
	echo "<br><a href='$panic_url'>
Leigh Stoller's avatar
Leigh Stoller committed
811 812 813 814 815 816 817
                 <img border=1 alt='panic button' src='panicbutton.gif'></a>";
	echo "<br><font color=red size=+2>".
	     " Press the Panic Button to contain your experiment".
	     "</font>\n";
    }
    echo "</center>\n";
}
818
SUBPAGEEND();
819

820 821
if ($instance) {
    $instance->ShowCurrentBindings();
822 823
}

824 825 826
#
# Dump the node information.
#
827
echo "<center>\n";
Mike Hibler's avatar
Mike Hibler committed
828
SHOWNODES($exp_pid, $exp_eid, $sortby, $showclass);
829
echo "</center>\n";
830

Leigh Stoller's avatar
Leigh Stoller committed
831
if ($isadmin) {
832 833 834 835
    echo "<center>
          <h3>Experiment Stats</h3>
         </center>\n";

836
    $experiment->ShowStats();
837 838
}

839 840 841 842 843 844 845
#
# Get the active tab to look right.
#
echo "<script type='text/javascript' language='javascript'>
      Setup();
      </script>\n";

846 847 848 849
#
# Standard Testbed Footer
# 
PAGEFOOTER();
850
?>