diff --git a/configure b/configure index 4a9fedec0e6b5b434ca36e5ca21ed22a8d3809d2..d4a4436e807ae0aa1704a0f1929fcd2a90a63640 100755 --- a/configure +++ b/configure @@ -1559,7 +1559,7 @@ outfiles="$outfiles Makeconf GNUmakefile \ utils/cvsupd.pl utils/newnode utils/grantnodetype \ utils/nsgen/GNUmakefile utils/nsgen/webnsgen \ utils/link_config utils/import_commitlog utils/dhcpd_wrapper \ - utils/opsreboot utils/deletenode utils/webdeletenode \ + utils/opsreboot utils/deletenode utils/webdeletenode utils/spewleds \ www/GNUmakefile www/defs.php3 www/dbdefs.php3 \ www/swish.conf www/websearch \ vis/GNUmakefile vis/webvistopology vis/dbvistopology \ diff --git a/utils/GNUmakefile.in b/utils/GNUmakefile.in index bd0e935396d4e3deba64a10543a73c2d4b8b1f01..054396dc8841ffb3cde2bceaa90802704630305d 100644 --- a/utils/GNUmakefile.in +++ b/utils/GNUmakefile.in @@ -18,7 +18,7 @@ BIN_SCRIPTS = delay_config sshtb create_image node_admin link_config SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \ eventping grantnodetype import_commitlog dhcpd_wrapper \ opsreboot deletenode node_statewait -LIBEXEC_SCRIPTS = webcreateimage newnode webdeletenode +LIBEXEC_SCRIPTS = webcreateimage newnode webdeletenode spewleds # # Force dependencies on the scripts so that they will be rerun through diff --git a/utils/spewleds.in b/utils/spewleds.in new file mode 100755 index 0000000000000000000000000000000000000000..c08cf18e38f4702421e4dff6f28ce582b5a7dd66 --- /dev/null +++ b/utils/spewleds.in @@ -0,0 +1,79 @@ +#!/usr/bin/perl -wT + +# +# EMULAB-COPYRIGHT +# Copyright (c) 2004 University of Utah and the Flux Group. +# All rights reserved. +# + +# +# Simple script to connect to the LED status port on a stargate and spew the LED status +# to stdout +# + +use English; +use Getopt::Std; +use IO::Socket; + +use lib '@prefix@/lib'; +use libdb; + +my $LED_STATUS_PORT = 1812; + +# Make output unbuffered +$| = 1; + +# +# Args +# +if (@ARGV != 1) { + die "Usage: spewleds mote\n"; +} + +my ($mote) = @ARGV; + +# +# Untaint the argument. +# +if ($mote =~ /^([-\w.]+)$/) { + $mote = $1; +} else { + die("Tainted node name: $mote"); +} + +# +# Make sure they have permissions to see this node +# +if (! TBNodeAccessCheck($UID, TB_NODEACCESS_READINFO, $mote)) { + print STDERR + "*** osload: Not enough permission to view that node!\n"; + exit 1; +} + +# +# Make sure it's a stargate or garcia (XXX garcia should be temporary) +# +my ($type, $class) = TBNodeType($mote); +if ($type ne "garcia" && $class ne "sg") { + die "Node $mote is not of the correct type ($type,$class)\n"; +} + +# +# Connect to the LED status port +# +my $sock = new IO::Socket::INET ( + PeerAddr => "$mote", + PeerPort => "$LED_STATUS_PORT", + Proto => 'tcp', + ); +die "Could not create socket: $!\n" unless $sock; + +# +# Okie, just loop on this guy forever +# +while (my $string = <$sock>) { + print "$string" +} + +close $sock; +exit 0; diff --git a/www/BlinkenLichten.class b/www/BlinkenLichten.class index 3e6b3fb2c59e0fe162a19145fae62db8317dcb69..265cbe65d9a70cee43c4783c859d4475deaf7770 100644 Binary files a/www/BlinkenLichten.class and b/www/BlinkenLichten.class differ diff --git a/www/BlinkenLichten.java b/www/BlinkenLichten.java index 85237de7514df964d3594687ec272606cf618d8f..0a40a5c4cabb2dc218ba64b08f34f6b03d9a2793 100644 --- a/www/BlinkenLichten.java +++ b/www/BlinkenLichten.java @@ -34,7 +34,9 @@ public class BlinkenLichten /** * The current status of the light, just on/off for now. */ - private boolean on; + private boolean red_on; + private boolean green_on; + private boolean yellow_on; public BlinkenLichten() { @@ -79,15 +81,19 @@ public class BlinkenLichten public void run() { - byte buffer[] = new byte[1]; + byte buffer[] = new byte[6]; try { /* Just read a character at a time from the other side. */ - while( this.is.read(buffer) > 0 ) + // Bad, bad, bad + //while( this.is.read(buffer) > 0 ) + while( this.is.read(buffer,0,6) > 0 ) { /* 1 == on, 0 == off */ - this.on = (buffer[0] == '1'); + this.red_on = (buffer[0] == '1'); + this.green_on = (buffer[2] == '1'); + this.yellow_on = (buffer[4] == '1'); repaint(); } @@ -108,16 +114,29 @@ public class BlinkenLichten public void paint(Graphics g) { Dimension size = getSize(); + int width = size.width / 3; + int height = size.height; /* - * Just paint the entire canvas provided to the applet, no need to get - * fancy. + * Paint each of the three LED values */ - if( this.on ) + if (this.red_on) g.setColor(Color.red); else - g.setColor(Color.black); - g.fillRect(0, 0, size.width, size.height); + g.setColor(Color.red.darker().darker()); + g.fillRect(0, 0, width, height); + + if (this.green_on) + g.setColor(Color.green); + else + g.setColor(Color.green.darker().darker()); + g.fillRect(width, 0, width, height); + + if (this.yellow_on) + g.setColor(Color.yellow); + else + g.setColor(Color.yellow.darker().darker()); + g.fillRect(width *2, 0, width, height); } public void destroy() diff --git a/www/ledpipe.php3 b/www/ledpipe.php3 index 675d18a6f5e1dde2b25052f162cfed5f00e0dfa9..166efb75664b012bf243cfb591d03d02fb82bd80 100644 --- a/www/ledpipe.php3 +++ b/www/ledpipe.php3 @@ -7,12 +7,7 @@ include("defs.php3"); # -# Standard Testbed Header -# -#PAGEHEADER("Watch Experiment Log"); - -# -# Only known and logged in users can end experiments. +# Only known and logged in users can watch LEDs # $uid = GETLOGIN(); LOGGEDINORDIE($uid); @@ -42,11 +37,48 @@ header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); flush(); -for ($lpc = 0; $lpc < 30; $lpc++) { - sleep(1); - $on_off = $lpc % 2; - echo "$on_off"; - flush(); +#for ($lpc = 0; $lpc < 30; $lpc++) { + # sleep(1); + # $on_off = $lpc % 2; + # echo "$on_off"; + # flush(); + #} + +# +# Silly, I can't get php to get the buffering behavior I want with a socket, so +# we'll open a pipe to a perl process +# +$socket = popen("$TBSUEXEC_PATH $uid nobody spewleds $node","r"); +if (!$socket) { + USERERROR("Error opening $node - $errstr",1); +} + +# +# Clean up when the remote user disconnects +# +function SPEWCLEANUP() +{ + global $socket; + + if (!$socket || !connection_aborted()) { + exit(); + } + pclose($socket); + exit(); +} +ignore_user_abort(1); +register_shutdown_function("SPEWCLEANUP"); + +# +# Just loop forver reading from the socket +# +while(!feof($socket)) { + + # Bad rob! No biscuit! + $onoff = fread($socket,6); + echo "$onoff"; + flush(); } +fclose($socket); ?> diff --git a/www/moteleds.php3 b/www/moteleds.php3 new file mode 100644 index 0000000000000000000000000000000000000000..c975ef5958d04d77416ecdcedcd27e0b4941f504 --- /dev/null +++ b/www/moteleds.php3 @@ -0,0 +1,80 @@ +<?php +# +# EMULAB-COPYRIGHT +# Copyright (c) 2004 University of Utah and the Flux Group. +# All rights reserved. +# + +include("defs.php3"); +include("showstuff.php3"); + +# +# Make sure they are logged in +# +$uid = GETLOGIN(); +LOGGEDINORDIE($uid); + +# +# Verify page arguments. +# +if (!isset($pid) || + strcmp($pid, "") == 0) { + USERERROR("You must provide a Project ID.", 1); +} + +if (!isset($eid) || + strcmp($eid, "") == 0) { + USERERROR("You must provide an Experiment ID.", 1); +} + +# +# Standard Testbed Header now that we have the pid/eid okay. +# +PAGEHEADER("View mote LEDs ($pid/$eid)"); + +# +# Make sure they have permission to view this experiment +# +if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) { + USERERROR("You do not have permission to view experiment $exp_eid!", 1); +} + +# +# Get a list of all nodes in this experiment of type 'garcia' or 'stargate' +# +$query_result = + DBQueryFatal("select r.node_id,t.type,t.class from reserved as r ". + "left join nodes as n on ". + " r.node_id=n.node_id ". + "left join node_types as t on ". + " n.type=t.type ". + "where r.pid='$pid' and r.eid='$eid'"); + +if (mysql_num_rows($query_result) == 0) { + echo "<h3>No nodes to display in this experiment!</h3>\n"; +} else { + echo "<center> + <h3>Blinky Lights</h3> + </center> + <table align=center cellpadding=2 border=1> + <tr><th>Node</th><th>LEDs</th>\n"; + while ($row = mysql_fetch_array($query_result)) { + if ($row['type'] != "garcia" && $row['class'] != "sg") { + # Only the LEDs, mam + continue; + } + echo "<tr><th>$row[node_id]</th><td>"; + SHOWBLINKENLICHTEN($uid, + $HTTP_COOKIE_VARS[$TBAUTHCOOKIE], + "ledpipe.php3?node=$row[node_id]"); + } + echo "</table>\n"; + +} + +# +# Standard Testbed Footer +# +PAGEFOOTER(); + +?> diff --git a/www/showexp.php3 b/www/showexp.php3 index b3ddad56367c79c0758da47c1b053eb4f54ec9f7..a0cdd5dd0c92fd4a2c1063771db0430f7eb5c256 100644 --- a/www/showexp.php3 +++ b/www/showexp.php3 @@ -72,6 +72,20 @@ $isbatch = $row["batchmode"]; $wireless = $row["wirelesslans"]; $linktest_running = $row["linktest_pid"]; +# +# Get a list of node types and classes in this experiment +# +$query_result = + DBQueryFatal("select distinct t.type,t.class from reserved as r " . + " left join nodes as n on r.node_id=n.node_id ". + " left join node_types as t on n.type=t.type ". + "where r.eid='$eid' and r.pid='$pid'"); +while ($row = mysql_fetch_array($query_result)) { + $classes[$row['class']] = 1; + $types[$row['type']] = 1; +} + + echo "<font size=+2>Experiment <b>". "<a href='showproject.php3?pid=$pid'>$pid</a>/". "<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a></b></font>\n"; @@ -194,6 +208,13 @@ if ($wireless) { WRITESUBMENUBUTTON("Show History", "showstats.php3?showby=expt&which=$expindex"); +# Blinky lights - but only if they have nodes of the correct type in their +# experiment +if ($types['garcia'] || $classes['sg']) { + WRITESUBMENUBUTTON("Show Blinky Lights", + "moteleds.php3?pid=$exp_pid&eid=$exp_eid"); +} + if (ISADMIN($uid)) { if ($expstate == $TB_EXPTSTATE_ACTIVE) { SUBMENUSECTION("Beta-Test Options"); diff --git a/www/showstuff.php3 b/www/showstuff.php3 index 7bceaa0a705756ff4a417bddc4300edf8ac2ddb1..ee6ba4b4a5aa7a98c980ca93f764e25e13123152 100644 --- a/www/showstuff.php3 +++ b/www/showstuff.php3 @@ -1004,7 +1004,7 @@ function SHOWEXPLIST($type,$id,$gid = "") { # $HTTP_COOKIE_VARS[$TBAUTHCOOKIE], # "ledpipe.php3?node=em1"); # -function SHOWBLINKENLICHTEN($uid, $auth, $pipeurl, $width = 10, $height = 10) { +function SHOWBLINKENLICHTEN($uid, $auth, $pipeurl, $width = 30, $height = 10) { echo " <applet code='BlinkenLichten.class' width='$width' height='$height'> <param name='pipeurl' value='$pipeurl'>