nodecontrol_list.php3 15.4 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
#
# Standard Testbed Header
#
19
PAGEHEADER("Node Control Center");
20

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

#
29
# Verify page arguments.
30 31 32 33 34 35 36
#
$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)) {
37 38 39 40
	USERERROR("You do not have permission to do this!", 1);
    }
    $target_uid  = $target_user->uid();
    $target_idx  = $target_user->uid_idx();
41 42
}
else {
43 44 45
    $target_uid  = $uid;
    $target_idx  = $this_user->uid_idx();
    $target_user = $this_user;
46
}
47

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

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

if (!isset($showtype)) {
67
    $showtype='summary';
68 69
}

Chad Barb's avatar
 
Chad Barb committed
70 71 72
$additionalVariables = "";
$additionalLeftJoin  = "";

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

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

120
    $view   = "Widearea";
121
}
122 123 124 125 126 127 128 129 130
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";
}
131
else {
132 133 134
    $role   = "(role='testnode')";
    $clause = "and (nt.class='pc')";
    $view   = "PCs";
135
}
136 137 138 139 140
# If admin or widearea, show the vname too. 
$showvnames = 0;
if ($isadmin || !strcmp($showtype, "widearea")) {
    $showvnames = 1;
}
141

142 143 144 145 146 147 148 149
#
# 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();
    
150
    if (!$isadmin || isset($bypid)) {
151 152 153 154 155 156
	$query_result =
	    DBQueryFatal("select type from nodetypeXpid_permissions");

	while ($row = mysql_fetch_array($query_result)) {
	    $perms{$row[0]} = 0;
	}
157 158 159 160 161 162

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

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

    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
213
	$unknowncounts[$type] = 0;
214 215 216 217
    }

    # Get free totals by type.
    $query_result =
Timothy Stack's avatar
 
Timothy Stack committed
218
	DBQueryFatal("select n.eventstate,n.type,count(*) from nodes as n ".
219 220 221 222 223
		     "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') ".
224
		     "      and r.pid is null and n.reserved_pid is null ".
Timothy Stack's avatar
 
Timothy Stack committed
225
		     "group BY n.eventstate,n.type");
226 227

    while ($row = mysql_fetch_array($query_result)) {
Timothy Stack's avatar
 
Timothy Stack committed
228 229 230 231 232 233 234 235 236 237 238 239
	$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;
	}
240 241
    }

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

	$allfree   += $freecount;
Timothy Stack's avatar
 
Timothy Stack committed
275
	$allunknown += $unknowncounts[$key];
276
	$alltotal  += $value;
Timothy Stack's avatar
 
Timothy Stack committed
277 278 279 280 281

	if ($unknowncounts[$key])
	    $ast = "*";
	else
	    $ast = "";
282
	
283 284 285 286 287 288
	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
289
              <td align=center>${freecount}${ast}</td>
290 291 292
              <td align=center>$value</td>
              </tr>\n";
    }
293 294 295 296 297 298
    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
299

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

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

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

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

347
while ($row = mysql_fetch_array($query_result)) {
348 349 350
    $pid                = $row["pid"];
    $status             = $row["status"];
    $type               = $row["type"];
351

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

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

echo "<br><center><b>
385
       View: $view\n";
386 387 388

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

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

395 396 397
SUBPAGESTART();

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

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

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

441
echo "<thead class='sort'>";
442
echo "<tr>
443 444 445 446 447 448 449
          <th align=center>ID</th>\n";

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

echo "    <th align=center>Type (Class)</th>
450
          <th align=center class='sorttable_nosort'>Up?</th>\n";
451 452

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

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

471
while ($row = mysql_fetch_array($query_result)) {
472 473 474
    $node_id            = $row["node_id"]; 
    $phys_nodeid        = $row["phys_nodeid"]; 
    $type               = $row["type"];
475
    $class              = $row["class"];
476 477 478 479 480
    $def_boot_osid      = $row["def_boot_osid"];
    $pid                = $row["pid"];
    $eid                = $row["eid"];
    $vname              = $row["vname"];
    $status             = $row["status"];
481

Chad Barb's avatar
 
Chad Barb committed
482
    if (!strcmp($showtype, "widearea")) {	
483 484 485 486 487
	$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
488 489
    } 

490
    echo "<tr>";
491

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

    if ($showvnames) {
	if ($vname)
	    echo "<td>$vname</td>\n";
	else
	    echo "<td>--</td>\n";
    }
512
    
513 514
    echo "   <td>$type ($class)</td>\n";

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

    # Admins get pid/eid/vname, but mere users yes/no.
    if ($isadmin) {
	if ($pid) {
Mike Hibler's avatar
Mike Hibler committed
534 535
	    echo "<td><a href=showproject.php3?pid=$pid>$pid</a></td>
                  <td><a href=showexp.php3?pid=$pid&eid=$eid>$eid</a></td>\n";
536 537 538 539 540
	}
	else {
	    echo "<td>--</td>
   	          <td>--</td>\n";
	}
541 542 543
	if ($def_boot_osid &&
	    ($osinfo = OSinfo::Lookup($def_boot_osid))) {
	    $osname = $osinfo->osname();
544
	    echo "<td>$osname</td>\n";
545
	}
546 547 548
	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 568 569
echo "<script type='text/javascript' language='javascript'>
         sorttable.makeSortable(getObjbyName('nodelist'));
      </script>\n";
570
SUBPAGEEND();
571 572 573 574 575

#
# Standard Testbed Footer
# 
PAGEFOOTER();
576 577 578
?>