swapexp.php3 9.89 KB
Newer Older
1
<?php
Leigh Stoller's avatar
Leigh Stoller committed
2 3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
Leigh Stoller's avatar
Leigh Stoller committed
5 6
# All rights reserved.
#
7
include("defs.php3");
8
include_once("template_defs.php");
9 10

#
11
# Only known and logged in users.
12
#
13 14 15
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
16

17 18 19
# This will not return if its a sajax request.
include("showlogfile_sup.php3");

20
#
21 22 23 24 25 26 27 28 29 30 31
# Verify Page Arguments.
#
$reqargs = RequiredPageArguments("experiment", PAGEARG_EXPERIMENT,
				 "inout",      PAGEARG_STRING);
$optargs = OptionalPageArguments("canceled",   PAGEARG_STRING,
				 "confirmed",  PAGEARG_STRING,
				 "force",      PAGEARG_BOOLEAN,
				 "forcetype",  PAGEARG_STRING,
				 "idleswap",   PAGEARG_BOOLEAN,
				 "autoswap",   PAGEARG_BOOLEAN);
				 
32
if (!isset($inout) ||
33
    (strcmp($inout, "in") && strcmp($inout, "out") &&
34 35 36
     strcmp($inout, "pause") && strcmp($inout, "restart") &&
     strcmp($inout, "instop"))) {
    USERERROR("Improper inout argument!", 1);
37 38
}

39
# Canceled operation redirects back to showexp page. See below.
40 41
if (isset($canceled) && $canceled) {
    header("Location: ". CreateURL("showexp", $experiment));
42 43 44 45 46 47 48 49
    return;
}

#
# Standard Testbed Header, after cancel above.
#
PAGEHEADER("Swap Control");

50 51 52 53
#
# Only admins can issue a force swapout
# 
if (isset($force) && $force == 1) {
54
	if (! $isadmin) {
55 56 57
		USERERROR("Only testbed administrators can forcibly swap ".
			  "an experiment out!", 1);
	}
58 59
	if (!isset($idleswap)) { $idleswap=0; }
	if (!isset($autoswap)) { $autoswap=0; }
60 61 62
	if (!isset($forcetype)){ $forcetype="force"; }
	if ($forcetype=="idleswap") { $idleswap=1; }
	if ($forcetype=="autoswap") { $autoswap=1; }
63 64
}
else {
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    # Must go through the geni interfaces.
    if ($experiment->geniflags()) {
	USERERROR("You must use forceable swap on ProtoGeni experiments", 1);
    }
    
    #
    # If the user is not a member of the group, it
    # must be an admin, and in that case we want him to use the force
    # swapout path to avoid permission issues.
    #
    $group = $experiment->Group();
    if (!isset($group)) {
	TBERROR("Could not get group object for $pid/eid", 1);
    }
    if (!$group->IsMember($this_user, $ignore) && $isadmin) {
	USERERROR("Since you are an administrator trying to swap out ".
		  "an experiment in a project/group you do not belong to, ".
		  "please go back and use the forcible swap options instead.",
		  1);
    }
    $force = 0;
    $idleswap=0;
    $autoswap=0;
88 89
}

90 91 92 93
# Need these below
$pid = $experiment->pid();
$eid = $experiment->eid();
$unix_gid = $experiment->UnixGID();
94 95 96 97

#
# Verify permissions.
#
98 99
if (!$experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
    USERERROR("You do not have permission for $eid!", 1);
100 101
}

102 103 104 105 106 107 108 109 110
$isbatch       = $experiment->batchmode();
$state         = $experiment->state();
$exptidx       = $experiment->idx();
$swappable     = $experiment->swappable();
$idleswap_bit  = $experiment->idleswap();
$idleswap_time = $experiment->idleswap_timeout();
$idlethresh    = min($idleswap_time/60.0,TBGetSiteVar("idle/threshold"));
$lockdown      = $experiment->lockdown();

111
# Template Instance Experiments get special treatment in this page.
112
$instance = TemplateInstance::LookupByExptidx($exptidx);
113

114 115 116 117 118 119 120 121 122
# Convert inout to informative text.
if (!strcmp($inout, "in")) {
    if ($isbatch) 
	$action = "queue";
    else
	$action = "swapin";
}
elseif (!strcmp($inout, "out")) {
    if ($isbatch) 
123
	$action = "swapout and dequeue";
124
    else {
125
	if ($state == $TB_EXPTSTATE_ACTIVATING) {
126 127 128 129 130 131
	    $action = "cancel";
	}
	else {
	    $action = "swapout";
	}
    }
132 133 134
}
elseif (!strcmp($inout, "pause")) {
    if (!$isbatch)
135
	USERERROR("Only batch experiments can be dequeued!", 1);
136
    $action = "dequeue";
137 138
}
elseif (!strcmp($inout, "restart")) {
Leigh Stoller's avatar
Leigh Stoller committed
139 140
    if ($instance)
        PAGEARGERROR("Invalid action for template instance");
141 142 143
    $action = "restart";
}

144
if ($instance) {
Leigh Stoller's avatar
Leigh Stoller committed
145 146 147 148 149 150 151
    $guid = $instance->guid();
    $version = $instance->vers();
    
    echo "<font size=+2>Template <b>" .
          MakeLink("template",
		   "guid=$guid&version=$version", "$guid/$version") .
	"</b>, Instance <b>";
152 153 154 155
}
else {
    echo "<font size=+2>Experiment <b>";
}
Leigh Stoller's avatar
Leigh Stoller committed
156 157 158
echo MakeLink("project", "pid=$pid", $pid) . "/" .
     MakeLink("experiment", "pid=$pid&eid=$eid", $eid);
echo "</b></font><br>\n";
159
flush();
160

161 162 163 164 165 166
# A locked down experiment means just that!
if ($lockdown) {
    echo "<br><br>\n";
    USERERROR("Cannot proceed; the experiment is locked down!", 1);
}

167 168 169
#
# We run this twice. The first time we are checking for a confirmation
# by putting up a form. The next time through the confirmation will be
170 171
# set. Or, the user can hit the cancel button, in which case we 
# redirect the browser back to the experiment page (see above).
172
#
173
if (!isset($confirmed)) {
174
    echo "<center><h2><br>
175 176
          Are you sure you want to ";
    if ($force) {
177
	echo "<font color=red><br>forcibly</br></font> ";
178
    }
179
    if ($instance) {
180
	echo "$action template instance";
181 182 183 184
    }
    else {
	echo "$action experiment";
    }
185
    echo " '$eid?'
186 187
          </h2>\n";
    
188
    $experiment->Show(1);
189

190
    echo "<form action='swapexp.php3?inout=$inout&pid=$pid&eid=$eid'
191
                method=post>";
192 193

    if ($force) {
194 195 196
	if (!$swappable) {
	    echo "<h2>Note: This experiment is <em>NOT</em> swappable!</h2>\n";
	}
197 198 199 200 201 202 203 204
	echo "Force Type: <select name=forcetype>\n";
	echo "<option value=force ".($forcetype=="force"?"selected":"").
	    ">Forced Swap</option>\n";
	echo "<option value=idleswap ".($forcetype=="idleswap"?"selected":"").
	    ">Idle-Swap</option>\n";
	echo "<option value=autoswap ".($forcetype=="autoswap"?"selected":"").
	    ">Auto-Swap</option>\n";
	echo "</select><br><br>\n";
205 206 207
	echo "<input type=hidden name=force value=$force>\n";
	echo "<input type=hidden name=idleswap value=$idleswap>\n";
	echo "<input type=hidden name=autoswap value=$autoswap>\n";
208 209
    }
    
210 211
    echo "<b><input type=submit name=confirmed value=Confirm></b>\n";
    echo "<b><input type=submit name=canceled value=Cancel></b>\n";
212
    echo "</form>\n";
213

214
    if ($inout!="out" && $idleswap_bit) {
215 216 217 218
	if ($idleswap_time / 60.0 != $idlethresh) {
	    echo "<p>Note: The Idle-Swap time for your experiment will be
		 reset to $idlethresh hours.</p>\n";
	}
219 220
    }
    
221 222
    if (!strcmp($inout, "restart")) {
	echo "<p>
223
              <a href='$TBDOCBASE/faq.php3#restart'>
224 225 226 227
                 (Information on experiment restart)</a>\n";
    }
    else {
	echo "<p>
228
              <a href='$TBDOCBASE/faq.php3#swapping'>
229 230
                 (Information on experiment swapping)</a>\n";
    }
231 232 233 234 235 236
    echo "</center>\n";

    PAGEFOOTER();
    return;
}

237 238
STARTBUSY("Starting");

239 240 241
if ($instance) {
    $guid = $instance->guid();
    $version = $instance->vers();
Leigh Stoller's avatar
Leigh Stoller committed
242

Leigh Stoller's avatar
Leigh Stoller committed
243 244
    if ($inout == "pause")
	$inout = "out";
245 246
}

247 248 249 250 251
#
# Run the scripts. We use a script wrapper to deal with changing
# to the proper directory and to keep some of these details out
# of this. 
#
252 253 254 255
# Avoid SIGPROF in child.
# 
set_time_limit(0);

256 257
# Args for idleswap It passes them on to swapexp, or if it is just a
# plain force swap, it passes -f for us.
258
$args = ($idleswap ? "-i" : ($autoswap ? "-a" : ""));
259

260
$retval = SUEXEC($uid, "$pid,$unix_gid",
261
		  ($force ?
262
		   "webidleswap $args $pid,$eid" :
263
		   ($instance ?
264 265
		    "webtemplate_swap$inout -e $eid $guid/$version" :
		    "webswapexp -s $inout $pid $eid")),
266
		 SUEXEC_ACTION_IGNORE);
267

268
HIDEBUSY();
269

270 271 272 273 274 275 276 277 278
#
# Fatal Error. Report to the user, even though there is not much he can
# do with the error. Also reports to tbops.
# 
if ($retval < 0) {
    SUEXECERROR(SUEXEC_ACTION_DIE);
    #
    # Never returns ...
    #
279 280 281 282 283 284
    die("");
}

#
# Exit status 0 means the experiment is swapping, or will be.
#
285 286
echo "<br>\n";
if ($retval) {
287
    echo "<h3>$action could not proceed</h3>";
288 289 290
    echo "<blockquote><pre>$suexec_output<pre></blockquote>";
}
else {
291 292 293 294 295 296 297 298 299 300
    if ($instance) {
	if ($isbatch) {
	    STARTWATCHER($experiment);
	    STARTLOG($instance);
	}
	else {
	    STARTLOG($experiment);
	}
    }
    elseif ($isbatch) {
301 302 303 304 305 306 307 308 309
	if (strcmp($inout, "in") == 0) {
	    echo "Batch Mode experiments will be run when enough resources
                  become available. This might happen immediately, or it
                  may take hours or days. You will be notified via email
                  when the experiment has been run. In the meantime, you can
                  check the web page to see how many attempts have been made,
                  and when the last attempt was.\n";
	}
	elseif (strcmp($inout, "out") == 0) {
310

311 312 313 314 315 316 317 318 319 320
	    echo "Batch mode experiments take a few moments to stop. Once
                  it does, the experiment will enter the 'paused' state.
                  You can requeue the batch experiment at that time.\n";

	    echo "<br><br>
                  If you do not receive
                  email notification within a reasonable amount of time,
                  please contact $TBMAILADDR.\n";
	}
	elseif (strcmp($inout, "pause") == 0) {
Leigh Stoller's avatar
Leigh Stoller committed
321
	    echo "Your experiment has been dequeued.
322
		  You may requeue your experiment at any time.\n";
323
	}
324
	STARTWATCHER($experiment);
325 326
    }
    else {
327
	echo "<div>";
328
	if (strcmp($inout, "out") == 0 &&
329
	    strcmp($state, $TB_EXPTSTATE_ACTIVATING) == 0) {
330 331 332 333 334

	    echo "Your experiment swapin has been marked for cancelation.
                  It typically takes a few minutes for this to be recognized,
                  assuming you made your request early enough. You will
                  be notified via email when the original swapin request has
335
                  either aborted or finished. ";
336 337 338 339 340 341
	}
	else {
	    if (strcmp($inout, "in") == 0)
		$howlong = "two to ten";
	    else
		$howlong = "less than two";
342
    
343
	    echo "<b>Your experiment has started its $action.</b> 
344 345
                 You will be notified via email when the operation is complete.
                 This typically takes $howlong minutes, depending on the
346
                 number of nodes in the experiment. ";
347
	}
348
	echo "If you do not receive
349 350
              email notification within a reasonable amount of time,
              please contact $TBMAILADDR.\n";
351
	echo "</div>";
352
	echo "<br>\n";
353
	STARTLOG($experiment);
354
    }
355 356 357 358 359 360 361
}

#
# Standard Testbed Footer
# 
PAGEFOOTER();
?>