linktest.php3 9.83 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
    global $this_user, $TB_EXPTSTATE_ACTIVE, $TB_EXPT_MODIFY;
54
    global $TB_EXPTSTATE_ACTIVATING, $TB_EXPTSTATE_MODIFY_RESWAP;
55 56 57 58
    global $pid, $eid, $experiment;
    global $unix_gid, $linktest_level, $linktest_pid;

    $reqargs = RequiredPageArguments("experiment", PAGEARG_EXPERIMENT);
59
    
60
    if (!$experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
61
	USERERROR("You do not have permission to start/stop linktest ".
62
		  "on $pid/$eid!", 1);
63
    }
64 65 66 67 68 69
    $expstate = $experiment->state();
    if ($expstate != $TB_EXPTSTATE_ACTIVE &&
	$expstate != $TB_EXPTSTATE_ACTIVATING &&
	$expstate != $TB_EXPTSTATE_MODIFY_RESWAP) {
	USERERROR("Experiment $eid must be active to start/stop linktest," . 
		  " not $expstate!", 1);
70
    }
71 72 73 74 75
    $pid            = $experiment->pid();
    $eid            = $experiment->eid();
    $unix_gid       = $experiment->UnixGID();
    $linktest_level = $experiment->linktest_level();
    $linktest_pid   = $experiment->linktest_pid();
76
}
77 78

#
79
# Stop a running linktest.
80
# 
81 82
function stop_linktest() {
    global $linktest_pid;
83
    global $uid, $pid, $unix_gid, $eid, $suexec_output, $session_interactive;
84

85 86
    # Must do this!
    CHECKPAGEARGS();
87

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

97 98 99 100
    if ($retval < 0) {
	return "failed:$suexec_output";
    }
    return "stopped:Linktest has been stopped.";
101 102
}

103 104 105
#
# If user hits stop button in the output side, stop linktest.
#
106
$linktest_running = 0;
107 108 109

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

112
    if (connection_aborted() && $linktest_running) {
113
	SUEXEC($uid, "$pid,$unix_gid", "weblinktest -k $pid $eid",
114 115 116 117 118
	       SUEXEC_ACTION_IGNORE);
    }
}

#
119 120 121
# Start linktest running.
# 
function start_linktest($level) {
122
    global $linktest_pid, $linktest_running, $TBSUEXEC_PATH;
123
    global $uid, $pid, $unix_gid, $eid, $suexec_output;
124

125 126
    # Must do this!
    CHECKPAGEARGS();
127

128 129
    if ($linktest_pid) {
	return "failed:Linktest is already running on experiment $pid/$eid!";
130
    }
131 132 133 134 135 136 137
    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.
138 139 140
    register_shutdown_function("SPEWCLEANUP");
    set_time_limit(0);

141 142 143 144 145 146
    # 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);
147
    }
148

149 150 151 152
    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");
153

154 155 156 157 158
    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 " ";
159
    }
160 161 162 163 164 165 166 167 168 169 170 171
    echo "\n";
    
    flush();
    
    while (!feof($fp)) {
	$string = fgets($fp, 1024);
	echo "$string";
	flush();
    }
    $retval = pclose($fp);
    $linktest_running = 0;

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

187 188 189 190
# 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();

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

205 206 207 208 209 210 211 212 213 214 215
#
# Okay, this is the initial page.
# 
PAGEHEADER("Run Linktest");

# Must do this!
CHECKPAGEARGS();

echo "<script>\n";
sajax_show_javascript();
if ($linktest_pid) {
216
    echo "var curstate    = 'busy';\n";
217 218
}
else {
219
    echo "var curstate    = 'stopped';\n";
220 221 222 223
}
?>

// Linktest stopped. No need to do anything since if a request was running,
224
// it will have returned prematurely.
225 226 227 228
function do_stop_cb(msg) {
    if (msg == '') {
	return;
    }
229

230 231 232 233 234 235 236 237 238 239 240 241 242
    //
    // 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') {
243
	alert("Linktest could not be stopped: " + output);
244 245 246 247 248 249 250 251 252 253 254
	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 = "";
255 256 257
    }
}

258 259 260
// 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
261
    if (curstate != 'running' && curstate != 'stopping')
262
	return;
263
    
264 265 266 267 268 269 270 271 272 273 274 275 276 277
    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>';
278
    }
279 280 281 282 283
    else {
	getObjbyName('message').innerHTML =
	    '<font size=+1 color=black>' +
	    'Linktest has completed, no reported errors' + '</font>';
    }
284 285 286 287 288 289 290 291 292 293 294
}

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;

295 296 297 298 299 300 301 302 303 304 305 306
	// 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;

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

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

325 326 327
echo "<center><font size=+2><br>
         Are you <b>sure</b> you want to run linktest?
         </font><br><br>\n";
328

329
$experiment->Show(1);
330

331
echo "<br>\n";
332
echo "<form action=linktest.php3 method=post name=myform id=myform>";
333 334
echo "<input type=hidden name=pid value=$pid>\n";
echo "<input type=hidden name=eid value=$eid>\n";
335

336 337 338 339 340 341
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";
342

343 344
for ($i = 1; $i <= TBDB_LINKTEST_MAX; $i++) {
    $selected = "";
345

346
    if (strcmp("$linktest_level", "$i") == 0)
347
	$selected = "selected";
348
	
349 350 351 352 353
    echo "        <option $selected value=$i>Level $i - " .
	$linktest_levels[$i] . "</option>\n";
}
echo "       </select>";
echo "    </td>
354 355 356
          </tr>
          </table><br>\n";

357 358 359 360 361 362 363
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";
364 365
}

366
echo "</form>\n";
367 368 369 370 371
echo "<div id=message>\n";
if ($linktest_pid) {
    echo "<font size=+1 color=red>Linktest is already running</font>\n";
}
echo "</div>\n";
372 373 374
echo "<div id=output style='overflow:auto'>
      <iframe onload=\"linktest_stopped();\"
      width=80% height=400 scrolling=auto id=outputarea frameborder=1>
375
      </iframe></center>\n";
376 377
echo "</center>\n";

378
#
379 380 381
# Standard Testbed Footer
# 
PAGEFOOTER();
382
?>