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

10 11 12 13 14 15
#
# 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.
# 

16 17 18
#
# Only known and logged in users can do this.
#
19 20 21
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
22 23

#
24
# Verify page arguments.
25 26 27 28 29 30 31
#
$optargs = OptionalPageArguments("target_user",	PAGEARG_USER,
				 "showtype",    PAGEARG_STRING,
				 "bypid",       PAGEARG_STRING);

if (isset($target_user)) {
    if (! $target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
32 33 34 35
	USERERROR("You do not have permission to do this!", 1);
    }
    $target_uid  = $target_user->uid();
    $target_idx  = $target_user->uid_idx();
36 37
}
else {
38 39 40
    $target_uid  = $uid;
    $target_idx  = $this_user->uid_idx();
    $target_user = $this_user;
41
}
42

43 44 45 46 47
#
# Standard Testbed Header
#
PAGEHEADER("Node Control Center");

48 49
echo "<b>Show: <a href='nodecontrol_list.php3?showtype=summary'>summary</a>,
               <a href='nodecontrol_list.php3?showtype=pcs'>pcs</a>,
50 51
               <a href='floormap.php3'>wireless maps</a>,
               <a href='nodecontrol_list.php3?showtype=wireless'>
52 53 54 55 56 57 58
                                                        wireless list</a>,";
if ($TBMAINSITE) {
    echo "     <a href='floormap.php3?feature=usrp'>
                  GNU USRP (software defined radio) maps</a>,
               <a href='robotmap.php3'>robot maps</a>, ";
}
echo "         <a href='nodecontrol_list.php3?showtype=widearea'>widearea</a>";
59 60

if ($isadmin) {
61 62
    echo    ", <a href='nodeutilization.php'>utilization</a>,
               <a href='nodecontrol_list.php3?showtype=virtnodes'>virtual</a>,
63 64 65
               <a href='nodecontrol_list.php3?showtype=physical'>physical</a>,
               <a href='nodecontrol_list.php3?showtype=all'>all</a>";
}
66
echo ".</b><br>\n";
67 68

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

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

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

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

122
    $view   = "Widearea";
123
}
124 125 126 127 128 129 130 131 132
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";
}
133 134 135 136 137
elseif (preg_match("/^[-\w]+$/", $showtype)) {
    $role   = "(role='testnode')";
    $clause = "and (nt.type='$showtype')";
    $view   = "only <a href=shownodetype.php3?node_type=$showtype>$showtype</a>";
}
138
else {
139 140 141
    $role   = "(role='testnode')";
    $clause = "and (nt.class='pc')";
    $view   = "PCs";
142
}
143 144 145 146 147
# If admin or widearea, show the vname too. 
$showvnames = 0;
if ($isadmin || !strcmp($showtype, "widearea")) {
    $showvnames = 1;
}
148

149 150 151 152 153 154 155 156
#
# 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();
    
157
    if (!$isadmin || isset($bypid)) {
158 159 160 161 162 163
	$query_result =
	    DBQueryFatal("select type from nodetypeXpid_permissions");

	while ($row = mysql_fetch_array($query_result)) {
	    $perms{$row[0]} = 0;
	}
164 165 166 167 168 169

	$pidclause = "";
	if (isset($bypid)) {
	    if ($bypid == "" || !TBvalid_pid($bypid)) {
		PAGEARGERROR("Invalid characters in 'bypid' argument!");
	    }
170
	    if (! ($target_project = Project::Lookup($bypid))) {
171 172
		PAGEARGERROR("No such project '$bypid'!");
	    }
173 174
	    if (!$target_project->AccessCheck($this_user,
					      $TB_PROJECT_READINFO)){
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
		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 ".
190
			     "where uid_idx='$target_idx' $pidclause");
191
	}
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
	
	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");

207 208
    $alltotal  = 0;
    $allfree   = 0;
Timothy Stack's avatar
 
Timothy Stack committed
209
    $allunknown = 0;
210
    $totals    = array();
Timothy Stack's avatar
 
Timothy Stack committed
211 212
    $freecounts = array();
    $unknowncounts = array();
213 214 215 216 217 218 219

    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
220
	$unknowncounts[$type] = 0;
221 222 223 224
    }

    # Get free totals by type.
    $query_result =
Timothy Stack's avatar
 
Timothy Stack committed
225
	DBQueryFatal("select n.eventstate,n.type,count(*) from nodes as n ".
226 227 228 229 230
		     "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') ".
231
		     "      and r.pid is null and n.reserved_pid is null ".
Timothy Stack's avatar
 
Timothy Stack committed
232
		     "group BY n.eventstate,n.type");
233 234

    while ($row = mysql_fetch_array($query_result)) {
Timothy Stack's avatar
 
Timothy Stack committed
235 236 237 238 239 240 241 242 243 244 245 246
	$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;
	}
247 248
    }

249
    $projlist = $target_user->ProjectAccessList($TB_PROJECT_CREATEEXPT);
250 251 252 253 254 255 256 257 258 259 260 261
    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>
262
          <b>Free Node Summary</b>
263 264 265 266 267
          <br>\n";
    if (isset($bypid)) {
	echo "($bypid)<br><br>\n";
    }
    echo "<table>
268 269 270 271 272 273 274 275 276 277 278 279
          <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;
280 281

	$allfree   += $freecount;
Timothy Stack's avatar
 
Timothy Stack committed
282
	$allunknown += $unknowncounts[$key];
283
	$alltotal  += $value;
Timothy Stack's avatar
 
Timothy Stack committed
284 285 286 287 288

	if ($unknowncounts[$key])
	    $ast = "*";
	else
	    $ast = "";
289
	
290 291 292 293 294 295
	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
296
              <td align=center>${freecount}${ast}</td>
297 298 299
              <td align=center>$value</td>
              </tr>\n";
    }
300 301 302 303 304 305
    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
306

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

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

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

344
#
345
# First count up free nodes as well as status counts.
346
#
347 348 349 350 351
$num_free = 0;
$num_up   = 0;
$num_pd   = 0;
$num_down = 0;
$num_unk  = 0;
352
$freetypes= array();
353

354
while ($row = mysql_fetch_array($query_result)) {
355 356 357
    $pid                = $row["pid"];
    $status             = $row["status"];
    $type               = $row["type"];
358

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

386
if (! strcmp($showtype, "widearea")) {
387
    echo "<a href='$WIKIDOCURL/widearea'>
388 389 390 391
             Widearea Usage Notes</a>\n";
}

echo "<br><center><b>
392
       View: $view\n";
393 394 395

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

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

402 403 404
SUBPAGESTART();

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

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

446
echo "<table border=2 cellpadding=2 cellspacing=2 id='nodelist'>\n";
447

448
echo "<thead class='sort'>";
449
echo "<tr>
450 451 452 453 454 455 456
          <th align=center>ID</th>\n";

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

echo "    <th align=center>Type (Class)</th>
457
          <th align=center class='sorttable_nosort'>Up?</th>\n";
458 459

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

if (!strcmp($showtype, "widearea")) {
470 471
    echo "<th align=center>Site</th>
          <th align=center>Processor</th>
Chad Barb's avatar
 
Chad Barb committed
472
	  <th align=center>Connection</th>
473
	  <th align=center>Location</th>";
Chad Barb's avatar
 
Chad Barb committed
474 475
}
    
476
echo "</tr></thead>\n";
477

478
while ($row = mysql_fetch_array($query_result)) {
479 480 481
    $node_id            = $row["node_id"]; 
    $phys_nodeid        = $row["phys_nodeid"]; 
    $type               = $row["type"];
482
    $class              = $row["class"];
483 484 485 486 487
    $def_boot_osid      = $row["def_boot_osid"];
    $pid                = $row["pid"];
    $eid                = $row["eid"];
    $vname              = $row["vname"];
    $status             = $row["status"];
488

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

497
    echo "<tr>";
498

499
    # Admins get a link to expand the node.
500 501
    if ($isadmin ||
	(OPSGUY() && (!$pid || $pid == $TBOPSPID))) {
502 503 504 505
	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";
506 507
    }
    else {
508 509 510
	echo "<td>$node_id " .
  	      (!strcmp($node_id, $phys_nodeid) ? "" : "($phys_nodeid)") .
	      "</td>\n";
511
    }
512 513 514 515 516 517 518

    if ($showvnames) {
	if ($vname)
	    echo "<td>$vname</td>\n";
	else
	    echo "<td>--</td>\n";
    }
519
    
520 521
    echo "   <td>$type ($class)</td>\n";

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

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

    if (!strcmp($showtype, "widearea")) {	
564 565
	echo "<td>$site</td>
	      <td>$machine_type</td>
Chad Barb's avatar
 
Chad Barb committed
566 567 568
	      <td>$connect_type</td>
	      <td><font size='-1'>$location</font></td>\n";
    }
569
    
570
    echo "</tr>\n";
571 572 573
}

echo "</table>\n";
574 575 576
echo "<script type='text/javascript' language='javascript'>
         sorttable.makeSortable(getObjbyName('nodelist'));
      </script>\n";
577
SUBPAGEEND();
578 579 580 581 582

#
# Standard Testbed Footer
# 
PAGEFOOTER();
583 584 585
?>