Commit 4820df1b authored by Leigh Stoller's avatar Leigh Stoller

Checkpoint little web page to spew the event stream out. The bulk of

this change was actually refactoring Tim's spewlog code to be more
general so that it can be used elsewhere. I still need to go back and
change Tim's oroginal code to use the stuff.
parent 9c9b43b4
......@@ -23,7 +23,7 @@ SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
spewconlog opsdb_control
LIBEXEC_SCRIPTS = webcreateimage newnode webdeletenode spewleds webcopy \
websetdest spewsource weblinkmon_ctl webcvsweb \
webspewconlog xlogin webviewvc
webspewconlog xlogin webviewvc spewevents
CTRLSBIN_SCRIPTS= opsdb_control.proxy
#
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002, 2005, 2006 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Fcntl;
use IO::Handle;
use strict;
#
# Spew event stream for an experiment.
#
sub usage()
{
print STDOUT "Usage: spewevents <pid> <eid>\n";
exit(-1);
}
my $optlist = "w";
my $fromweb = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use event;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Turn off line buffering on output
$| = 1;
# Protos
sub callbackFunc($$$);
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"w"})) {
$fromweb = 1;
}
if (@ARGV != 2) {
usage();
}
my $pid = $ARGV[0];
my $eid = $ARGV[1];
#
# Untaint the arguments.
#
if ($pid =~ /^([-\@\w]+)$/) {
$pid = $1;
}
else {
die("*** Bad data in pid: $pid\n");
}
if ($eid =~ /^([-\@\w]+)$/) {
$eid = $1;
}
else {
die("*** Bad data in eid: $eid\n");
}
#
# Verify that this person is allowed to do this.
#
if (!TBExptAccessCheck($UID, $pid, $eid, TB_EXPT_READINFO)) {
die("*** $0:\n".
" You do not have permission to view events for $pid/$eid!\n");
}
# Obvious.
STDOUT->autoflush(1);
if (! EventRegister()) {
die("*** $0:\n".
" Unable to register with event system\n");
}
my $handle = $event::EventSendHandle;
my $tuple = address_tuple_alloc();
if (! $tuple) {
die("*** $0:\n".
" Could not allocate an address tuple\n");
}
# All events for this experiment, sans scheduler events.
%$tuple = (expt => "$pid/$eid");
if (!event_subscribe($handle, \&callbackFunc, $tuple)) {
die("*** $0:\n".
" Could not subscribe to event\n");
}
#
# Icky. Send out some stuff at the beginning to make the browser do
# something. This terrible, but not sure what else to do.
#
if ($fromweb) {
for (my $i = 0; $i <= 1024; $i++) {
print " ";
}
print "\n";
}
#
# Loop.
#
while (1) {
# Quit when the experiment is no longer active.
last
if (ExpState($pid, $eid) ne EXPTSTATE_ACTIVE());
event_poll_blocking($handle, 2000);
}
exit(0);
sub callbackFunc($$$) {
my ($handle, $notification, $data) = @_;
my $time = time();
my $site = event_notification_get_site($handle, $notification);
my $expt = event_notification_get_expt($handle, $notification);
my $group = event_notification_get_group($handle, $notification);
my $host = event_notification_get_host($handle, $notification);
my $objtype = event_notification_get_objtype($handle, $notification);
my $objname = event_notification_get_objname($handle, $notification);
my $eventtype = event_notification_get_eventtype($handle, $notification);
my $arguments = event_notification_get_arguments($handle, $notification);
my $string =
"$time $group $host $objtype $objname $eventtype";
$string .= " ARGS:$arguments"
if (defined($arguments));
$string .= "\n";
my $rval = syswrite(STDOUT, $string);
# If the web page stops ...
exit(0)
if (!defined($rval));
}
......@@ -58,3 +58,239 @@ function GraphChange(which) {
x_GraphShow(which, arg0, arg1, GraphChange_cb);
return false;
}
function SetupOutputArea(id) {
var Iframe = document.getElementById(id);
var IframeDoc = IframeDocument(id);
var winheight = 0;
var yoff = 0;
// This tells us the total height of the browser window.
if (window.innerHeight) // all except Explorer
winheight = window.innerHeight;
else if (document.documentElement &&
document.documentElement.clientHeight)
// Explorer 6 Strict Mode
winheight = document.documentElement.clientHeight;
else if (document.body)
// other Explorers
winheight = document.body.clientHeight;
// Now get the Y offset of the outputframe.
yoff = Iframe.offsetTop;
IframeDoc.open();
IframeDoc.write('<html><head><base href=$BASEPATH/></head><body><pre id=outputarea></pre></body></html>');
IframeDoc.close();
if (winheight != 0)
// Now calculate how much room is left and make the iframe
// big enough to use most of the rest of the window.
if (yoff != 0)
winheight = winheight - (yoff + 175);
else
winheight = winheight * 0.7;
Iframe.height = winheight;
}
/* @return The innerHeight of the window. */
function getInnerHeight(id) {
var retval;
var win = document.getElementById(id).contentWindow;
var doc = document.getElementById(id).contentWindow.document;
if (win.innerHeight)
// all except Explorer
retval = win.innerHeight;
else if (doc.documentElement && doc.documentElement.clientHeight)
// Explorer 6 Strict Mode
retval = doc.documentElement.clientHeight;
else if (doc.body)
// other Explorers
retval = doc.body.clientHeight;
return retval;
}
/* @return The scrollTop of the window. */
function getScrollTop(id) {
var retval;
var win = document.getElementById(id).contentWindow;
var doc = document.getElementById(id).contentWindow.document;
if (win.pageYOffset)
// all except Explorer
retval = win.pageYOffset;
else if (document.documentElement && document.documentElement.scrollTop)
// Explorer 6 Strict
retval = document.documentElement.scrollTop;
else if (document.body)
// all other Explorers
retval = document.body.scrollTop;
return retval;
}
/* @return The height of the document. */
function getScrollHeight(id) {
var retval;
var win = document.getElementById(id).contentWindow;
var doc = document.getElementById(id).contentWindow.document;
var test1 = doc.body.scrollHeight;
var test2 = doc.body.offsetHeight;
if (test1 > test2)
// all but Explorer Mac
retval = doc.body.scrollHeight;
else
// Explorer Mac;
// would also work in Explorer 6 Strict, Mozilla and Safari
retval = doc.body.offsetHeight;
return retval;
}
/* Write the text to the output area, keeping the cursor at the bottom. */
var lastLength = 0; // The length of the download text at the last update
var lastLine = ""; // The last line of the download text.
var firstLine = 1; // Flag.
function WriteOutputText(id, stuff) {
var Iframe = document.getElementById(id);
var idoc = IframeDocument(id);
var output = idoc.getElementById('outputarea');
/*
* Append new stuff to the last line from the previous call in case
* the previous line was only partially downloaded.
*/
var newData = lastLine + stuff.substring(lastLength);
var lines = newData.split("\n");
var newText = "";
// Globals
lastLength = stuff.length;
lastLine = "";
/*
* Record the size of the document before modifying it so we can see
* if we can automatically do the scroll.
*/
var ih = getInnerHeight(id);
var y = getScrollTop(id);
var h = getScrollHeight(id);
/* Iterate over lines */
for (i = 0; i < lines.length - 1; i++) {
var line = lines[i];
if (firstLine) {
if (line.search(/^[ \ ]*$/) >= 0) {
continue;
}
firstLine = 0;
}
newText += line + "\n";
}
// For next call
lastLine = lines[lines.length - 1];
// Add the new text to the DOM.
textNode = idoc.createTextNode(newText);
output.appendChild(textNode);
/* See if we should scroll the window down. */
var nh = getScrollHeight(id);
if ((h - (y + ih)) < (y == 0 ? 200 : 10)) {
idoc.documentElement.scrollTop = nh;
idoc.body.scrollTop = nh;
}
}
function GetInnerText(el) {
if (typeof el == "string")
return el;
if (typeof el == "undefined")
return "";
// Not needed but it is faster
if (el.innerText)
return el.innerText;
var str = "";
var cs = el.childNodes;
var l = cs.length;
for (var i = 0; i < l; i++) {
switch (cs[i].nodeType) {
case 1: //ELEMENT_NODE
str += GetInnerText(cs[i]);
break;
case 3: //TEXT_NODE
str += cs[i].nodeValue;
break;
}
}
return str;
}
/*
* @return The text in the given iframe. If the text is surrounded by '<pre>'
* tags (mozilla, IE), they will be stripped.
*/
function GetInputText(id) {
var ifr = document.getElementById(id);
var retval = null;
try {
var oDoc = (ifr.contentWindow || ifr.contentDocument);
if (oDoc.document) {
oDoc = oDoc.document;
}
for (lpc = 0; lpc < oDoc.childNodes.length; lpc++) {
text = GetInnerText(oDoc.childNodes[lpc]);
if (text != "") {
if (retval == null)
retval = "";
retval += text;
}
}
if (retval.indexOf("<pre>") != -1 || retval.indexOf("<PRE>") != -1) {
retval = retval.substring(5, retval.length - 6);
}
}
catch (error) {
}
return retval;
}
/*
* Process, start and stop output.
*/
var OutputInterval;
var InputID;
var OutputID;
function LookforOutput() {
var stuff;
if ((stuff = GetInputText(InputID)) != null) {
WriteOutputText(OutputID, stuff);
}
}
function StartOutput(input_id, output_id) {
OutputID = output_id;
InputID = input_id;
firstLine = 1;
OutputInterval = setInterval('LookforOutput()', 1000);
}
function StopOutput() {
clearInterval(OutputInterval);
LookforOutput();
}
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
include("showstuff.php3");
#
# Only known and logged in users.
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($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);
}
#
# Check to make sure this is a valid PID/EID tuple.
if (! TBValidExperiment($pid, $eid)) {
USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
}
#
# Verify permission.
#
if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) {
USERERROR("You do not have permission to view the log for $pid/$eid!", 1);
}
#
# A cleanup function to keep the child from becoming a zombie, since
# the script is terminated, but the children are left to roam.
#
$fp = 0;
function SPEWCLEANUP()
{
global $fp;
if (!$fp || !connection_aborted()) {
exit();
}
pclose($fp);
exit();
}
register_shutdown_function("SPEWCLEANUP");
if ($fp = popen("$TBSUEXEC_PATH $uid $pid spewevents -w $pid $eid", "r")) {
header("Content-Type: text/plain");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
flush();
while (!feof($fp)) {
$string = fgets($fp, 1024);
echo "$string";
flush();
}
pclose($fp);
$fp = 0;
}
else {
USERERROR("Experiment $pid/$eid is no longer in transition!", 1);
}
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment