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

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

17
#
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 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";
    # 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
40
$uid = GETLOGIN();
LOGGEDINORDIE($uid);

#
41
42
# Need this argument checking in a function so it can called from the
# request handlers.
43
#
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function CHECKPAGEARGS() {
    global $uid, $TB_EXPTSTATE_ACTIVE, $TB_EXPT_MODIFY;
    
    #
    # Check to make sure a valid experiment.
    #
    $pid = $_GET['pid'];
    $eid = $_GET['eid'];
    
    if (isset($pid) && strcmp($pid, "") &&
	isset($eid) && strcmp($eid, "")) {
	if (! TBvalid_eid($eid)) {
	    PAGEARGERROR("$eid is contains invalid characters!");
	}
	if (! TBvalid_pid($pid)) {
	    PAGEARGERROR("$pid is contains invalid characters!");
	}
	if (! TBValidExperiment($pid, $eid)) {
	    USERERROR("$pid/$eid is not a valid experiment!", 1);
	}
	if (TBExptState($pid, $eid) != $TB_EXPTSTATE_ACTIVE) {
	    USERERROR("$pid/$eid is not currently swapped in!", 1);
	}
	if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_MODIFY)) {
	    USERERROR("You do not have permission to run linktest on ".
		      "$pid/$eid!", 1);
	}
71
    }
72
73
    else {
	PAGEARGERROR("Must specify pid and eid!");
74
75
    }
}
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#
# Grab DB data we need.
#
function GRABDBDATA() {
    global $pid, $eid;
    global $gid, $linktest_level, $linktest_pid;
    
    # Need the GID, plus current level and the pid.
    $query_result =
	DBQueryFatal("select gid,linktest_level,linktest_pid ".
		     "  from experiments ".
		     "where pid='$pid' and eid='$eid'");
    $row = mysql_fetch_array($query_result);
    $gid            = $row[0];
    $linktest_level = $row[1];
    $linktest_pid   = $row[2];
}
94
95

#
96
# Stop a running linktest.
97
# 
98
99
100
function stop_linktest() {
    global $linktest_pid;
    global $uid, $pid, $gid, $eid, $suexec_output;
101

102
103
104
    # Must do this!
    CHECKPAGEARGS();
    GRABDBDATA();
105

106
107
108
109
110
111
112
113
    if (! $linktest_pid) {
	return "stopped:Linktest is not running on experiment $pid/$eid!";
    }
    # For backend script call.
    TBGroupUnixInfo($pid, $gid, $unix_gid, $unix_name);
    
    $retval = SUEXEC($uid, "$pid,$unix_gid", "weblinktest -k $pid $eid",
		     SUEXEC_ACTION_IGNORE);
114

115
116
117
118
    if ($retval < 0) {
	return "failed:$suexec_output";
    }
    return "stopped:Linktest has been stopped.";
119
120
}

121
122
123
#
# If user hits stop button in the output side, stop linktest.
#
124
$process = 0;
125
126
127

function SPEWCLEANUP()
{
128
129
130
131
    global $pid, $gid;
    $process = $GLOBALS["process"];

    TBGroupUnixInfo($pid, $gid, $unix_gid, $unix_name);
132

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

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

147
148
149
    # Must do this!
    CHECKPAGEARGS();
    GRABDBDATA();
150

151
152
    if ($linktest_pid) {
	return "failed:Linktest is already running on experiment $pid/$eid!";
153
    }
154
155
156
157
158
159
160
161
162
163
    if (! TBvalid_tinyint($level) ||
	$level < 0 || $level > TBDB_LINKTEST_MAX) {
	return "failed:Linktest level ($level) must be an integer ".
	    "1 <= level <= ". TBDB_LINKTEST_MAX;
    }
    
    # For backend script call.
    TBGroupUnixInfo($pid, $gid, $unix_gid, $unix_name);

    # Make sure we shutdown if client goes away.
164
165
166
167
    register_shutdown_function("SPEWCLEANUP");
    ignore_user_abort(1);
    set_time_limit(0);

168
169
170
171
172
173
174
175
176
177
    #
    # Having problems with popen reporting the proper exit status,
    # so switched to proc_open instead. Obtuse, I know.
    #
    $descriptorspec = array(0 => array("pipe", "r"),
			    1 => array("pipe", "w"));

    $process = proc_open("$TBSUEXEC_PATH ".
		 "$uid $pid,$unix_gid weblinktest -l $level $pid $eid",
			 $descriptorspec, $pipes);
178

179
180
    if (! is_resource($process)) {
	return "failed:Linktest failed!";
181
    }
182
183
184
185
186
187
188
189
190
191
    $GLOBALS["process"] = $process;
    fclose($pipes[0]);

    # Build up an output string to return to caller.
    $output = "Starting linktest run at level $level on " .
	date("D M d G:i:s T") . "\n";

    while (!feof($pipes[1])) {
	$string  = fgets($pipes[1], 1024);
	$output .= $string;
192
    }
193
194
    fclose($pipes[1]);
    $retval = proc_close($process);
195
    $fp = 0;
196
197
198
199
200
201
202
203
204
205
206
207
    if ($retval > 0) {
	$output .= "Linktest reported errors! Stopped at " .
	    date("D M d G:i:s T") . "\n";
	return "error:$output";
    }
    elseif ($retval < 0) {
	return "failed:$output";
    }
    # Success.
    $output .= "Linktest run was successful! Stopped at " .
	date("D M d G:i:s T") . "\n";
    return "stopped:$output";
208
209
}

210
211
212
213
# 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();

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

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#
# Okay, this is the initial page.
# 
PAGEHEADER("Run Linktest");

# Must do this!
CHECKPAGEARGS();
GRABDBDATA();

echo "<script>\n";
sajax_show_javascript();
if ($linktest_pid) {
    echo "var curstate    = 'running';";
}
else {
    echo "var curstate    = 'stopped';";
}
?>
function do_start_cb(msg) {
    if (msg == '') {
	return;
    }

    //
    // The first part of the message is an indicator whether linktest
    // really started. 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);

    curstate = 'stopped';
    getObjbyName('action').value = 'Start';

    // Display the data, even if error.
    var stuff = "";

    if (status == 'error') {
	stuff = "<font size=+1 color=red><blink>" +
	    "Linktest has reported errors! Please examine log below." +
	    "</blink></font>";
    }

    stuff = stuff + 
	'<textarea id=outputarea rows=15 cols=90 readonly>' +
	output + '</textarea>';

    getObjbyName('output').innerHTML = stuff;

    // If we got an error; disable the button. 
    if (status == 'failed') {
	getObjbyName('action').disabled = true;    
    }
}

// Linktest stopped. No need to do anything since if a request was running,
// it will have returned to do_start_cb() above, prematurely. 
function do_stop_cb(msg) {
    if (msg == '') {
	return;
    }
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    //
    // 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') {
	alert("Linktest Stop: " + output);
    }
}

function heartbeat() {
    var today=new Date();
    var h=today.getHours();
    var m=today.getMinutes();
    var s=today.getSeconds();
    
    // add a zero in front of numbers<10
    if (m < 10)
	m = "0" + 1;
    if (s < 10)
	s = "0" + 1;

    if (curstate == 'running') {
	getObjbyName('outputarea').value =
	    "Linktest starting up ... please be patient: " + h+":"+m+":"+s;
	setTimeout('heartbeat()', 500);
    }
}

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;

	// Display something so that users activity.
	getObjbyName('output').innerHTML =
	    '<textarea id=outputarea rows=15 cols=90 readonly>' +
	    "Linktest starting up ... please be patient. " + '</textarea>';
	
	curstate = "running";
	theform['action'].value = "Stop Linktest";
	heartbeat();
	x_start_linktest(level, do_start_cb);
    }
    else {
	x_stop_linktest(do_stop_cb);
    }
}
<?php
echo "</script>\n";

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

356
357
358
echo "<center><font size=+2><br>
         Are you <b>sure</b> you want to run linktest?
         </font><br><br>\n";
359

360
SHOWEXP($pid, $eid, 1);
361

362
363
echo "<br>\n";
echo "<form action=linktest.php3 method=post name=myform
364
                target=Linktest_${pid}_${eid}>";
365
366
echo "<input type=hidden name=pid value=$pid>\n";
echo "<input type=hidden name=eid value=$eid>\n";
367

368
369
370
371
372
373
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";
374

375
376
for ($i = 1; $i <= TBDB_LINKTEST_MAX; $i++) {
    $selected = "";
377

378
379
    if (strcmp("$level", "$i") == 0)
	$selected = "selected";
380
	
381
382
383
384
385
    echo "        <option $selected value=$i>Level $i - " .
	$linktest_levels[$i] . "</option>\n";
}
echo "       </select>";
echo "    </td>
386
387
388
          </tr>
          </table><br>\n";

389
390
391
392
393
394
395
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";
396
397
}

398
399
400
401
echo "</form>\n";
echo "<div id=output></div>\n";
echo "</center>\n";

402
#
403
404
405
# Standard Testbed Footer
# 
PAGEFOOTER();
406
?>