swapexp.php3 10.7 KB
Newer Older
1
<?php
Leigh Stoller's avatar
Leigh Stoller committed
2
#
3
# Copyright (c) 2000-2015 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/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
23
#
24
include("defs.php3");
25
include_once("template_defs.php");
26 27

#
28
# Only known and logged in users.
29
#
30 31 32
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
33

34 35 36
# This will not return if its a sajax request.
include("showlogfile_sup.php3");

37
#
38 39 40 41 42 43 44 45 46 47 48
# 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);
				 
49
if (!isset($inout) ||
50
    (strcmp($inout, "in") && strcmp($inout, "out") &&
51 52 53
     strcmp($inout, "pause") && strcmp($inout, "restart") &&
     strcmp($inout, "instop"))) {
    USERERROR("Improper inout argument!", 1);
54 55
}

56
# Canceled operation redirects back to showexp page. See below.
57 58
if (isset($canceled) && $canceled) {
    header("Location: ". CreateURL("showexp", $experiment));
59 60 61 62 63 64 65 66
    return;
}

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

67 68 69 70
#
# Only admins can issue a force swapout
# 
if (isset($force) && $force == 1) {
71
	if (! $isadmin) {
72 73 74
		USERERROR("Only testbed administrators can forcibly swap ".
			  "an experiment out!", 1);
	}
75 76
	if (!isset($idleswap)) { $idleswap=0; }
	if (!isset($autoswap)) { $autoswap=0; }
77 78 79
	if (!isset($forcetype)){ $forcetype="force"; }
	if ($forcetype=="idleswap") { $idleswap=1; }
	if ($forcetype=="autoswap") { $autoswap=1; }
80 81
}
else {
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    # 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;
105 106
}

107 108 109 110
# Need these below
$pid = $experiment->pid();
$eid = $experiment->eid();
$unix_gid = $experiment->UnixGID();
111 112
$project  = $experiment->Project();
$unix_pid = $project->unix_gid();
113 114 115 116

#
# Verify permissions.
#
117 118
if (!$experiment->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
    USERERROR("You do not have permission for $eid!", 1);
119 120
}

121 122 123 124 125 126 127 128
$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();
129
$isgeni        = $experiment->geniflags();
130

131
# Template Instance Experiments get special treatment in this page.
132
$instance = TemplateInstance::LookupByExptidx($exptidx);
133

134 135 136 137 138 139 140 141 142
# Convert inout to informative text.
if (!strcmp($inout, "in")) {
    if ($isbatch) 
	$action = "queue";
    else
	$action = "swapin";
}
elseif (!strcmp($inout, "out")) {
    if ($isbatch) 
143
	$action = "swapout and dequeue";
144
    else {
145
	if ($state == $TB_EXPTSTATE_ACTIVATING) {
146 147 148 149 150 151
	    $action = "cancel";
	}
	else {
	    $action = "swapout";
	}
    }
152 153 154
}
elseif (!strcmp($inout, "pause")) {
    if (!$isbatch)
155
	USERERROR("Only batch experiments can be dequeued!", 1);
156
    $action = "dequeue";
157 158
}
elseif (!strcmp($inout, "restart")) {
Leigh Stoller's avatar
Leigh Stoller committed
159 160
    if ($instance)
        PAGEARGERROR("Invalid action for template instance");
161 162 163
    $action = "restart";
}

164
if ($instance) {
Leigh Stoller's avatar
Leigh Stoller committed
165 166 167 168 169 170 171
    $guid = $instance->guid();
    $version = $instance->vers();
    
    echo "<font size=+2>Template <b>" .
          MakeLink("template",
		   "guid=$guid&version=$version", "$guid/$version") .
	"</b>, Instance <b>";
172 173 174 175
}
else {
    echo "<font size=+2>Experiment <b>";
}
Leigh Stoller's avatar
Leigh Stoller committed
176 177 178
echo MakeLink("project", "pid=$pid", $pid) . "/" .
     MakeLink("experiment", "pid=$pid&eid=$eid", $eid);
echo "</b></font><br>\n";
179
flush();
180

181 182 183 184 185 186
# A locked down experiment means just that!
if ($lockdown) {
    echo "<br><br>\n";
    USERERROR("Cannot proceed; the experiment is locked down!", 1);
}

187 188 189
#
# 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
190 191
# set. Or, the user can hit the cancel button, in which case we 
# redirect the browser back to the experiment page (see above).
192
#
193
if (!isset($confirmed)) {
194
    echo "<center><h2><br>
195 196
          Are you sure you want to ";
    if ($force) {
197
	echo "<font color=red><br>forcibly</br></font> ";
198
    }
199
    if ($instance) {
200
	echo "$action template instance";
201 202 203 204
    }
    else {
	echo "$action experiment";
    }
205
    echo " '$eid?'
206 207
          </h2>\n";
    
208
    $experiment->Show(1);
209

210
    echo "<form action='swapexp.php3?inout=$inout&pid=$pid&eid=$eid'
211
                method=post>";
212 213

    if ($force) {
214 215 216
	if (!$swappable) {
	    echo "<h2>Note: This experiment is <em>NOT</em> swappable!</h2>\n";
	}
217 218 219 220 221 222 223 224
	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";
225 226 227
	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";
228 229
    }
    
230 231
    echo "<b><input type=submit name=confirmed value=Confirm></b>\n";
    echo "<b><input type=submit name=canceled value=Cancel></b>\n";
232
    echo "</form>\n";
233

234
    if ($inout!="out" && $idleswap_bit) {
235 236 237 238
	if ($idleswap_time / 60.0 != $idlethresh) {
	    echo "<p>Note: The Idle-Swap time for your experiment will be
		 reset to $idlethresh hours.</p>\n";
	}
239 240
    }
    
241 242
    if (!strcmp($inout, "restart")) {
	echo "<p>
243
              <a href='$TBDOCBASE/faq.php3#restart'>
244 245 246 247
                 (Information on experiment restart)</a>\n";
    }
    else {
	echo "<p>
248
              <a href='$TBDOCBASE/faq.php3#swapping'>
249 250
                 (Information on experiment swapping)</a>\n";
    }
251 252 253 254 255 256
    echo "</center>\n";

    PAGEFOOTER();
    return;
}

257 258
STARTBUSY("Starting");

259 260 261
if ($instance) {
    $guid = $instance->guid();
    $version = $instance->vers();
Leigh Stoller's avatar
Leigh Stoller committed
262

Leigh Stoller's avatar
Leigh Stoller committed
263 264
    if ($inout == "pause")
	$inout = "out";
265 266
}

267 268 269 270 271
#
# 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. 
#
272 273 274 275
# Avoid SIGPROF in child.
# 
set_time_limit(0);

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

280
$retval = SUEXEC($uid, "$unix_pid,$unix_gid",
281
		  ($force ?
282
		   "webidleswap $args $pid,$eid" :
283
		   ($instance ?
284 285
		    "webtemplate_swap$inout -e $eid $guid/$version" :
		    "webswapexp -s $inout $pid $eid")),
286
		 SUEXEC_ACTION_IGNORE);
287

288
HIDEBUSY();
289

290 291 292 293 294 295 296 297 298
#
# 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 ...
    #
299 300 301 302 303 304
    die("");
}

#
# Exit status 0 means the experiment is swapping, or will be.
#
305 306
echo "<br>\n";
if ($retval) {
307
    echo "<h3>$action could not proceed</h3>";
308 309 310
    echo "<blockquote><pre>$suexec_output<pre></blockquote>";
}
else {
311 312 313 314 315 316 317 318 319
    if ($instance) {
	if ($isbatch) {
	    STARTWATCHER($experiment);
	    STARTLOG($instance);
	}
	else {
	    STARTLOG($experiment);
	}
    }
320 321 322
    elseif ($isgeni) {
        echo "Done!";
    }
323
    elseif ($isbatch) {
324 325 326 327 328 329 330 331 332
	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) {
333

334 335 336 337 338 339 340 341 342 343
	    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
344
	    echo "Your experiment has been dequeued.
345
		  You may requeue your experiment at any time.\n";
346
	}
347
	STARTWATCHER($experiment);
348 349
    }
    else {
350
	echo "<div>";
351
	if (strcmp($inout, "out") == 0 &&
352
	    strcmp($state, $TB_EXPTSTATE_ACTIVATING) == 0) {
353 354 355 356 357

	    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
358
                  either aborted or finished. ";
359 360 361 362 363 364
	}
	else {
	    if (strcmp($inout, "in") == 0)
		$howlong = "two to ten";
	    else
		$howlong = "less than two";
365
    
366
	    echo "<b>Your experiment has started its $action.</b> 
367 368
                 You will be notified via email when the operation is complete.
                 This typically takes $howlong minutes, depending on the
369
                 number of nodes in the experiment. ";
370
	}
371
	echo "If you do not receive
372 373
              email notification within a reasonable amount of time,
              please contact $TBMAILADDR.\n";
374
	echo "</div>";
375
	echo "<br>\n";
376
	STARTLOG($experiment);
377
    }
378 379 380 381 382 383 384
}

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