linktest.php3 10.7 KB
Newer Older
1 2
<?php
#
3
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26
#
include("defs.php3");

#
27
# This script uses Sajax ... BEWARE!
28
#
29 30
require("Sajax.php");
sajax_init();
31
sajax_export("stop_linktest");
32

33
#
34 35 36 37 38 39
# 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";
40
    TBERROR("failed:$message", 0);
41 42 43 44 45 46 47 48 49 50 51 52 53
    # 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.
54 55 56
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
57

58 59 60 61
# This stuff will be setup below in CHECKPAGEARGS()
$pid            = "";
$eid            = "";
$unix_gid       = "";
Leigh Stoller's avatar
Leigh Stoller committed
62
$unix_pid       = "";
63 64 65
$linktest_level = 0;
$linktest_pid   = 0;

66
#
67 68
# Need this argument checking in a function so it can called from the
# request handlers.
69
#
70
function CHECKPAGEARGS() {
71
    global $this_user, $TB_EXPTSTATE_ACTIVE, $TB_EXPT_MODIFY;
72
    global $TB_EXPTSTATE_ACTIVATING, $TB_EXPTSTATE_MODIFY_RESWAP;
73
    global $pid, $eid, $experiment;
74
    global $unix_gid, $unix_pid, $linktest_level, $linktest_pid;
75 76

    $reqargs = RequiredPageArguments("experiment", PAGEARG_EXPERIMENT);
77
    
78
    if (!$experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
79
	USERERROR("You do not have permission to start/stop linktest ".
80
		  "on $pid/$eid!", 1);
81
    }
82 83 84 85 86 87
    $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);
88
    }
89 90 91
    $pid            = $experiment->pid();
    $eid            = $experiment->eid();
    $unix_gid       = $experiment->UnixGID();
92 93
    $project        = $experiment->Project();
    $unix_pid       = $project->unix_gid();
94 95
    $linktest_level = $experiment->linktest_level();
    $linktest_pid   = $experiment->linktest_pid();
96
}
97 98

#
99
# Stop a running linktest.
100
# 
101 102
function stop_linktest() {
    global $linktest_pid;
103 104
    global $uid, $pid, $unix_pid, $unix_gid;
    global $eid, $suexec_output, $session_interactive;
105

106 107
    # Must do this!
    CHECKPAGEARGS();
108

109
    if (! $linktest_pid) {
Leigh Stoller's avatar
Leigh Stoller committed
110 111 112
	if ($session_interactive) {
	    USERERROR("$pid/$eid is not running linktest!", 1);
	}
113 114
	return "stopped:Linktest is not running on experiment $pid/$eid!";
    }
115
    $retval = SUEXEC($uid, "$unix_pid,$unix_gid", "weblinktest -k $pid $eid",
116
		     SUEXEC_ACTION_IGNORE);
117

118 119 120 121
    if ($retval < 0) {
	return "failed:$suexec_output";
    }
    return "stopped:Linktest has been stopped.";
122 123
}

124 125 126
#
# If user hits stop button in the output side, stop linktest.
#
127
$linktest_running = 0;
128 129 130

function SPEWCLEANUP()
{
131
    global $pid, $unix_pid, $unix_gid, $uid, $eid, $linktest_running;
132

133
    if (connection_aborted() && $linktest_running) {
134
	SUEXEC($uid, "$unix_pid,$unix_gid", "weblinktest -k $pid $eid",
135 136 137 138 139
	       SUEXEC_ACTION_IGNORE);
    }
}

#
140 141 142
# Start linktest running.
# 
function start_linktest($level) {
143
    global $linktest_pid, $linktest_running, $TBSUEXEC_PATH;
144
    global $uid, $pid, $unix_pid, $unix_gid, $eid, $suexec_output;
145

146 147
    # Must do this!
    CHECKPAGEARGS();
148

149 150
    if ($linktest_pid) {
	return "failed:Linktest is already running on experiment $pid/$eid!";
151
    }
152 153 154 155 156 157 158
    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.
159 160 161
    register_shutdown_function("SPEWCLEANUP");
    set_time_limit(0);

162 163
    # XXX Hackish!
    $linktest_running = 1;
164
    $fp = popen("$TBSUEXEC_PATH $uid $unix_pid,$unix_gid ".
165 166 167
		"weblinktest -l $level $pid $eid", "r");
    if (! $fp) {
	USERERROR("Could not start linktest!", 1);
168
    }
169

170 171 172 173
    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");
174

175 176 177 178 179
    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 " ";
180
    }
181 182 183 184 185 186 187 188 189 190 191 192
    echo "\n";
    
    flush();
    
    while (!feof($fp)) {
	$string = fgets($fp, 1024);
	echo "$string";
	flush();
    }
    $retval = pclose($fp);
    $linktest_running = 0;

193
    if ($retval > 0) {
194
	echo "Linktest reported errors! Stopped at " .
195 196 197
	    date("D M d G:i:s T") . "\n";
    }
    elseif ($retval < 0) {
198
	echo $suexec_output;
199
    }
200 201 202 203 204 205
    else {
        # Success.
	echo "Linktest run was successful! Stopped at " .
	    date("D M d G:i:s T") . "\n";
    }
    exit(0);
206 207
}

208 209 210 211
# 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();

212
#
213 214
# In plain kill mode, just use the stop_linktest function and then
# redirect back to the showexp page.
215
#
216
if (isset($_REQUEST["kill"])) {
217 218
    stop_linktest();
    header("Location: showexp.php3?pid=$pid&eid=$eid");
219 220
    return;
}
221 222
if (isset($_REQUEST["start"]) && isset($_REQUEST["level"])) {
    start_linktest($_REQUEST["level"]);
223 224
    return;
}
225

226 227 228
# Must do this!
CHECKPAGEARGS();

229 230 231 232 233 234 235 236
#
# Okay, this is the initial page.
# 
PAGEHEADER("Run Linktest");

echo "<script>\n";
sajax_show_javascript();
if ($linktest_pid) {
237
    echo "var curstate    = 'busy';\n";
238 239
}
else {
240
    echo "var curstate    = 'stopped';\n";
241 242 243 244
}
?>

// Linktest stopped. No need to do anything since if a request was running,
245
// it will have returned prematurely.
246 247 248 249
function do_stop_cb(msg) {
    if (msg == '') {
	return;
    }
250

251 252 253 254 255 256 257 258 259 260 261 262 263
    //
    // 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') {
264
	alert("Linktest could not be stopped: " + output);
265 266 267 268 269 270 271 272 273 274 275
	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 = "";
276 277 278
    }
}

279 280 281
// onLoad callback for when linktest stops in the iframe.
function linktest_stopped() {
    // Avoid initial outer page load event.
Leigh Stoller's avatar
Leigh Stoller committed
282
    if (curstate != 'running' && curstate != 'stopping')
283
	return;
284
    
285 286 287 288 289 290 291 292 293 294 295 296 297 298
    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>';
299
    }
300 301 302 303 304
    else {
	getObjbyName('message').innerHTML =
	    '<font size=+1 color=black>' +
	    'Linktest has completed, no reported errors' + '</font>';
    }
305 306 307 308 309 310 311 312 313 314 315
}

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;

316 317 318 319 320 321 322 323 324 325
	// 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 =
326
	    '<?php echo $_SERVER["REQUEST_URI"]; ?>&start=1&level=' + level;
327

328 329 330
	curstate = "running";
	theform['action'].value = "Stop Linktest";
    }
331 332
    else if (curstate == 'running') {
	curstate = 'stopping';	
333 334
	x_stop_linktest(do_stop_cb);
    }
335 336 337
    else if (curstate == 'busy') {
	x_stop_linktest(do_stop_cb);
    }
338 339 340 341 342
}
<?php
echo "</script>\n";

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

346 347 348
echo "<center><font size=+2><br>
         Are you <b>sure</b> you want to run linktest?
         </font><br><br>\n";
349

350
$experiment->Show(1);
351

352
echo "<br>\n";
353
echo "<form action=linktest.php3 method=post name=myform id=myform>";
354 355
echo "<input type=hidden name=pid value=$pid>\n";
echo "<input type=hidden name=eid value=$eid>\n";
356

357 358
echo "<table align=center border=1>\n";
echo "<tr>
359
          <td><a href='$WIKIDOCURL/linktest'>Linktest</a> Option:</td>
360 361
          <td><select name=level>
                 <option value=0>Skip Linktest </option>\n";
362

363 364
for ($i = 1; $i <= TBDB_LINKTEST_MAX; $i++) {
    $selected = "";
365

366
    if (strcmp("$linktest_level", "$i") == 0)
367
	$selected = "selected";
368
	
369 370 371 372 373
    echo "        <option $selected value=$i>Level $i - " .
	$linktest_levels[$i] . "</option>\n";
}
echo "       </select>";
echo "    </td>
374 375 376
          </tr>
          </table><br>\n";

377 378 379 380 381 382 383
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";
384 385
}

386
echo "</form>\n";
387 388 389 390 391
echo "<div id=message>\n";
if ($linktest_pid) {
    echo "<font size=+1 color=red>Linktest is already running</font>\n";
}
echo "</div>\n";
392 393 394
echo "<div id=output style='overflow:auto'>
      <iframe onload=\"linktest_stopped();\"
      width=80% height=400 scrolling=auto id=outputarea frameborder=1>
395
      </iframe></center>\n";
396 397
echo "</center>\n";

398
#
399 400 401
# Standard Testbed Footer
# 
PAGEFOOTER();
402
?>