linktest.php3 9.61 KB
Newer Older
1 2 3
<?php
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
5 6 7 8 9
# All rights reserved.
#
include("defs.php3");

#
10
# This script uses Sajax ... BEWARE!
11
#
12 13
require("Sajax.php");
sajax_init();
14
sajax_export("stop_linktest");
15

16
#
17 18 19 20 21 22
# We need all errors to come back to us so that we can report the error
# to the user even when its from within an exported sajax function.
# 
function handle_error($message, $death)
{
    echo "failed:$message";
23
    TBERROR("failed:$message", 0);
24 25 26 27 28 29 30 31 32 33 34 35 36
    # Always exit; ignore $death.
    exit(1);
}
$session_errorhandler = 'handle_error';

# If this call is to client request function, then turn off interactive mode.
# All errors will go to above function and get reported back through the
# Sajax interface.
if (sajax_client_request()) {
    $session_interactive = 0;
}

# Now check login status.
37 38 39
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
40

41 42 43 44 45 46 47
# This stuff will be setup below in CHECKPAGEARGS()
$pid            = "";
$eid            = "";
$unix_gid       = "";
$linktest_level = 0;
$linktest_pid   = 0;

48
#
49 50
# Need this argument checking in a function so it can called from the
# request handlers.
51
#
52
function CHECKPAGEARGS() {
53 54 55 56 57
    global $this_user, $TB_EXPTSTATE_ACTIVE, $TB_EXPT_MODIFY;
    global $pid, $eid, $experiment;
    global $unix_gid, $linktest_level, $linktest_pid;

    $reqargs = RequiredPageArguments("experiment", PAGEARG_EXPERIMENT);
58
    
59 60 61
    if (!$experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
	USERERROR("You do not have permission to run linktest ".
		  "on $pid/$eid!", 1);
62
    }
63
    if ($experiment->state() != $TB_EXPTSTATE_ACTIVE) {
Russ Fish's avatar
Typo.  
Russ Fish committed
64
	USERERROR("Experiment $eid must be active to run linktest!", 1);
65
    }
66 67 68 69 70
    $pid            = $experiment->pid();
    $eid            = $experiment->eid();
    $unix_gid       = $experiment->UnixGID();
    $linktest_level = $experiment->linktest_level();
    $linktest_pid   = $experiment->linktest_pid();
71
}
72 73

#
74
# Stop a running linktest.
75
# 
76 77
function stop_linktest() {
    global $linktest_pid;
78
    global $uid, $pid, $unix_gid, $eid, $suexec_output, $session_interactive;
79

80 81
    # Must do this!
    CHECKPAGEARGS();
82

83
    if (! $linktest_pid) {
Leigh B. Stoller's avatar
Leigh B. Stoller committed
84 85 86
	if ($session_interactive) {
	    USERERROR("$pid/$eid is not running linktest!", 1);
	}
87 88 89 90
	return "stopped:Linktest is not running on experiment $pid/$eid!";
    }
    $retval = SUEXEC($uid, "$pid,$unix_gid", "weblinktest -k $pid $eid",
		     SUEXEC_ACTION_IGNORE);
91

92 93 94 95
    if ($retval < 0) {
	return "failed:$suexec_output";
    }
    return "stopped:Linktest has been stopped.";
96 97
}

98 99 100
#
# If user hits stop button in the output side, stop linktest.
#
101
$linktest_running = 0;
102 103 104

function SPEWCLEANUP()
{
Leigh B. Stoller's avatar
Leigh B. Stoller committed
105
    global $pid, $unix_gid, $uid, $eid, $linktest_running;
106

107
    if (connection_aborted() && $linktest_running) {
108
	SUEXEC($uid, "$pid,$unix_gid", "weblinktest -k $pid $eid",
109 110 111 112 113
	       SUEXEC_ACTION_IGNORE);
    }
}

#
114 115 116
# Start linktest running.
# 
function start_linktest($level) {
117
    global $linktest_pid, $linktest_running, $TBSUEXEC_PATH;
118
    global $uid, $pid, $unix_gid, $eid, $suexec_output;
119

120 121
    # Must do this!
    CHECKPAGEARGS();
122

123 124
    if ($linktest_pid) {
	return "failed:Linktest is already running on experiment $pid/$eid!";
125
    }
126 127 128 129 130 131 132
    if (! TBvalid_tinyint($level) ||
	$level < 0 || $level > TBDB_LINKTEST_MAX) {
	return "failed:Linktest level ($level) must be an integer ".
	    "1 <= level <= ". TBDB_LINKTEST_MAX;
    }
    
    # Make sure we shutdown if client goes away.
133 134 135
    register_shutdown_function("SPEWCLEANUP");
    set_time_limit(0);

136 137 138 139 140 141
    # XXX Hackish!
    $linktest_running = 1;
    $fp = popen("$TBSUEXEC_PATH $uid $pid,$unix_gid ".
		"weblinktest -l $level $pid $eid", "r");
    if (! $fp) {
	USERERROR("Could not start linktest!", 1);
142
    }
143

144 145 146 147
    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");
148

149 150 151 152 153
    echo "Starting linktest run at level $level on " .
	date("D M d G:i:s T");
    # Oh, this is soooooo bogus!
    for ($i = 0; $i < 1024; $i++) {
	echo " ";
154
    }
155 156 157 158 159 160 161 162 163 164 165 166
    echo "\n";
    
    flush();
    
    while (!feof($fp)) {
	$string = fgets($fp, 1024);
	echo "$string";
	flush();
    }
    $retval = pclose($fp);
    $linktest_running = 0;

167
    if ($retval > 0) {
168
	echo "Linktest reported errors! Stopped at " .
169 170 171
	    date("D M d G:i:s T") . "\n";
    }
    elseif ($retval < 0) {
172
	echo $suexec_output;
173
    }
174 175 176 177 178 179
    else {
        # Success.
	echo "Linktest run was successful! Stopped at " .
	    date("D M d G:i:s T") . "\n";
    }
    exit(0);
180 181
}

182 183 184 185
# See if this request is to one of the above functions. Does not return
# if it is. Otherwise return and continue on.
sajax_handle_client_request();

186
#
187 188
# In plain kill mode, just use the stop_linktest function and then
# redirect back to the showexp page.
189
#
190
if (isset($_REQUEST["kill"])) {
191 192
    stop_linktest();
    header("Location: showexp.php3?pid=$pid&eid=$eid");
193 194
    return;
}
195 196
if (isset($_REQUEST["start"]) && isset($_REQUEST["level"])) {
    start_linktest($_REQUEST["level"]);
197 198
    return;
}
199

200 201 202 203 204 205 206 207 208 209 210
#
# Okay, this is the initial page.
# 
PAGEHEADER("Run Linktest");

# Must do this!
CHECKPAGEARGS();

echo "<script>\n";
sajax_show_javascript();
if ($linktest_pid) {
211
    echo "var curstate    = 'busy';\n";
212 213
}
else {
214
    echo "var curstate    = 'stopped';\n";
215 216 217 218
}
?>

// Linktest stopped. No need to do anything since if a request was running,
219
// it will have returned prematurely.
220 221 222 223
function do_stop_cb(msg) {
    if (msg == '') {
	return;
    }
224

225 226 227 228 229 230 231 232 233 234 235 236 237
    //
    // The first part of the message is an indicator whether command
    // was sucessful. The rest of it (after the ":" is the text itself).
    //
    var offset = msg.indexOf(":");
    if (offset == -1) {
	return;
    }
    var status = msg.substring(0, offset);
    var output = msg.substring(offset + 1);

    // If we got an error; throw up something useful.
    if (status != 'stopped') {
238
	alert("Linktest could not be stopped: " + output);
239 240 241 242 243 244 245 246 247 248 249
	return;
    }

    // Strictly for the benefit of stopping a linktest started from
    // another window.
    if (curstate == 'busy') {
	curstate = 'stopped';	
	getObjbyName('action').value = 'Start';

	// This clears the message area.
	getObjbyName('message').innerHTML = "";
250 251 252
    }
}

253 254 255
// onLoad callback for when linktest stops in the iframe.
function linktest_stopped() {
    // Avoid initial outer page load event.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
256
    if (curstate != 'running' && curstate != 'stopping')
257
	return;
258
    
259 260 261 262 263 264 265 266 267 268 269 270 271 272
    curstate = 'stopped';	
    getObjbyName('action').value = 'Start';

    var Iframe = document.getElementById('outputarea');
    var html   = Iframe.contentWindow.document.documentElement.innerHTML;

    re = /reported errors/gi
    re.multiline = true;

    if (html.search(re) != -1) {
	getObjbyName('message').innerHTML =
	    '<font size=+1 color=red><blink>' +
	    'Linktest has reported errors! Please examine log below.' +
	    '</blink></font>';
273
    }
274 275 276 277 278
    else {
	getObjbyName('message').innerHTML =
	    '<font size=+1 color=black>' +
	    'Linktest has completed, no reported errors' + '</font>';
    }
279 280 281 282 283 284 285 286 287 288 289
}

function doaction(theform) {
    var levelx = theform['level'].selectedIndex;
    var level  = theform['level'].options[levelx].value;
    var action = theform['action'].value;

    if (curstate == 'stopped') {
	if (level == '0')
	    return;

290 291 292 293 294 295 296 297 298 299 300 301
	// This clears the message area.
	getObjbyName('message').innerHTML = "";

	Iframe = document.getElementById('outputarea');
	// This stuff clears the current contents of the iframe.
	Iframe.contentWindow.document.open();
	Iframe.contentWindow.document.write(" ");
	Iframe.contentWindow.document.close();
	// And this fires it up.
	Iframe.contentWindow.document.location =
	    '<?php echo $REQUEST_URI; ?>&start=1&level=' + level;

302 303 304
	curstate = "running";
	theform['action'].value = "Stop Linktest";
    }
305 306
    else if (curstate == 'running') {
	curstate = 'stopping';	
307 308
	x_stop_linktest(do_stop_cb);
    }
309 310 311
    else if (curstate == 'busy') {
	x_stop_linktest(do_stop_cb);
    }
312 313 314 315 316
}
<?php
echo "</script>\n";

echo "<font size=+2>Experiment <b>".
317 318 319
	"<a href='showproject.php3?pid=$pid'>$pid</a>/".
	"<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a></b></font>\n";

320 321 322
echo "<center><font size=+2><br>
         Are you <b>sure</b> you want to run linktest?
         </font><br><br>\n";
323

324
$experiment->Show(1);
325

326
echo "<br>\n";
327
echo "<form action=linktest.php3 method=post name=myform id=myform>";
328 329
echo "<input type=hidden name=pid value=$pid>\n";
echo "<input type=hidden name=eid value=$eid>\n";
330

331 332 333 334 335 336
echo "<table align=center border=1>\n";
echo "<tr>
          <td><a href='$TBDOCBASE/doc/docwrapper.php3?".
                 "docname=linktest.html'>Linktest</a> Option:</td>
          <td><select name=level>
                 <option value=0>Skip Linktest </option>\n";
337

338 339
for ($i = 1; $i <= TBDB_LINKTEST_MAX; $i++) {
    $selected = "";
340

341
    if (strcmp("$linktest_level", "$i") == 0)
342
	$selected = "selected";
343
	
344 345 346 347 348
    echo "        <option $selected value=$i>Level $i - " .
	$linktest_levels[$i] . "</option>\n";
}
echo "       </select>";
echo "    </td>
349 350 351
          </tr>
          </table><br>\n";

352 353 354 355 356 357 358
if ($linktest_pid) {
    echo "<input type=button name=action id=action value='Stop Linktest' ".
	         "onclick=\"doaction(myform); return false;\">\n";
}
else {
    echo "<input type=button name=action id=action value=Start ".
	         "onclick=\"doaction(myform); return false;\">\n";
359 360
}

361
echo "</form>\n";
362 363 364 365 366
echo "<div id=message>\n";
if ($linktest_pid) {
    echo "<font size=+1 color=red>Linktest is already running</font>\n";
}
echo "</div>\n";
367 368 369
echo "<div id=output style='overflow:auto'>
      <iframe onload=\"linktest_stopped();\"
      width=80% height=400 scrolling=auto id=outputarea frameborder=1>
Timothy Stack's avatar
 
Timothy Stack committed
370
      </iframe></center>\n";
371 372
echo "</center>\n";

373
#
374 375 376
# Standard Testbed Footer
# 
PAGEFOOTER();
377
?>