Commit 07323144 authored by Leigh Stoller's avatar Leigh Stoller

Ah, the things I do. Added web page and backend script to scroll the

experiment log file to the user as it gets generated. The web page
does not redraw, it just never exits until the backend sees that the
experiement transition is done, and then it exists, which terminates
the script. I added a DB field to hold the logfile name and some
routines in libdb, with the idea that this might be more generally
useful at some point. Next time you create an experiment, look for the
last sentence, and click on "realtime".
parent c751902c
......@@ -1193,7 +1193,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
pxe/GNUmakefile pxe/proxydhcp.restart pxe/bootinfo.restart \
security/GNUmakefile security/paperbag security/lastlog_daemon \
security/plasticwrap \
tbsetup/GNUmakefile tbsetup/console_setup \
tbsetup/GNUmakefile tbsetup/console_setup tbsetup/spewlogfile \
tbsetup/console_reset tbsetup/bwconfig tbsetup/power_rpc27.pm \
tbsetup/os_load tbsetup/os_setup tbsetup/power \
tbsetup/node_reboot tbsetup/webnscheck tbsetup/nscheck \
......
......@@ -265,7 +265,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
pxe/GNUmakefile pxe/proxydhcp.restart pxe/bootinfo.restart \
security/GNUmakefile security/paperbag security/lastlog_daemon \
security/plasticwrap \
tbsetup/GNUmakefile tbsetup/console_setup \
tbsetup/GNUmakefile tbsetup/console_setup tbsetup/spewlogfile \
tbsetup/console_reset tbsetup/bwconfig tbsetup/power_rpc27.pm \
tbsetup/os_load tbsetup/os_setup tbsetup/power \
tbsetup/node_reboot tbsetup/webnscheck tbsetup/nscheck \
......
......@@ -79,7 +79,7 @@ use Exporter;
TBValidNodeLogType TBValidNodeName TBSetNodeLogEntry
TBSetSchedReload MapNodeOSID TBLockExp TBUnLockExp TBSetExpSwapTime
TBUnixGroupList TBOSID TBImageID TBdbfork VnameToNodeid TBExpLocked
TBIsNodeRemote
TBIsNodeRemote TBExptSetLogFile TBExptClearLogFile TBExptGetLogFile
);
# Must come after package declaration!
......@@ -1446,6 +1446,54 @@ sub TBIsNodeRemote($)
return 0;
}
#
# Set/Clear the current logfile for an experiment. The idea is to provide
# a way to look at what is going on from the web interface!
#
# usage TBExptSetLogFile(char *pid, char *eid, char *logname)
#
sub TBExptSetLogFile($$$)
{
my ($pid, $eid, $logname) = @_;
DBQueryFatal("update experiments set logfile='$logname' ".
"where pid='$pid' and eid='$eid'");
}
sub TBExptClearLogFile($$)
{
my ($pid, $eid) = @_;
DBQueryFatal("update experiments set logfile=NULL ".
"where pid='$pid' and eid='$eid'");
}
#
# Get the current logfile for an experiment.
#
# usage TBExptGetLogFile(char *pid, char *eid, char \*logname)
# Return 1 if there is a valid logname, and sets logname.
# Return 0 if no logfile or error.
#
sub TBExptGetLogFile($$$)
{
my ($pid, $eid, $logname) = @_;
my $query_result =
DBQueryFatal("select logfile from experiments ".
"where pid='$pid' and eid='$eid'");
if ($query_result->numrows == 0) {
return 0;
}
my @row = $query_result->fetchrow_array();
if (defined($row[0])) {
$$logname = $row[0];
return 1;
}
return 0;
}
#
# Issue a DB query. Argument is a string. Returns the actual query object, so
# it is up to the caller to test it. I would not for one moment view this
......
......@@ -173,6 +173,7 @@ CREATE TABLE experiments (
minimum_nodes tinyint(4) default NULL,
testdb tinytext,
path tinytext,
logfile tinytext,
attempts smallint(5) unsigned NOT NULL default '0',
canceled tinyint(4) NOT NULL default '0',
batchstate varchar(12) default NULL,
......
......@@ -30,7 +30,8 @@ LIBEXEC_STUFF = rmproj rmacct-ctrl \
webstartexp webendexp webbatchexp \
assign_wrapper ptopgen webnodeupdate \
webrmgroup webswapexp webnodecontrol \
webmkgroup webmkacct websetgroups webmkproj
webmkgroup webmkacct websetgroups webmkproj \
spewlogfile
LIB_STUFF = libtbsetup.pm exitonwarn.pm libtestbed.pm snmpit_intel.pm \
snmpit_cisco.pm snmpit_lib.pm snmpit_apc.pm power_rpc27.pm \
......
#!/usr/bin/perl -wT
use English;
use Getopt::Std;
#
# Spew the current log file for an experiment to stdout. This is for
# use by the web interface, so it can send the lofgile to the user in
# a web page.
#
# The wrinkle is that the logfile only exists while the experiment is
# in transition, and we have to quit when the experiment is no longer in
# transition so that the web page can finish.
#
sub usage()
{
print STDOUT "Usage: spewlogfile <pid> <eid>\n".
"Spew the logfile for an experiment.\n";
exit(-1);
}
my $optlist = "";
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $logname;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
# 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;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
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 log files for $pid/$eid!\n");
}
#
# Get the logfile name.
#
if (! TBExptGetLogFile($pid, $eid, \$logname)) {
die("*** $0:\n".
" There is no logfile to view for $pid/$eid!\n");
}
use Fcntl;
use IO::Handle;
STDOUT->autoflush(1);
sysopen(LOG, $logname, O_RDONLY | O_NONBLOCK) or
die("*** $0:\n".
" Could not open $logname. Must no longer be in transition!");
#
# Loop reading the file in nonblocking mode. Sleep between loops, and
# check for a change in status. For now, this is simply accomplished
# by checking to make sure the name of the logfile has not changed!
#
while (1) {
my $tmp;
while (sysread(LOG, $buf, 2048)) {
print STDOUT "$buf";
}
if (! TBExptGetLogFile($pid, $eid, \$tmp) || $tmp ne $logname) {
last;
}
sleep(3);
}
close(LOG);
exit(0);
......@@ -209,6 +209,8 @@ TBLockExp($pid, $eid);
# is actually torn down.
#
if (! $batch) {
TBExptSetLogFile($pid, $eid, $logname);
if (TBBackGround($logname)) {
#
# Parent exits normally
......@@ -338,6 +340,7 @@ SENDMAIL("$user_name <$user_email>",
"Bcc: $TBLOGS",
($repfile, $logname, $nsfile));
TBExptClearLogFile($pid, $eid);
unlink($logname);
exit 0;
......@@ -396,6 +399,7 @@ sub fatal()
system("/bin/mv", "-f", "${expt_path}", "${expt_path}-TBfailed");
}
TBExptClearLogFile($pid, $eid);
unlink($logname);
exit($errorstat);
}
......
......@@ -702,7 +702,11 @@ else {
configured and you are able to proceed. This typically takes less
than 10 minutes, depending on the number of nodes you have requested.
If you do not receive email notification within a reasonable amount
of time, please contact $TBMAILADDR.\n";
of time, please contact $TBMAILADDR.<br>
<br>
While you are waiting, you can watch the log of experiment creation
in <a target=logfile href=spewlogfile.php3?pid=$exp_pid&eid=$exp_id>
realtime</a>.\n";
}
echo "<br>
</font>\n";
......
<?php
include("defs.php3");
include("showstuff.php3");
#
# Standard Testbed Header
#
#PAGEHEADER("Watch Experiment Log");
#
# Only known and logged in users can end experiments.
#
$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);
}
#
# Check for a logfile. This file is transient, so it could be gone by
# the time we get to reading it.
#
$expstate = TBExptState($pid, $eid);
if (strcmp($expstate, $TB_EXPTSTATE_ACTIVATING)) {
USERERROR("Experiment $pid/$eid is no longer in transition!", 1);
}
header("Content-Type: text/plain");
$retval = 0;
$result = system("$TBSUEXEC_PATH $uid $pid spewlogfile $pid $eid", $retval);
if ($retval) {
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