showexp_list.php3 25 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
#
3
# Copyright (c) 2000-2012 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 B. Stoller's avatar
Leigh B. Stoller committed
23
#
24 25 26
include("defs.php3");

#
27
# Only known and logged in users.
28
#
29 30 31
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
32

33 34 35 36 37
#
# Verify Page arguments.
#
$optarg = OptionalPageArguments("showtype",   PAGEARG_STRING,
				"sortby",     PAGEARG_STRING,
Leigh B. Stoller's avatar
Leigh B. Stoller committed
38
				"thumb",      PAGEARG_INTEGER,
39 40
				"noignore",   PAGEARG_BOOLEAN);

41 42 43 44 45
#
# Standard Testbed Header
#
PAGEHEADER("Experiment Information Listing");

46 47
$clause      = 0;
$having      = "";
Mac Newbold's avatar
Mac Newbold committed
48 49
$active      = 0;
$idle        = 0;
50
$protogeni   = 0;
51

52 53 54 55 56
#
# Hack for NSDI deadline. Generalize later.
#
$openlist        = TBGetSiteVar("general/open_showexplist");
$openlist_member = 0;
57 58
$openlist_join   = "";
$openlist_clause = "";
59
if (!$isadmin && isset($openlist) && $openlist != "") {
60 61 62
    if (! ($project = Project::Lookup($openlist))) {
	TBERROR("Could not map project $openlist to its object", 1);
    }
63
    $openlist_member =
64
	TBMinTrust($project->UserTrust($this_user), $TBDB_TRUST_USER);
65 66 67 68 69 70
    $openlist_join =
	" left join group_membership as g on ".
	"     g.uid=e.expt_swap_uid and g.pid='$openlist' and g.pid=g.gid ";
    $openlist_clause = " and g.uid is not null ";
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
71 72
if (! isset($showtype))
    $showtype="active";
73 74
if (! isset($sortby))
    $sortby = "normal";
75 76
if (! isset($thumb)) 
    $thumb = 0;
77 78
if (! isset($noignore)) 
    $noignore = 0;
79

80
echo "<b>Show: ";
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
if ($showtype != "active") {
    echo "<a class='static' href='showexp_list.php3?showtype=active&sortby=$sortby&thumb=$thumb'>Active</a>, ";
} else {
    echo "Active, ";
}

if ($showtype != "batch") {
    echo "<a class='static' href='showexp_list.php3?showtype=batch&sortby=$sortby&thumb=$thumb'>Batch</a>, ";
} else {
    echo "Batch, ";
}

if ($isadmin) {
    if ($showtype != "idle") {
	echo "<a class='static' href='showexp_list.php3?showtype=idle&sortby=$sortby&thumb=$thumb'>Idle</a>, ";
    } else {
	echo "Idle, ";
    }
100 101 102 103 104 105

    if ($showtype != "ProtoGENI") {
	echo "<a class='static' href='showexp_list.php3?showtype=ProtoGENI&sortby=$sortby&thumb=$thumb'>ProtoGENI</a>, ";
    } else {
	echo "ProtoGENI, ";
    }    
106 107 108 109 110 111 112 113 114 115
}

if ($showtype != "all") {
    echo "<a class='static' href='showexp_list.php3?showtype=all&sortby=$sortby&thumb=$thumb'>All</a>";
} else {
    echo "All";
}

echo "</b><br />\n";

116 117
# Default value for showlastlogin is 1 for admins
$showlastlogin = $isadmin;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
118
# Note: setting this to 1 for non-admins still does not make the column
119 120
# show properly... it just shows the header in the table, over the
# wrong column. 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
121

122 123
# How many hours is considered idle...
$idlehours = TBGetSiteVar("idle/threshold");
124

Leigh B. Stoller's avatar
Leigh B. Stoller committed
125 126 127 128 129 130 131
#
# Handle showtype
# 
if (! strcmp($showtype, "all")) {
    $title  = "All";
}
elseif (! strcmp($showtype, "active")) {
132 133
    # Active is now defined as "having nodes reserved" - we just depend on
    # the fact that we skip expts with no nodes further down...
134 135 136
    # But for speed, explicitly exclude expts that say they are "swapped"
    # (leave in activating, swapping, etc.)
    $clause = "e.state !='$TB_EXPTSTATE_SWAPPED'";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
137
    $title  = "Active";
138
    $having = "having (ncount>0)";
139
    $active = 1;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
140 141
}
elseif (! strcmp($showtype, "batch")) {
142 143
    $clause = "(e.batchmode=1 and e.state!='" .
               $TB_EXPTSTATE_SWAPPED . "')";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
144
    $title  = "Batch";
145
}
146
elseif ((!strcmp($showtype, "idle")) && $isadmin ) {
147
    # Do not put active in the clause for same reason as active
148 149
    # However, it takes a long time with so many swapped expts
    $clause = "e.state !='$TB_EXPTSTATE_SWAPPED'";
150
    $title  = "Idle";
151 152
    #$having = "having (lastswap>=1)"; # At least one day since swapin
    $having = "having (lastswap>=0)";
153
    $idle = 1;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
154
    $showlastlogin = 0; # do not show a lastlogin column
155
}
156 157 158 159 160 161
elseif ($showtype == "ProtoGENI" && $isadmin) {
    $title  = "ProtoGENI";
    $clause = "e.nonlocal_type='protogeni'";
    $protogeni = 1;
    $showlastlogin = 0; # do not show a lastlogin column
}
162
else {
163
    # See active above
Leigh B. Stoller's avatar
Leigh B. Stoller committed
164
    $title  = "Active";
165
    $having = "having (ncount>0)";
166
    $active = 1;
167
}
168

169 170 171


if (!$idle) {
172 173 174
    echo "<b>View: ";

    if ($thumb != 0) {
175
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=$sortby&thumb=0'>";
176 177 178 179 180 181 182 183
	echo "List";
        echo "</a>";
    } else {
        echo "List";
    }
    echo ", ";

    if ($thumb != 1) {
184
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=$sortby&thumb=1'>";
185 186
	echo "Detailed Thumbnails";
        echo "</a>";
187
    } else {
188
        echo "Detailed Thumbnails";
189
    }
190 191 192
    echo ", ";

    if ($thumb != 2) {
193
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=$sortby&thumb=2'>";
194 195 196 197 198 199
	echo "Brief Thumbnails";
        echo "</a>";
    } else {
        echo "Brief Thumbnails";
    }
    echo "</b><br />\n";
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

if ($thumb && !$idle) {
    echo "<b>Sort by: ";
    if (isset($sortby) && $sortby != "normal" && $sortby != "pid") {
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=pid&thumb=$thumb'>";
	echo "Project";
        echo "</a>, ";
    } else {
        echo "Project, ";
    }	
    if ($sortby != "eid") {
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=eid&thumb=$thumb'>";
	echo "Experiment ID";
        echo "</a>, ";
    } else {
        echo "Experiment ID, ";
    }
    if ($sortby != "pcs") {
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=pcs&thumb=$thumb'>";
	echo "Node Usage";
        echo "</a>, ";
    } else {
        echo "Node Usage, ";
    }	
    if ($sortby != "name") {
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=name&thumb=$thumb'>";
	echo "Experiment Description";
        echo "</a>, ";
    } else {
        echo "Experiment Description, ";
    }	
    if ($sortby != "uid") {
	echo "<a class='static' href='showexp_list.php3?showtype=$showtype&sortby=uid&thumb=$thumb'>";
	echo "Creator";
        echo "</a>";
    } else {
        echo "Creator";
    }

    echo "</b><br />\n";
}
241
}
242
 
243 244
echo "<br />\n";

Leigh B. Stoller's avatar
Leigh B. Stoller committed
245 246 247
#
# Handle sortby.
# 
248 249 250 251 252 253 254 255 256
if (! strcmp($sortby, "normal") ||
    ! strcmp($sortby, "pid"))
    $order = "e.pid,e.eid";
elseif (! strcmp($sortby, "eid"))
    $order = "e.eid,e.expt_head_uid";
elseif (! strcmp($sortby, "uid"))
    $order = "e.expt_head_uid,e.pid,e.eid";
elseif (! strcmp($sortby, "name"))
    $order = "e.expt_name";
257
elseif (! strcmp($sortby, "pcs"))
258
    $order = "ncount DESC,e.pid,e.eid";
259 260
elseif (! strcmp($sortby, "idle"))
    $order = "canbeidle desc,idle_ignore,idlesec DESC,ncount desc,e.pid,e.eid";
261 262
elseif (! strcmp($sortby, "created"))
    $order = "e.expt_created";
263 264 265
else 
    $order = "e.pid,e.eid";

266 267 268 269
#
# Show a menu of all experiments for all projects that this uid
# is a member of. Or, if an admin type person, show them all!
#
270 271 272 273 274
if ($clause) {
    $clause = "and ($clause)";
} else {
    $clause = "";
}
275 276 277

# Notes about the queries below:
# - idle is fudged by 121 seconds so that in the five minutes between 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
278
#   slothd reports we do not get active expts showing up as idle for 0.1 hrs
279

280
if ($isadmin || $openlist_member) {
Leigh B. Stoller's avatar
Leigh B. Stoller committed
281
    $experiments_result =
282 283 284 285 286 287 288 289
	DBQueryFatal("
select e.*, date_format(expt_swapped,'%Y-%m-%d') as d, 
date_format(expt_swapped,'%c/%e') as dshort, 
(to_days(now())-to_days(expt_swapped)) as lastswap, 
count(r.node_id) as ncount, swap_requests, 
round((unix_timestamp(now())-unix_timestamp(last_swap_req))/3600,1) as lastreq,
(unix_timestamp(now()) - unix_timestamp(max(greatest(
last_tty_act,last_net_act,last_cpu_act,last_ext_act)))) as idlesec,
290 291
(max(last_report) is not null) as canbeidle, s.rsrcidx, p.nonlocal_id
from experiments as e
292 293
left join reserved as r on e.pid=r.pid and e.eid=r.eid
left join experiment_stats as s on e.idx=s.exptidx
294 295
left join nodes as n on r.node_id=n.node_id
left join node_activity as na on r.node_id=na.node_id
296
left join projects as p on p.pid_idx=e.pid_idx
297 298
$openlist_join
where (n.type!='dnard' or n.type is null) $clause $openlist_clause
299
group by e.pid,e.eid $having order by $order");
300 301
}
else {
Leigh B. Stoller's avatar
Leigh B. Stoller committed
302
    $experiments_result =
303 304 305 306 307
	DBQueryFatal("
select distinct e.*, date_format(expt_swapped,'%Y-%m-%d') as d, 
date_format(expt_swapped,'%c/%e') as dshort, count(r.node_id) as ncount, 
(unix_timestamp(now()) - unix_timestamp(max(greatest(
last_tty_act,last_net_act,last_cpu_act,last_ext_act)))) as idlesec,
308
(max(last_report) is not null) as canbeidle, s.rsrcidx
309 310
from group_membership as g 
left join experiments as e on g.pid=e.pid and g.pid=g.gid 
311
left join experiment_stats as s on e.idx=s.exptidx
312 313 314 315 316 317
left join reserved as r on e.pid=r.pid and e.eid=r.eid 
left join nodes as n on r.node_id=n.node_id 
left join node_activity as na on r.node_id=na.node_id
where (n.type!='dnard' or n.type is null) and 
 g.uid='$uid' and e.pid is not null and e.eid is not null $clause 
group by e.pid,e.eid $having order by $order");    
318
}
319
if (! mysql_num_rows($experiments_result)) {
320
    USERERROR("There are no experiments running that match the criteria.", 1);
321 322
}

323 324
if (mysql_num_rows($experiments_result)) {
    echo "<center>
Leigh B. Stoller's avatar
Leigh B. Stoller committed
325
           <h2>$title Experiments</h2>
326
          </center>\n";
327

Mac Newbold's avatar
Mac Newbold committed
328
    if ($idle) {
329
      echo "<p><center><b>Experiments that have been idle at least 
330 331 332 333 334 335
$idlehours hours</b><br>\n";
      if ($noignore) {
        echo "<a class='static' href='showexp_list.php3?showtype=idle&sortby=$sortby&thumb=$thumb'>\n
Exclude idle-ignore experiments</a></center></p><br />\n";
      } else {
        echo "<a class='static' href='showexp_list.php3?showtype=idle&sortby=$sortby&thumb=$thumb&noignore=1'>\n
336
Include idle-ignore experiments</a></center></p><br />\n";
337
      }
Mac Newbold's avatar
Mac Newbold committed
338
    }
339
    
340
    $idlemark = "<b>*</b>";
341 342 343
    $stalemark = "<b>?</b>";
    $parens = 0;
    
344 345 346 347 348 349 350
    #
    # Okay, I decided to do this as one big query instead of a zillion
    # per-exp queries in the loop below. No real reason, except my personal
    # desire not to churn the DB.
    # 
    $total_usage  = array();
    $perexp_usage = array();
351
    $perexp_types = array();
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373

    #
    # Geta all the classes of nodes each experiment is using, and create
    # a two-D array with their counts.
    # 
    $usage_query =
	DBQueryFatal("select r.pid,r.eid,nt.class, ".
		     "  count(nt.class) as ncount ".
		     "from reserved as r ".
		     "left join nodes as n on r.node_id=n.node_id ".
		     "left join node_types as nt on n.type=nt.type ".
		     "where n.type!='dnard' ".
		     "group by r.pid,r.eid,nt.class");

    while ($row = mysql_fetch_array($usage_query)) {
	$pid   = $row[0];
	$eid   = $row[1];
	$class = $row[2];
	$count = $row[3];
	
	$perexp_usage["$pid:$eid"][$class] = $count;
    }
374

375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
    #
    # Geta all the types of nodes each experiment is using, and create
    # a two-D array with their counts.
    # 
    $usage_query =
	DBQueryFatal("select r.pid,r.eid,n.type, ".
		     "  count(n.type) as ncount ".
		     "from reserved as r ".
		     "left join nodes as n on r.node_id=n.node_id ".
		     "group by r.pid,r.eid,n.type");

    while ($row = mysql_fetch_array($usage_query)) {
	$pid   = $row[0];
	$eid   = $row[1];
	$type  = $row[2];
	$count = $row[3];
	
	$perexp_types["$pid:$eid"][$type] = $count;
    }

395 396 397
    #
    # Now shove out the column headers.
    #
398
if ($thumb && !$idle) {
399 400 401 402 403
    if ($thumb == 2) {
	echo "<table border=2 cols=4 cellpadding=2 cellspacing=2 align=center><tr>";
    } else {
	echo "<table border=2 cols=2 cellpadding=2 cellspacing=2 align=center><tr>";
    }
404 405 406 407 408 409
    $thumbCount = 0;
 
    while ($row = mysql_fetch_array($experiments_result)) {	
	$pid  = $row["pid"];
	$eid  = $row["eid"]; 
	$huid = $row["expt_head_uid"];
410
	$sidx = $row["swapper_idx"];
411
	$name = stripslashes($row["expt_name"]);
412
	$date = $row["dshort"];
413
        $rsrcidx = $row["rsrcidx"];
414
	$state= $row["state"];
415

416 417 418 419 420 421 422 423 424
	if ($state == "active" && isset($sidx)) {
	    if (! ($user = User::Lookup($sidx))) {
		TBERROR("Could not lookup object for user $sidx", 1);
	    }
	}
	else {
	    if (! ($user = User::Lookup($huid))) {
		TBERROR("Could not lookup object for user $huid", 1);
	    }
425
	}
426 427 428
	$showuser_url = CreateURL("showuser", $user);
	$user_affil   = $user->affil_abbrev();
	$user_affil_text = $user_affil ? "&nbsp;($user_affil)" : "";
429 430
	
	if ($idle && ($str=="&nbsp;" || !$pcs)) { continue; }
431

432 433 434 435
	if ($thumb == 2) {
	    if ($pid != "emulab-ops") {
		echo "<td align=center>".
		     "<a href='shownsfile.php3?pid=$pid&eid=$eid'>".
436
		     "<img border=1 class='stealth' ".
437 438
		     " src='showthumb.php3?idx=$rsrcidx'>".
		     "<br>\n".
439 440 441 442 443
		     "<b>".
		     "<a href='showproject.php3?pid=$pid'>$pid</a>/<br />".
		     "<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a>".
		     "</b>".
		     "</td>";
Chad Barb's avatar
Chad Barb committed
444

Leigh B. Stoller's avatar
Leigh B. Stoller committed
445 446
		$thumbCount++;
		if (($thumbCount % 4) == 0) { echo "</tr><tr>\n"; }
447 448 449 450 451 452
	    }
	} else {

	    echo "<td>".
		 "<table border=0 cellpadding=4 cellspacing=0>".
		 "<tr>".
453
		 "<td width=160 align=center>".
454
	         "<a href='shownsfile.php3?pid=$pid&eid=$eid'>".
455
		 "<img border=1 class='stealth' ".
456
		 " src='showthumb.php3?idx=$rsrcidx'>".
457 458 459 460 461 462 463 464 465 466
	         "</a>".
                 "</td>".
	         "<td align=left class='paddedcell'>".
	         "<b>".
 	         "<a href='showproject.php3?pid=$pid'>$pid</a>/".
                 "<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a>".
	         "</b>".
	         "<br />\n".
	         "<b><font size=-1>$name</font></b>".
                 "<br />\n";
467 468


469 470 471 472 473 474 475 476 477
	    if ($isadmin) {
		$swappable= $row["swappable"];
		$swapreq=$row["swap_requests"];
		$lastswapreq=$row["lastreq"];
		$lastlogin = "";
		if ($lastexpnodelogins = TBExpUidLastLogins($pid, $eid)) {
		    $daysidle=$lastexpnodelogins["daysidle"];
		    #if ($idle && $daysidle < 1)
		    #  continue;
478
		    $lastlogin .= $lastexpnodelogins["shortdate"] . " " .
479 480 481
			"(" . $lastexpnodelogins["uid"] . ")";
		} elseif ($state=="active") {
		    $daysidle=$row["lastswap"];
482
		    $lastlogin .= "$date swapin";
483 484 485 486 487 488
		}
		# if ($lastlogin=="") { $lastlogin="<td>&nbsp;</td>\n"; }
		if ($lastlogin != "") {
		    echo "<font size=-2><b>Last Login:</b> $lastlogin</font><br />\n";
		}
	    }	
489

490
	    echo "<font size=-2><b>Created by:</b> ".
491
		 "<a href='$showuser_url'>$huid</a>$user_affil_text".
492
		 "</font><br />\n";
493

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
	    $special = 0;
	    $pcs     = 0;
	    reset($perexp_usage);
	    if (isset($perexp_usage["$pid:$eid"])) {
		while (list ($class, $count) = each($perexp_usage["$pid:$eid"])) {
		    if (strcmp($class, "pc")) {
			$special += $count;
		    } else {
			$pcs += $count;
		    }
		}
	    }

	    if ($pcs) {
		if ($pcs == 1) { $plural = ""; } else { $plural = "s"; }  
		echo "<font size=-1><b>Using <font color=red>$pcs PC</font> Node$plural</b></font><br />\n";
	    }
	    if ($special) {
		if ($special == 1) { $plural = ""; } else { $plural = "s"; }  
		echo "<font size=-1><b>Using <font color=red>$special Special</font> Node$plural</b></font><br />\n";
	    }

516 517
	    echo "</td></tr></table> \n";
	    echo "</td>";
518

Leigh B. Stoller's avatar
Leigh B. Stoller committed
519 520
	    $thumbCount++;
	    if (($thumbCount % 2) == 0) { echo "</tr><tr>\n"; }
521
	}
522 523 524 525
    }

    echo "</tr></table>";
} else {
526 527 528

    $ni = ($noignore ? "&noignore=$noignore" : "");
    
529 530 531
    echo "<table border=2 cols=0
                 cellpadding=0 cellspacing=2 align=center>
            <tr>
532 533 534
              <th >
               <a class='static'
                  href='showexp_list.php3?showtype=$showtype&sortby=pid$ni'>
535
                  PID</a></th>
536 537 538
              <th >
               <a class='static'
                  href='showexp_list.php3?showtype=$showtype&sortby=eid$ni'>
539
                  EID</a></th>
540 541 542
              <th align=center >
               <a class='static'
                  href='showexp_list.php3?showtype=$showtype&sortby=pcs$ni'>
543
                  PCs</a> [1]</th>
544 545 546 547
              <th align=center >
               <a class='static'
                  href='showexp_list.php3?showtype=$showtype&sortby=idle$ni'>
                  Hours Idle</a> [2]</th>\n";
548
    
549
    if ($showlastlogin)
550
        echo "<th align=center>Last Login</th>\n";
551
    if ($idle) {
552
	#echo "<th width=4% align=center colspan=2>Swap Requests</th>\n";
553
	echo "<th align=center>Swap Requests</th>\n";
554
    }
555

556 557
    if (! ($openlist_member || $protogeni)) {
	echo "<th >
558 559 560 561
                  <a class='static' ".
                     "href='showexp_list.php3?showtype=$showtype".
                     "&sortby=name$ni'>Description</a></th>\n";
    }
562
    echo "  <th >
563 564
               <a class='static' ".
                  "href='showexp_list.php3?showtype=$showtype&sortby=uid$ni'>
565 566 567 568 569 570 571 572 573
                  Creator/<br>Swapper</a></th>\n";
    
    if ($protogeni) {
	echo "<th>
                <a class='static' ".
                "href='showexp_list.php3?showtype=$showtype&sortby=created$ni'>
                Created</a></th>\n";
    }
    echo "</tr>\n";
574

575
    while ($row = mysql_fetch_array($experiments_result)) {
576 577 578
	$pid  = $row["pid"];
	$eid  = $row["eid"]; 
	$huid = $row["expt_head_uid"];
579
	$sidx = $row["swapper_idx"];
Leigh B. Stoller's avatar
Leigh B. Stoller committed
580
	$name = stripslashes($row["expt_name"]);
581
	$date = $row["dshort"];
582
	$state= $row["state"];
583 584 585
	$ignore = $row['idle_ignore'];
	$idlesec= $row["idlesec"];
	$swapreqs = $row["swap_requests"];
586 587
	$nonlocal_id = $row["nonlocal_id"];
	$nonlocal_user_id = $row["nonlocal_user_id"];
588
	$created = $row["expt_created"];
589
	$isidle = ($idlesec >= 3600*$idlehours);
590
	$daysidle=0;
591
	$idletime = ($idlesec > 300 ? round($idlesec/3600,1) : 0);
592 593
	# reset pcs
	$pcs=0;
594

595 596 597 598 599
	if (! ($experiment = Experiment::LookupByPidEid($pid, $eid))) {
	    TBERROR("Could not map $pid/$eid to its object", 1);
	}
	$stale = $experiment->IdleStale();

600 601 602 603
	if ($state == "active" && isset($sidx)) {
	    if (! ($user = User::Lookup($sidx))) {
		TBERROR("Could not lookup object for user $sidx", 1);
	    }
604
	}
605 606 607 608 609 610 611 612
	else {
	    if (! ($user = User::Lookup($huid))) {
		TBERROR("Could not lookup object for user $huid", 1);
	    }
	}
	$showuser_url = CreateURL("showuser", $user);
	$user_affil   = $user->affil_abbrev();
	$user_affil_text = $user_affil ? "&nbsp;($user_affil)" : "";
613 614 615
	
	if ($swapreqs && !$isidle) {
	    $swapreqs = "";
616 617 618 619
	    mysql_query("update experiments set swap_requests='' ".
			"where pid='$pid' and eid='$eid'");
	}

620
	if ($isadmin) {
621 622 623
	    $swappable= $row["swappable"];
	    $swapreq=$row["swap_requests"];
	    $lastswapreq=$row["lastreq"];
624 625 626 627 628 629
	    if ($lastswapreq > $idletime) {
		# My last request was from _before_ it was idle this time
		mysql_query("update experiments set swap_requests='' ".
			    "where pid='$pid' and eid='$eid'");
		$swapreq=0;
	    }
630 631
	    $idlemailinterval = TBGetSiteVar("idle/mailinterval");
	    # Is it toosoon to send another mail?
632
	    $toosoon = ($swapreq>0 && ($lastswapreq < $idlemailinterval));
633
	    $lastlogin = "<td>";
634
	    if ($lastexpnodelogins = TBExpUidLastLogins($pid, $eid)) {
635
	        $daysidle=$lastexpnodelogins["daysidle"];
636 637
	        #if ($idle && $daysidle < 1)
		#  continue;
638
		$lastlogin .= $lastexpnodelogins["shortdate"] . " " .
639
		 "(" . $lastexpnodelogins["uid"] . ")";
640
	    } elseif ($state=="active") {
641
	        $daysidle=$row["lastswap"];
642
	        $lastlogin .= "$date swapin";
643
	    }
644 645
	    $lastlogin.="</td>\n";
	    if ($lastlogin=="<td></td>\n") { $lastlogin="<td>&nbsp;</td>\n"; }
646
	}
647
	
648
	if ($idle) {
649
	    # If it is ignored, skip it now.
650
	    if ($ignore && !$noignore) { continue; }
651
	    #$lastlogin .= "<td align=center>$daysidle</td>\n";
652 653 654
	    if (isset($perexp_usage["$pid:$eid"]) &&
		isset($perexp_usage["$pid:$eid"]["pc"])) {
	      $pcs = $perexp_usage["$pid:$eid"]["pc"];
655
	    }
656 657
	    $foo = "<td align=center valign=center>\n";
	    #$label = "";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
658
	    # Probably do not need this when we are using stalemark
659
	    #if ($stale) { $label .= "stale "; }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
660
	    # Do not really need this if we are marking ignore with ()
661 662 663 664 665 666 667 668 669 670 671 672
	    #if ($ignore) { $label .= "ignore "; }
	    #if (!$swappable) { $label .= "unswap. "; }
 	    #if ($isidle && !$stale && !$ignore && !$toosoon && $pcs) {
	    #    $fooswap = "<td><a ".
	    #       "href=\"request_swapexp.php3?pid=$pid&eid=$eid\">".
	    #       "<img border=0 src=\"redball.gif\"></a> $label</td>\n" ;
	    #} else {
	    #   if ($label == "") { $label = "&nbsp;"; }
	    #   $fooswap = "<td>$label</td>";
	    #   if (!$pcs) { $foo .= "(no PCs)\n"; }
	    #   else { $foo .="&nbsp;"; }
	    #}
673
	    if ($swapreq > 0) {
674
	      $foo .= "$swapreq&nbsp;sent<br>".
675
	              "<font size=-2>(${lastswapreq}&nbsp;hrs&nbsp;ago)</font>\n";
676
	    }
677 678 679
	    #$foo .= "</td>".$fooswap."\n"; 
	    if (!$swappable) { $foo .= "unswap.\n"; }
	    
680
	}
681

682
	if ($idle && (!$pcs || !$isidle)) { continue; }
683

684 685
	$nodes   = 0;
	$special = 0;
686 687 688 689
	reset($perexp_usage);
	if (isset($perexp_usage["$pid:$eid"])) {
	    while (list ($class, $count) = each($perexp_usage["$pid:$eid"])) {
		$nodes += $count;
690
		if (strcmp($class, "pc")) {
691
		    $special = 1;
692 693 694 695
		} else {
		    $pcs = $count;
		}

696 697 698 699 700 701
		# Summary counts for just the experiments in the projects
		# the user is a member of.
		if (!isset($total_usage[$class]))
		    $total_usage[$class] = 0;
			
		$total_usage[$class] += $count;
702
	    }
703
	}
704

705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
	$onmouseover = "";
	reset($perexp_types);
	if (isset($perexp_types["$pid:$eid"])) {
	    $mouseover  = "<table align=center ";
	    $mouseover .= " cellpadding=2 cellspacing=2 border=2> ";
	    $mouseover .= "<tr><th>Node Type</th><th>Count</th></tr> ";

	    while (list ($type, $count) = each($perexp_types["$pid:$eid"])) {
		$mouseover .= "<tr><td class=pad4>$type</td>";
		$mouseover .= "    <td class=pad4>$count</td></tr> ";

	    }
	    $mouseover .= "</table>";
	    $onmouseover  = "onmouseover=\"this.T_WIDTH=175; ";
	    $onmouseover .= "this.T_FONTSIZE='16px'; this.T_OFFSETX=0; ";
	    $onmouseover .= "return escape('$mouseover')\"";
	}

723 724
	# in idle or active, skip experiments with no nodes.
	if (($idle || $active) && $nodes == 0) { continue; }
725 726
	if ($nodes==0) { $nodes = "&nbsp;"; }
	
727
	echo "<tr>
728 729
                <td><A href='showproject.php3?pid=$pid'>";
	if ($protogeni && $nonlocal_id) {
730 731
            # Drop the URN cruft; waste of space.
	    $nonlocal_id = substr($nonlocal_id, strlen("urn:publicid:IDN+"));
732 733 734 735 736 737 738
	    echo $nonlocal_id;
	}
	else {
	    echo "$pid";
	}
	echo "</A>";
	echo "  </td>
Leigh B. Stoller's avatar
Leigh B. Stoller committed
739
                <td><A href='showexp.php3?pid=$pid&eid=$eid'>
740
                       $eid</A></td>\n";
741
	
742
	if ($isidle && !$ignore) { $nodes = $nodes.$idlemark; }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
743 744
	# If multiple classes, then hightlight the number and show pcs/nodes.
	if ($special) {
745
	    echo "<td nowrap $onmouseover><font color=red>$nodes</font>";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
746
	    if ($pcs)
747 748
		echo " ($pcs)";
	    echo "</td>\n";	    
Leigh B. Stoller's avatar
Leigh B. Stoller committed
749
	}
750
	else
751
            echo "<td $onmouseover>$nodes</td>\n";
752

Chad Barb's avatar
Chad Barb committed
753
	if ($idletime == -1) {
754
	    $idlestr = "&nbsp;";
Chad Barb's avatar
Chad Barb committed
755
	} else {
756 757 758 759
	    $idlestr = "$idletime";
	    # Order between the next two lines determines if the
	    # stalemark goes inside or outside the parens
	    if ($stale && $pcs > 0) { $idlestr .= $stalemark; }
760
	    if ($ignore && $idletime !=0) {
761 762
		$idlestr = "($idlestr)";
		$parens = 1;
763
	    }
Chad Barb's avatar
Chad Barb committed
764
	}
765
	echo "<td>$idlestr</td>";
766 767
	
	if ($showlastlogin) echo "$lastlogin\n";
768
	if ($idle) echo "$foo\n";
769

770
	if (! ($openlist_member || $protogeni)) {
771 772
	    echo "<td>$name</td>\n";
	}
773 774
	if ($protogeni) {
	    echo "<td>$nonlocal_user_id</td>\n";
775
	    echo "<td>$created</td>\n";
776 777 778 779
	}
	else {
	    echo "<td><A href='$showuser_url'>$huid</A>$user_affil_text</td>\n";
	}
780
	echo "</tr>\n";
781 782
    }
    echo "</table>\n";
783

784 785
    
    echo "<font size=-1><ol>
786
             <li><font color=red>Red</font> indicates nodes other than PCs.
787
                 A $idlemark mark by the node count indicates that the
Leigh B. Stoller's avatar
Leigh B. Stoller committed
788 789
                 experiment is currently considered idle. The number of
                 local pcs is indicated in the parens. 
790 791 792 793 794 795 796 797 798
             <li>A $stalemark indicates that the data is stale, and
		 at least one node in the experiment has not reported
		 on its proper schedule.\n";
    if ($parens) {
	# don't show this unless we did it... most users shouldn't ever
	# need to know that you can set expts to have their idleness ignored
	echo "Values are in parenthesis for idle-ignore experiments.\n";
    }
    echo "</ol></font>\n";
799 800
    
    echo "<center><b>Node Totals</b></center>\n";
801 802 803
    echo "<table border=0
                 cellpadding=1 cellspacing=1 align=center>\n";
    $total = 0;
804
    ksort($total_usage);
805 806 807 808
    while (list($type, $count) = each($total_usage)) {
	    $total += $count;
	    echo "<tr>
                    <td align=right>${type}:</td>
809
                    <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
810 811 812 813 814
                    <td align=center>$count</td>
                  </tr>\n";
    }
    echo "<tr>
             <td align=right><hr></td>
815
             <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
816 817 818 819
             <td align=center><hr></td>
          </tr>\n";
    echo "<tr>
             <td align=right><b>Total</b>:</td>
820
             <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
821 822 823 824
             <td align=center>$total</td>
          </tr>\n";
    
    echo "</table>\n";
825 826
} # if ($thumb && !$idle)
} # if (mysql_num_rows($experiments_result))
827 828 829 830 831 832

#
# Standard Testbed Footer
# 
PAGEFOOTER();
?>