showexp_list.php3 25.1 KB
Newer Older
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
#
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 Stoller's avatar
Leigh 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      = "";
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 Stoller's avatar
Leigh Stoller committed
71 72
if (! isset($showtype))
    $showtype="active";
73 74
if (! isset($sortby))
    $sortby = "normal";
Chad Barb's avatar
Chad Barb committed
75 76
if (! isset($thumb)) 
    $thumb = 0;
77 78
if (! isset($noignore)) 
    $noignore = 0;
79

Chad Barb's avatar
Chad Barb committed
80
echo "<b>Show: ";
81

Chad Barb's avatar
Chad Barb committed
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, ";
    }    
Chad Barb's avatar
Chad Barb committed
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 Stoller's avatar
Leigh 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 Stoller's avatar
Leigh Stoller committed
121

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

Leigh Stoller's avatar
Leigh 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 Stoller's avatar
Leigh Stoller committed
137
    $title  = "Active";
138
    $having = "having (ncount>0)";
139
    $active = 1;
Leigh Stoller's avatar
Leigh Stoller committed
140 141
}
elseif (! strcmp($showtype, "batch")) {
142 143
    $clause = "(e.batchmode=1 and e.state!='" .
               $TB_EXPTSTATE_SWAPPED . "')";
Leigh Stoller's avatar
Leigh 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 Stoller's avatar
Leigh 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 Stoller's avatar
Leigh Stoller committed
164
    $title  = "Active";
165
    $having = "having (ncount>0)";
166
    $active = 1;
167
}
168

Chad Barb's avatar
Chad Barb committed
169 170 171


if (!$idle) {
Chad Barb's avatar
Chad Barb committed
172 173 174
    echo "<b>View: ";

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

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

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

Leigh Stoller's avatar
Leigh 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"))
Chad Barb's avatar
Chad Barb committed
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 Stoller's avatar
Leigh 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 Stoller's avatar
Leigh 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 Stoller's avatar
Leigh 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 Stoller's avatar
Leigh Stoller committed
325
           <h2>$title Experiments</h2>
326
          </center>\n";
327

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
      }
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.
    #
Chad Barb's avatar
Chad Barb committed
398
if ($thumb && !$idle) {
Chad Barb's avatar
Chad Barb committed
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>";
    }
Chad Barb's avatar
Chad Barb committed
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"];
Chad Barb's avatar
Chad Barb committed
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)" : "";
Chad Barb's avatar
Chad Barb committed
429 430
	
	if ($idle && ($str=="&nbsp;" || !$pcs)) { continue; }
Chad Barb's avatar
Chad Barb committed
431

Chad Barb's avatar
Chad Barb committed
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".
Chad Barb's avatar
Chad Barb committed
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>";
444

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

	    echo "<td>".
		 "<table border=0 cellpadding=4 cellspacing=0>".
		 "<tr>".
453
		 "<td width=160 align=center>".
Chad Barb's avatar
Chad Barb committed
454
	         "<a href='shownsfile.php3?pid=$pid&eid=$eid'>".
455
		 "<img border=1 class='stealth' ".
456
		 " src='showthumb.php3?idx=$rsrcidx'>".
Chad Barb's avatar
Chad Barb committed
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";
Chad Barb's avatar
Chad Barb committed
467 468


Chad Barb's avatar
Chad Barb committed
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"] . " " .
Chad Barb's avatar
Chad Barb committed
479 480 481
			"(" . $lastexpnodelogins["uid"] . ")";
		} elseif ($state=="active") {
		    $daysidle=$row["lastswap"];
482
		    $lastlogin .= "$date swapin";
Chad Barb's avatar
Chad Barb committed
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";
		}
	    }	
Chad Barb's avatar
Chad Barb committed
489

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

Chad Barb's avatar
Chad Barb committed
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";
	    }

Chad Barb's avatar
Chad Barb committed
516 517
	    echo "</td></tr></table> \n";
	    echo "</td>";
Chad Barb's avatar
Chad Barb committed
518

Leigh Stoller's avatar
Leigh Stoller committed
519 520
	    $thumbCount++;
	    if (($thumbCount % 2) == 0) { echo "</tr><tr>\n"; }
Chad Barb's avatar
Chad Barb committed
521
	}
Chad Barb's avatar
Chad Barb committed
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'>
Chad Barb's avatar
Chad Barb committed
535
                  PID</a></th>
536 537 538
              <th >
               <a class='static'
                  href='showexp_list.php3?showtype=$showtype&sortby=eid$ni'>
Chad Barb's avatar
Chad Barb committed
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 Stoller's avatar
Leigh 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 604 605 606 607
        #
        # No longer show Geni experiments here, going to be bad news for
        # mere users.
        #
        if ($nonlocal_id && !$isadmin) {
            continue;
        }

608 609 610 611
	if ($state == "active" && isset($sidx)) {
	    if (! ($user = User::Lookup($sidx))) {
		TBERROR("Could not lookup object for user $sidx", 1);
	    }
612
	}
613 614 615 616 617 618 619 620
	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)" : "";
621 622 623
	
	if ($swapreqs && !$isidle) {
	    $swapreqs = "";
624
	    mysql_query("update experiments set swap_requests='0' ".
625 626 627
			"where pid='$pid' and eid='$eid'");
	}

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

690
	if ($idle && (!$pcs || !$isidle)) { continue; }
691

692 693
	$nodes   = 0;
	$special = 0;
694 695 696 697
	reset($perexp_usage);
	if (isset($perexp_usage["$pid:$eid"])) {
	    while (list ($class, $count) = each($perexp_usage["$pid:$eid"])) {
		$nodes += $count;
698
		if (strcmp($class, "pc")) {
699
		    $special = 1;
700 701 702 703
		} else {
		    $pcs = $count;
		}

704 705 706 707 708 709
		# 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;
710
	    }
711
	}
712

713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
	$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')\"";
	}

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

Chad Barb's avatar
Chad Barb committed
761
	if ($idletime == -1) {
762
	    $idlestr = "&nbsp;";
Chad Barb's avatar
Chad Barb committed
763
	} else {
764 765 766 767
	    $idlestr = "$idletime";
	    # Order between the next two lines determines if the
	    # stalemark goes inside or outside the parens
	    if ($stale && $pcs > 0) { $idlestr .= $stalemark; }
768
	    if ($ignore && $idletime !=0) {
769 770
		$idlestr = "($idlestr)";
		$parens = 1;
771
	    }
Chad Barb's avatar
Chad Barb committed
772
	}
773
	echo "<td>$idlestr</td>";
774 775
	
	if ($showlastlogin) echo "$lastlogin\n";
776
	if ($idle) echo "$foo\n";
777

778
	if (! ($openlist_member || $protogeni)) {
779 780
	    echo "<td>$name</td>\n";
	}
781 782
	if ($protogeni) {
	    echo "<td>$nonlocal_user_id</td>\n";
783
	    echo "<td>$created</td>\n";
784 785 786 787
	}
	else {
	    echo "<td><A href='$showuser_url'>$huid</A>$user_affil_text</td>\n";
	}
788
	echo "</tr>\n";
789 790
    }
    echo "</table>\n";
791

792 793
    
    echo "<font size=-1><ol>
794
             <li><font color=red>Red</font> indicates nodes other than PCs.
795
                 A $idlemark mark by the node count indicates that the
Leigh Stoller's avatar
Leigh Stoller committed
796 797
                 experiment is currently considered idle. The number of
                 local pcs is indicated in the parens. 
798 799 800 801 802 803 804 805 806
             <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";
807 808
    
    echo "<center><b>Node Totals</b></center>\n";
809 810 811
    echo "<table border=0
                 cellpadding=1 cellspacing=1 align=center>\n";
    $total = 0;
812
    ksort($total_usage);
813 814 815 816
    while (list($type, $count) = each($total_usage)) {
	    $total += $count;
	    echo "<tr>
                    <td align=right>${type}:</td>
817
                    <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
818 819 820 821 822
                    <td align=center>$count</td>
                  </tr>\n";
    }
    echo "<tr>
             <td align=right><hr></td>
823
             <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
824 825 826 827
             <td align=center><hr></td>
          </tr>\n";
    echo "<tr>
             <td align=right><b>Total</b>:</td>
828
             <td>&nbsp; &nbsp; &nbsp; &nbsp;</td>
829 830 831 832
             <td align=center>$total</td>
          </tr>\n";
    
    echo "</table>\n";
Chad Barb's avatar
Chad Barb committed
833 834
} # if ($thumb && !$idle)
} # if (mysql_num_rows($experiments_result))
835 836 837 838 839 840

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