nodecontrol_list.php3 15.2 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2 3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
5 6
# All rights reserved.
#
7 8
include("defs.php3");

9 10 11 12 13 14
#
# This page is used for both admin node control, and for mere user
# information purposes. Be careful about what you do outside of
# $isadmin tests.
# 

15 16 17
#
# Standard Testbed Header
#
18
PAGEHEADER("Node Control Center");
19

20 21 22
#
# Only known and logged in users can do this.
#
23 24 25
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
26 27

#
28 29
# Verify page arguments.
# 
30 31 32
if (isset($user)) {
    if ($user == "") {
	$user = $uid;
33
    }
34 35
    elseif (! User::ValidWebID($user)) {
	PAGEARGERROR("Invalid characters in '$user'");
36
    }
37 38
    elseif (! ($target_user = User::Lookup($user))) {
	USERERROR("The user $user is not a valid user", 1);
39
    }
40 41 42 43 44
    elseif (! $target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
	USERERROR("You do not have permission to do this!", 1);
    }
    $target_uid  = $target_user->uid();
    $target_idx  = $target_user->uid_idx();
45 46
}
else {
47 48 49
    $target_uid  = $uid;
    $target_idx  = $this_user->uid_idx();
    $target_user = $this_user;
50
}
51

52 53
echo "<b>Show: <a href='nodecontrol_list.php3?showtype=summary'>summary</a>,
               <a href='nodecontrol_list.php3?showtype=pcs'>pcs</a>,
54
               <a href='floormap.php3'>wireless maps</a>,
55 56
               <a href='floormap.php3?feature=usrp'>
                  GNU USRP (software defined radio) maps</a>,
57 58
               <a href='nodecontrol_list.php3?showtype=wireless'>
                                                        wireless list</a>,
59
               <a href='robotmap.php3'>robot maps</a>,
60 61 62 63 64 65 66
               <a href='nodecontrol_list.php3?showtype=widearea'>widearea</a>";

if ($isadmin) {
    echo    ", <a href='nodecontrol_list.php3?showtype=virtnodes'>virtual</a>,
               <a href='nodecontrol_list.php3?showtype=physical'>physical</a>,
               <a href='nodecontrol_list.php3?showtype=all'>all</a>";
}
67
echo ".</b><br>\n";
68 69

if (!isset($showtype)) {
70
    $showtype='summary';
71 72
}

Chad Barb's avatar
 
Chad Barb committed
73 74 75
$additionalVariables = "";
$additionalLeftJoin  = "";

76 77 78 79 80 81 82
if (! strcmp($showtype, "summary")) {
    # Separate query below.
    $role   = "";
    $clause = "";
    $view   = "Free Node Summary";
}
elseif (! strcmp($showtype, "all")) {
83 84 85
    $role   = "(role='testnode' or role='virtnode')";
    $clause = "";
    $view   = "All";
86 87
}
elseif (! strcmp($showtype, "pcs")) {
88 89 90
    $role   = "(role='testnode')";
    $clause = "and (nt.class='pc')";
    $view   = "PCs";
91
}
92 93 94 95
elseif (! strcmp($showtype, "sharks")) {
    $role   = "(role='testnode')";
    $clause = "and (nt.class='shark')";
    $view   = "Sharks";
96 97
}
elseif (! strcmp($showtype, "virtnodes")) {
98 99 100 101
    $role   = "(role='virtnode')";
    $clause = "";
    $view   = "Virtual Nodes";
}
102 103 104 105 106
elseif (! strcmp($showtype, "physical")) {
    $role   = "";
    $clause = "(nt.isvirtnode=0)";
    $view   = "Physical Nodes";
}
107 108 109
elseif (! strcmp($showtype, "widearea")) {
    $role   = "(role='testnode')";
    $clause = "and (nt.isremotenode=1)";
Chad Barb's avatar
 
Chad Barb committed
110 111 112 113 114 115 116

    $additionalVariables = ",".
			   "wani.machine_type,".
			   "REPLACE(CONCAT_WS(', ',".
			   "wani.city,wani.state,wani.country,wani.zip), ".
		 	   "'USA, ','')".
			   "AS location, ".
117
	 		   "wani.connect_type, ".
118 119
			   "wani.hostname, " .
                           "wani.site";
Chad Barb's avatar
 
Chad Barb committed
120 121 122
    $additionalLeftJoin = "LEFT JOIN widearea_nodeinfo AS wani ".
			  "ON n.node_id=wani.node_id";

123
    $view   = "Widearea";
124
}
125 126 127 128 129 130 131 132 133
elseif (! strcmp($showtype, "wireless")) {
    $role   = "(role='testnode')";
    $clause = "and (loc.node_id is not null)";

    $additionalLeftJoin = "LEFT JOIN location_info AS loc ".
			  "ON n.node_id=loc.node_id";

    $view   = "Wireless";
}
134
else {
135 136 137
    $role   = "(role='testnode')";
    $clause = "and (nt.class='pc')";
    $view   = "PCs";
138
}
139 140 141 142 143
# If admin or widearea, show the vname too. 
$showvnames = 0;
if ($isadmin || !strcmp($showtype, "widearea")) {
    $showvnames = 1;
}
144

145 146 147 148 149 150 151 152
#
# Summary info very different.
# 
if (! strcmp($showtype, "summary")) {
    # Get permissions table so as not to show nodes the user is not allowed
    # to see.
    $perms = array();
    
153
    if (!$isadmin || isset($bypid)) {
154 155 156 157 158 159
	$query_result =
	    DBQueryFatal("select type from nodetypeXpid_permissions");

	while ($row = mysql_fetch_array($query_result)) {
	    $perms{$row[0]} = 0;
	}
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

	$pidclause = "";
	if (isset($bypid)) {
	    if ($bypid == "" || !TBvalid_pid($bypid)) {
		PAGEARGERROR("Invalid characters in 'bypid' argument!");
	    }
	    if (! TBValidProject($bypid)) {
		PAGEARGERROR("No such project '$bypid'!");
	    }
	    if (! TBProjAccessCheck($target_uid,
				    $bypid, $bypid, $TB_PROJECT_READINFO)){
		USERERROR("You are not a member of project '$bypid!", 1);
	    }
	    $pidclause = "and g.pid='$bypid'";
	}
	if ($isadmin) {
	    $query_result =
		DBQueryFatal("select distinct type ".
			     "  from nodetypeXpid_permissions ".
			     "where pid='$bypid'");
	}
	else {
	    $query_result =
		DBQueryFatal("select distinct type from group_membership as g ".
			     "left join nodetypeXpid_permissions as p ".
			     "     on g.pid=p.pid ".
186
			     "where uid_idx='$target_idx' $pidclause");
187
	}
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
	
	while ($row = mysql_fetch_array($query_result)) {
	    $perms{$row[0]} = 1;
	}
    }
    
    # Get totals by type.
    $query_result =
	DBQueryFatal("select n.type,count(*) from nodes as n ".
		     "left join node_types as nt on n.type=nt.type ".
		     "where (role='testnode') and ".
		     "      (nt.class!='shark' and nt.class!='pcRemote' ".
		     "      and nt.class!='pcplabphys') ".
		     "group BY n.type");

203 204
    $alltotal  = 0;
    $allfree   = 0;
Timothy Stack's avatar
 
Timothy Stack committed
205
    $allunknown = 0;
206
    $totals    = array();
Timothy Stack's avatar
 
Timothy Stack committed
207 208
    $freecounts = array();
    $unknowncounts = array();
209 210 211 212 213 214 215

    while ($row = mysql_fetch_array($query_result)) {
	$type  = $row[0];
	$count = $row[1];

	$totals[$type]    = $count;
	$freecounts[$type] = 0;
Timothy Stack's avatar
 
Timothy Stack committed
216
	$unknowncounts[$type] = 0;
217 218 219 220
    }

    # Get free totals by type.
    $query_result =
Timothy Stack's avatar
 
Timothy Stack committed
221
	DBQueryFatal("select n.eventstate,n.type,count(*) from nodes as n ".
222 223 224 225 226
		     "left join node_types as nt on n.type=nt.type ".
		     "left join reserved as r on r.node_id=n.node_id ".
		     "where (role='testnode') and ".
		     "      (nt.class!='shark' and nt.class!='pcRemote' ".
		     "      and nt.class!='pcplabphys') ".
227
		     "      and r.pid is null and n.reserved_pid is null ".
Timothy Stack's avatar
 
Timothy Stack committed
228
		     "group BY n.eventstate,n.type");
229 230

    while ($row = mysql_fetch_array($query_result)) {
Timothy Stack's avatar
 
Timothy Stack committed
231 232 233 234 235 236 237 238 239 240 241 242
	$type  = $row[1];
	$count = $row[2];
        # XXX Yeah, I'm a doofus and can't figure out how to do this in SQL.
	if (($row[0] == TBDB_NODESTATE_ISUP) ||
	    ($row[0] == TBDB_NODESTATE_PXEWAIT) ||
	    ($row[0] == TBDB_NODESTATE_ALWAYSUP) ||
	    ($row[0] == TBDB_NODESTATE_POWEROFF)) {
	    $freecounts[$type] += $count;
	}
	else {
	    $unknowncounts[$type] += $count;
	}
243 244
    }

245
    $projlist = $target_user->ProjectAccessList($TB_PROJECT_CREATEEXPT);
246 247 248 249 250 251 252 253 254 255 256 257
    if (count($projlist) > 1) {
	echo "<b>By Project Permission: ";
	while (list($project) = each($projlist)) {
	    echo "<a href='nodecontrol_list.php3?".
		"showtype=summary&bypid=$project'>$project</a>,\n";
	}
	echo "<a href='nodecontrol_list.php3?showtype=summary'>".
	    "combined membership</a>.\n";
	echo "</b><br>\n";
    }

    echo "<br><center>
258
          <b>Free Node Summary</b>
259 260 261 262 263
          <br>\n";
    if (isset($bypid)) {
	echo "($bypid)<br><br>\n";
    }
    echo "<table>
264 265 266 267 268 269 270 271 272 273 274 275
          <tr>
             <th>Type</th>
             <th align=center>Free<br>Nodes</th>
             <th align=center>Total<br>Nodes</th>
          </tr>\n";

    foreach($totals as $key => $value) {
	$freecount = $freecounts[$key];

	# Check perm entry.
	if (isset($perms[$key]) && !$perms[$key])
	    continue;
276 277

	$allfree   += $freecount;
Timothy Stack's avatar
 
Timothy Stack committed
278
	$allunknown += $unknowncounts[$key];
279
	$alltotal  += $value;
Timothy Stack's avatar
 
Timothy Stack committed
280 281 282 283 284

	if ($unknowncounts[$key])
	    $ast = "*";
	else
	    $ast = "";
285
	
286 287 288 289 290 291
	echo "<tr>\n";
	if ($isadmin)
	    echo "<td><a href=editnodetype.php3?node_type=$key>\n";
	else
	    echo "<td><a href=shownodetype.php3?node_type=$key>\n";
	echo "           $key</a></td>
Timothy Stack's avatar
 
Timothy Stack committed
292
              <td align=center>${freecount}${ast}</td>
293 294 295
              <td align=center>$value</td>
              </tr>\n";
    }
296 297 298 299 300 301
    echo "<tr></tr>\n";
    echo "<tr>
            <td><b>Totals</b></td>
              <td align=center>$allfree</td>
              <td align=center>$alltotal</td>
              </tr>\n";
Timothy Stack's avatar
 
Timothy Stack committed
302

303 304
    if ($isadmin) {
	# Give admins the option to create a new type
305 306 307 308
	echo "<tr></tr>\n";
	echo "<th colspan=3 align=center>
                <a href=editnodetype.php3?new_type=1>Create a new type</a>
              </th>\n";
309
    }
310
    echo "</table>\n";
Timothy Stack's avatar
 
Timothy Stack committed
311 312 313 314
    if ($allunknown > 0) {
	    echo "<br><font size=-1><b>*</b> - Some nodes ($allunknown) are ".
		    "free, but currently in an unallocatable state.</font>";
    }
315 316 317 318
    PAGEFOOTER();
    exit();
}

319 320 321
#
# Suck out info for all the nodes.
# 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
322
$query_result =
323
    DBQueryFatal("select distinct n.node_id,n.phys_nodeid,n.type,ns.status, ".
324
		 "   n.def_boot_osid,r.pid,r.eid,nt.class,r.vname ".
Chad Barb's avatar
 
Chad Barb committed
325 326
		 "$additionalVariables ".
		 "from nodes as n ".
327
		 "left join node_types as nt on n.type=nt.type ".
328
		 "left join node_status as ns on n.node_id=ns.node_id ".
329
		 "left join reserved as r on n.node_id=r.node_id ".
Chad Barb's avatar
 
Chad Barb committed
330
		 "$additionalLeftJoin ".
331 332
		 "where $role $clause ".
		 "ORDER BY priority");
333 334 335 336

if (mysql_num_rows($query_result) == 0) {
    echo "<center>Oops, no nodes to show you!</center>";
    PAGEFOOTER();
337
    exit();
338
}
339

340
#
341
# First count up free nodes as well as status counts.
342
#
343 344 345 346 347
$num_free = 0;
$num_up   = 0;
$num_pd   = 0;
$num_down = 0;
$num_unk  = 0;
348
$freetypes= array();
349

350 351 352
while ($row = mysql_fetch_array($query_result)) {
    $pid                = $row[pid];
    $status             = $row[status];
353
    $type               = $row[type];
354

355 356 357
    if (! isset($freetypes[$type])) {
	$freetypes[$type] = 0;
    }
358 359 360
    if (!$pid) {
	$num_free++;
	$freetypes[$type]++;
361
	continue;
362
    }
363 364 365 366 367 368 369 370 371 372 373 374 375 376
    switch ($status) {
    case "up":
	$num_up++;
	break;
    case "possibly down":
    case "unpingable":
	$num_pd++;
	break;
    case "down":
	$num_down++;
	break;
    default:
	$num_unk++;
	break;
377 378
    }
}
379
$num_total = ($num_free + $num_up + $num_down + $num_pd + $num_unk);
380 381
mysql_data_seek($query_result, 0);

382 383 384 385 386 387
if (! strcmp($showtype, "widearea")) {
    echo "<a href=tutorial/docwrapper.php3?docname=widearea.html>
             Widearea Usage Notes</a>\n";
}

echo "<br><center><b>
388
       View: $view\n";
389 390 391

if (! strcmp($showtype, "widearea")) {
    echo "<br>
392
          <a href=widearea_nodeinfo.php3>(Widearea Link Metrics)</a><br>
Leigh B. Stoller's avatar
Leigh B. Stoller committed
393
          <a href=plabmetrics.php3>(PlanetLab Node Metrics)</a>\n";
394 395 396
}

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

398 399 400
SUBPAGESTART();

echo "<table>
401 402 403
       <tr><td align=right>
           <img src='/autostatus-icons/greenball.gif' alt=up>
           <b>Up</b></td>
404 405
           <td align=left>$num_up</td>
       </tr>
406 407 408
       <tr><td align=right nowrap>
           <img src='/autostatus-icons/yellowball.gif' alt='possibly down'>
           <b>Possibly Down</b></td>
409 410
           <td align=left>$num_pd</td>
       </tr>
411 412 413
       <tr><td align=right>
           <img src='/autostatus-icons/blueball.gif' alt=unknown>
           <b>Unknown</b></td>
414 415
           <td align=left>$num_unk</td>
       </tr>
416 417 418
       <tr><td align=right>
           <img src='/autostatus-icons/redball.gif' alt=down>
           <b>Down</b></td>
419 420
           <td align=left>$num_down</td>
       </tr>
421 422 423
       <tr><td align=right>
           <img src='/autostatus-icons/whiteball.gif' alt=free>
           <b>Free</b></td>
424 425
           <td align=left>$num_free</td>
       </tr>
426 427 428
       <tr><td align=right><b>Total</b></td>
           <td align=left>$num_total</td>
       </tr>
429 430 431 432 433
       <tr><td colspan=2 nowrap align=center>
               <b>Free Subtotals</b></td></tr>\n";

foreach($freetypes as $key => $value) {
    echo "<tr>
434
           <td align=right><a href=shownodetype.php3?node_type=$key>
435
                           $key</a></td>
436 437 438 439
           <td align=left>$value</td>
          </tr>\n";
}
echo "</table>\n";
440 441 442
SUBMENUEND_2B();

echo "<table border=2 cellpadding=2 cellspacing=2>\n";
443 444

echo "<tr>
445 446 447 448 449 450 451
          <th align=center>ID</th>\n";

if ($showvnames) {
    echo "<th align=center>Name</th>\n";
}

echo "    <th align=center>Type (Class)</th>
Chad Barb's avatar
 
Chad Barb committed
452
          <th align=center>Up?</th>\n";
453 454

if ($isadmin) {
Chad Barb's avatar
 
Chad Barb committed
455 456 457
    echo "<th align=center>PID</th>
          <th align=center>EID</th>
          <th align=center>Default<br>OSID</th>\n";
458
}
459 460
elseif (strcmp($showtype, "widearea")) {
    # Widearea nodes are always "free"
Chad Barb's avatar
 
Chad Barb committed
461
    echo "<th align=center>Free?</th>\n";
Chad Barb's avatar
 
Chad Barb committed
462 463 464
}

if (!strcmp($showtype, "widearea")) {
465 466
    echo "<th align=center>Site</th>
          <th align=center>Processor</th>
Chad Barb's avatar
 
Chad Barb committed
467
	  <th align=center>Connection</th>
468
	  <th align=center>Location</th>";
Chad Barb's avatar
 
Chad Barb committed
469 470
}
    
471
echo "</tr>\n";
472

473 474
while ($row = mysql_fetch_array($query_result)) {
    $node_id            = $row[node_id]; 
475
    $phys_nodeid        = $row[phys_nodeid]; 
476
    $type               = $row[type];
477
    $class              = $row["class"];
478
    $def_boot_osid      = $row[def_boot_osid];
Leigh B. Stoller's avatar
Leigh B. Stoller committed
479 480
    $pid                = $row[pid];
    $eid                = $row[eid];
481
    $vname              = $row[vname];
482
    $hostname           = $row[hostname];
483
    $status             = $row[status];
484

Chad Barb's avatar
 
Chad Barb committed
485
    if (!strcmp($showtype, "widearea")) {	
486
	$site         = $row[site];
Chad Barb's avatar
 
Chad Barb committed
487
	$machine_type = $row[machine_type];
488
	$location     = $row[location];
Chad Barb's avatar
 
Chad Barb committed
489
	$connect_type = $row[connect_type];
490
	$vname        = $row[hostname];
Chad Barb's avatar
 
Chad Barb committed
491 492
    } 

493
    echo "<tr>";
494

495
    # Admins get a link to expand the node.
496 497
    if ($isadmin ||
	(OPSGUY() && (!$pid || $pid == $TBOPSPID))) {
498 499 500 501
	echo "<td><A href='shownode.php3?node_id=$node_id'>$node_id</a> " .
	    (!strcmp($node_id, $phys_nodeid) ? "" :
	     "(<A href='shownode.php3?node_id=$phys_nodeid'>$phys_nodeid</a>)")
	    . "</td>\n";
502 503
    }
    else {
504 505 506
	echo "<td>$node_id " .
  	      (!strcmp($node_id, $phys_nodeid) ? "" : "($phys_nodeid)") .
	      "</td>\n";
507
    }
508 509 510 511 512 513 514

    if ($showvnames) {
	if ($vname)
	    echo "<td>$vname</td>\n";
	else
	    echo "<td>--</td>\n";
    }
515
    
516 517
    echo "   <td>$type ($class)</td>\n";

518 519 520 521
    if (!$pid)
	echo "<td align=center>
                  <img src='/autostatus-icons/whiteball.gif' alt=free></td>\n";
    elseif (!$status)
522 523 524
	echo "<td align=center>
                  <img src='/autostatus-icons/blueball.gif' alt=unk></td>\n";
    elseif ($status == "up")
525 526
	echo "<td align=center>
                  <img src='/autostatus-icons/greenball.gif' alt=up></td>\n";
527
    elseif ($status == "down")
528 529
	echo "<td align=center>
                  <img src='/autostatus-icons/redball.gif' alt=down></td>\n";
530 531 532
    else
	echo "<td align=center>
                  <img src='/autostatus-icons/yellowball.gif' alt=unk></td>\n";
533 534 535 536

    # Admins get pid/eid/vname, but mere users yes/no.
    if ($isadmin) {
	if ($pid) {
Mike Hibler's avatar
Mike Hibler committed
537 538
	    echo "<td><a href=showproject.php3?pid=$pid>$pid</a></td>
                  <td><a href=showexp.php3?pid=$pid&eid=$eid>$eid</a></td>\n";
539 540 541 542 543 544 545 546 547 548
	}
	else {
	    echo "<td>--</td>
   	          <td>--</td>\n";
	}
	if ($def_boot_osid && TBOSInfo($def_boot_osid, $osname, $ospid))
	    echo "<td>$osname</td>\n";
	else
	    echo "<td>&nbsp</td>\n";
    }
549
    elseif (strcmp($showtype, "widearea")) {
550
	if ($pid)
551
	    echo "<td>--</td>\n";
552 553 554
	else
	    echo "<td>Yes</td>\n";
    }
Chad Barb's avatar
 
Chad Barb committed
555 556

    if (!strcmp($showtype, "widearea")) {	
557 558
	echo "<td>$site</td>
	      <td>$machine_type</td>
Chad Barb's avatar
 
Chad Barb committed
559 560 561
	      <td>$connect_type</td>
	      <td><font size='-1'>$location</font></td>\n";
    }
562
    
563
    echo "</tr>\n";
564 565 566
}

echo "</table>\n";
567
SUBPAGEEND();
568 569 570 571 572

#
# Standard Testbed Footer
# 
PAGEFOOTER();
573 574 575
?>