Commit eca91b95 authored by Leigh B Stoller's avatar Leigh B Stoller Committed by Gary Wong
Browse files

Checkpoint.

parent fbeb0a2b
...@@ -22,3 +22,11 @@ body > #bodycontainer { height: auto; min-height: 100%; } ...@@ -22,3 +22,11 @@ body > #bodycontainer { height: auto; min-height: 100%; }
height: 1.0em; height: 1.0em;
} }
/* Extra wide modal /*/
.uk-modal-dialog-wide {
width: 800px;
/* 3 */
margin-left: -200px;
/* 4 */
}
...@@ -25,7 +25,7 @@ chdir(".."); ...@@ -25,7 +25,7 @@ chdir("..");
include("defs.php3"); include("defs.php3");
include_once("osinfo_defs.php"); include_once("osinfo_defs.php");
include_once("geni_defs.php"); include_once("geni_defs.php");
chdir("aptui"); chdir("apt");
include("quickvm_sup.php"); include("quickvm_sup.php");
# #
...@@ -197,9 +197,9 @@ function SPITFORM($username, $email, $sshkey, $imageid, $newuser, $errors) ...@@ -197,9 +197,9 @@ function SPITFORM($username, $email, $sshkey, $imageid, $newuser, $errors)
else { else {
$stuffing = substr(GENHASH(), 0, 16); $stuffing = substr(GENHASH(), 0, 16);
} }
mail($email, "Confirm your email to create your Sandbox", mail($email, "Confirm your email to create your Experiment",
"Here is your new user verification code. Please copy and\n". "Here is your user verification code. Please copy and\n".
"paste this code into the box on the sandbox page.\n\n". "paste this code into the box on the experiment page.\n\n".
" $stuffing\n", " $stuffing\n",
"From: $TBMAIL_OPS"); "From: $TBMAIL_OPS");
echo "<input type='hidden' name='stuffing' value='$stuffing' />"; echo "<input type='hidden' name='stuffing' value='$stuffing' />";
...@@ -223,6 +223,7 @@ if (!isset($create)) { ...@@ -223,6 +223,7 @@ if (!isset($create)) {
# #
$username = null; $username = null;
$email = null; $email = null;
$sshkey = null;
if (isset($_COOKIE['quickvm_user'])) { if (isset($_COOKIE['quickvm_user'])) {
$geniuser = GeniUser::Lookup("sa", $_COOKIE['quickvm_user']); $geniuser = GeniUser::Lookup("sa", $_COOKIE['quickvm_user']);
...@@ -315,27 +316,44 @@ $args["username"] = $username; ...@@ -315,27 +316,44 @@ $args["username"] = $username;
$args["email"] = $email; $args["email"] = $email;
$args["imageid"] = $imageid; $args["imageid"] = $imageid;
#
# Need to check for browser cookie, and existing VM.
#
# #
# See if user exists and is verified. We send email with a code, which # See if user exists and is verified. We send email with a code, which
# they have to paste back into a box we add to the form. See above. # they have to paste back into a box we add to the form. See above.
# Maybe use some ajax code here.
# #
if (! ($exists && $exists->IsActive())) { # We also get here if the user exists, but the browser did not have
# the tokens, as will happen if switching to another browser. We
# force the user to repeat the verification with the same code we
# have stored in the DB.
#
if (!$exists || !isset($_COOKIE['quickvm_authkey']) ||
$_COOKIE['quickvm_authkey'] != $exists->auth_token()) {
if (isset($stuffing) && $stuffing != "") { if (isset($stuffing) && $stuffing != "") {
if (! (isset($verify) && $verify == $stuffing)) { if (! (isset($verify) && $verify == $stuffing)) {
SPITFORM($username, $email, $sshkey, $imageid, $stuffing, $errors); SPITFORM($username, $email, $sshkey, $imageid, $stuffing, $errors);
SPITFOOTER(); SPITFOOTER();
return; return;
} }
#
# If this is an existing user and they give us the right code,
# we can check again for an existing VM and redirect to the
# status page, like we do above.
#
if ($exists) {
$quickvm = QuickVM::LookupByCreator($exists->uuid());
if ($quickvm && $quickvm->status() != "terminating") {
header("Location: quickvm_status.php?uuid=" . $quickvm->uuid());
return;
}
}
# Pass to backend to save in user object. # Pass to backend to save in user object.
$args["auth_token"] = $stuffing; $args["auth_token"] = $stuffing;
} }
else { else {
SPITFORM($username, $email, $sshkey, $imageid, true, $errors); # Existing user, use existing auth token.
# New user, we create a new one.
$token = ($exists ? $exists->auth_token() : true);
SPITFORM($username, $email, $sshkey, $imageid, $token, $errors);
SPITFOOTER(); SPITFOOTER();
return; return;
} }
......
...@@ -25,7 +25,7 @@ chdir(".."); ...@@ -25,7 +25,7 @@ chdir("..");
include("defs.php3"); include("defs.php3");
include_once("osinfo_defs.php"); include_once("osinfo_defs.php");
include_once("geni_defs.php"); include_once("geni_defs.php");
chdir("aptui"); chdir("apt");
include("quickvm_sup.php"); include("quickvm_sup.php");
$ajax_request = 0; $ajax_request = 0;
...@@ -39,7 +39,7 @@ $reqargs = OptionalPageArguments("uuid", PAGEARG_STRING, ...@@ -39,7 +39,7 @@ $reqargs = OptionalPageArguments("uuid", PAGEARG_STRING,
"ajax_argument", PAGEARG_STRING); "ajax_argument", PAGEARG_STRING);
if (!isset($uuid)) { if (!isset($uuid)) {
if ($ajax_request) { if ($ajax_request) {
SPITAJAX_ERROR("must provide uuid"); SPITAJAX_ERROR(1, "must provide uuid");
exit(); exit();
} }
SPITHEADER(1); SPITHEADER(1);
...@@ -59,7 +59,7 @@ if (!isset($uuid)) { ...@@ -59,7 +59,7 @@ if (!isset($uuid)) {
$quickvm = QuickVM::Lookup($uuid); $quickvm = QuickVM::Lookup($uuid);
if (!$quickvm) { if (!$quickvm) {
if ($ajax_request) { if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid"); SPITAJAX_ERROR(1, "no such quickvm uuid");
exit(); exit();
} }
SPITHEADER(1); SPITHEADER(1);
...@@ -78,7 +78,7 @@ if (!$quickvm) { ...@@ -78,7 +78,7 @@ if (!$quickvm) {
$creator = GeniUser::Lookup("sa", $quickvm->creator_uuid()); $creator = GeniUser::Lookup("sa", $quickvm->creator_uuid());
if (!$creator) { if (!$creator) {
if ($ajax_request) { if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid"); SPITAJAX_ERROR(1, "no such quickvm uuid");
exit(); exit();
} }
SPITHEADER(1); SPITHEADER(1);
...@@ -95,7 +95,7 @@ if (!$creator) { ...@@ -95,7 +95,7 @@ if (!$creator) {
$slice = GeniSlice::Lookup("sa", $quickvm->slice_uuid()); $slice = GeniSlice::Lookup("sa", $quickvm->slice_uuid());
if (!$slice) { if (!$slice) {
if ($ajax_request) { if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid"); SPITAJAX_ERROR(1, "no slice for quickvm ");
exit(); exit();
} }
SPITHEADER(1); SPITHEADER(1);
...@@ -138,12 +138,39 @@ if (isset($ajax_request)) { ...@@ -138,12 +138,39 @@ if (isset($ajax_request)) {
SPITAJAX_RESPONSE(GateOneAuthObject($creator->uid())); SPITAJAX_RESPONSE(GateOneAuthObject($creator->uid()));
} }
elseif ($ajax_method == "request_extension") { elseif ($ajax_method == "request_extension") {
TBMAIL($TBMAIL_OPS, "Request Extension", $ajax_argument); # Only extend for 24 hours. More later.
SPITAJAX_RESPONSE(""); $expires_time = strtotime($slice->expires());
if ($expires_time > time() + (3600 * 36)) {
SPITAJAX_ERROR(1, "You still have lots of time left!");
return;
}
$retval =
SUEXEC("nobody", "nobody", "webquickvm -e " . 3600 * 24 . " $uuid",
SUEXEC_ACTION_CONTINUE);
if ($retval == 0) {
# Refresh.
$slice = GeniSlice::Lookup("sa", $quickvm->slice_uuid());
$new_expires = gmdate("Y-m-d H:i:s",
strtotime($slice->expires())) . " GMT";
SPITAJAX_RESPONSE($new_expires);
TBMAIL($creator->email(),
"APT Extension: $uuid",
"A request to extend your APT experiment was made and ".
"granted.\n".
"Your reason was:\n\n". $ajax_argument . "\n".
"Your experiment will now expire at $new_expires\n",
"CC: $TBMAIL_OPS");
}
else {
SPITAJAX_ERROR(-1, "Internal Error. Please try again later");
}
} }
elseif ($ajax_method == "extend") { elseif ($ajax_method == "extend") {
TBMAIL($TBMAIL_OPS, "Extend", $ajax_argument); SPITAJAX_ERROR(1, "Not implemented yet!");
SPITAJAX_RESPONSE("");
} }
exit(); exit();
} }
...@@ -159,6 +186,7 @@ $creator_email = $creator->email(); ...@@ -159,6 +186,7 @@ $creator_email = $creator->email();
$quickvm_profile = $quickvm->profile(); $quickvm_profile = $quickvm->profile();
$slice_url = ""; $slice_url = "";
$color = ""; $color = "";
$disabled = "disabled";
$spin = 1; $spin = 1;
if ($quickvm_status == "failed") { if ($quickvm_status == "failed") {
$color = "color=red"; $color = "color=red";
...@@ -167,6 +195,7 @@ if ($quickvm_status == "failed") { ...@@ -167,6 +195,7 @@ if ($quickvm_status == "failed") {
elseif ($quickvm_status == "ready") { elseif ($quickvm_status == "ready") {
$color = "color=green"; $color = "color=green";
$spin = 0; $spin = 0;
$disabled = "";
} }
elseif ($quickvm_status == "created") { elseif ($quickvm_status == "created") {
$spinwidth = "33"; $spinwidth = "33";
...@@ -209,7 +238,8 @@ echo "<td class='uk-width-4-5' $style>$quickvm_profile</td>\n"; ...@@ -209,7 +238,8 @@ echo "<td class='uk-width-4-5' $style>$quickvm_profile</td>\n";
echo "</tr>\n"; echo "</tr>\n";
echo "<tr>\n"; echo "<tr>\n";
echo "<td class='uk-width-1-5' $style>Expires:</td>\n"; echo "<td class='uk-width-1-5' $style>Expires:</td>\n";
echo "<td class='uk-width-4-5' $style>$slice_expires - Time left: echo "<td class='uk-width-4-5' $style>
<span id='quickvm_expires'>$slice_expires</span> - Time left:
<span id='quickvm_countdown'></span></td>\n"; <span id='quickvm_countdown'></span></td>\n";
echo "</tr>\n"; echo "</tr>\n";
echo "</table>\n"; echo "</table>\n";
...@@ -218,11 +248,11 @@ echo " <button class='uk-button uk-button-primary' ...@@ -218,11 +248,11 @@ echo " <button class='uk-button uk-button-primary'
id='register_button' type=button id='register_button' type=button
onclick=\"ShowModal('#register_modal'); return false;\"> onclick=\"ShowModal('#register_modal'); return false;\">
Register</button>\n"; Register</button>\n";
echo " <button class='uk-button uk-button-success' echo " <button class='uk-button uk-button-success' $disabled
id='extend_button' type=button id='extend_button' type=button
onclick=\"ShowModal('#extend_modal'); return false;\"> onclick=\"ShowModal('#extend_modal'); return false;\">
Extend</button>\n"; Extend</button>\n";
echo " <button class='uk-button uk-button-danger' echo " <button class='uk-button uk-button-danger' $disabled
id='terminate_button' type=button id='terminate_button' type=button
onclick=\"ShowModal('#terminate_modal'); return false;\"> onclick=\"ShowModal('#terminate_modal'); return false;\">
Terminate</button>\n"; Terminate</button>\n";
...@@ -259,18 +289,18 @@ echo "<!-- This is a modal --> ...@@ -259,18 +289,18 @@ echo "<!-- This is a modal -->
# #
echo "<!-- This is a modal --> echo "<!-- This is a modal -->
<div id='extend_modal' class='uk-modal'> <div id='extend_modal' class='uk-modal'>
<div class='uk-modal-dialog'> <div class='uk-modal-dialog uk-modal-dialog-wide'>
<a href='' class='uk-modal-close uk-close'></a> <a href='' class='uk-modal-close uk-close'></a>
<div class='uk-grid uk-grid-divider' data-uk-grid-match> <div class='uk-grid uk-grid-divider' data-uk-grid-match>
<div class='uk-width-2-3'> <div class='uk-width-1-2'>
If you want to extend this experiment so that it does If you want to extend this experiment so that it does
not self-terminate at the time shown, you can request an not self-terminate at the time shown, just tell us why
extension code from us. Just tell us why. A reply will and we will extend it for another 24 hours.
arrive via email as soon as possible. Watch for an email message that says its been done.
<form id='extend_request_form'> <form id='extend_request_form'>
<div class='uk-form-controls'> <div class='uk-form-controls'>
<textarea id='why_extend' name='why_extend' <textarea id='why_extend' name='why_extend'
placeholder='Tell us a story please' placeholder='Tell us a good story please.'
class='uk-width-100 uk-align-center' class='uk-width-100 uk-align-center'
rows=5></textarea> rows=5></textarea>
<br> <br>
...@@ -281,15 +311,17 @@ echo "<!-- This is a modal --> ...@@ -281,15 +311,17 @@ echo "<!-- This is a modal -->
</div> </div>
</form> </form>
</div> </div>
<div class='uk-width-1-3'> <div class='uk-width-1-2'>
<form id='extend_form'> To extend your experiment for more then another 24 hours,
<center>Got your code?</center><br> you need an extension code. If you do not have a code then
you need not worry about it.
<form id='extend_form'>
<div class='uk-form-controls'> <div class='uk-form-controls'>
<input id='extend_code' name='extend_code' <input id='extend_code' name='extend_code'
class='uk-form-width-small uk-align-center' class='uk-form-width-small uk-align-center'
placeholder='Extension code' autofocus type='text' /> placeholder='Extension code' autofocus type='text' />
<br> <br>
<button class='uk-button uk-button-primary uk-button-small <button class='uk-button uk-button-primary uk-button-small
uk-align-center' uk-align-center'
onclick=\"Extend('$uuid'); return false;\" onclick=\"Extend('$uuid'); return false;\"
type='submit' name='extend'>Extend</button> type='submit' name='extend'>Extend</button>
......
...@@ -8,7 +8,7 @@ function ShowModal(which) ...@@ -8,7 +8,7 @@ function ShowModal(which)
function HideModal(which) function HideModal(which)
{ {
$( which ).hide(); $( which ).hide();
console.log('Showing modal ' + which); console.log('Hide modal ' + which);
} }
function CallMethod(method, callback, uuid, arg) function CallMethod(method, callback, uuid, arg)
...@@ -26,7 +26,7 @@ function CallMethod(method, callback, uuid, arg) ...@@ -26,7 +26,7 @@ function CallMethod(method, callback, uuid, arg)
}, },
// whether this is a POST or GET request // whether this is a POST or GET request
type: "GET", type: (arg ? "POST" : "GET"),
// the type of data we expect back // the type of data we expect back
dataType : "json", dataType : "json",
...@@ -36,7 +36,7 @@ function CallMethod(method, callback, uuid, arg) ...@@ -36,7 +36,7 @@ function CallMethod(method, callback, uuid, arg)
function GetStatus(uuid) function GetStatus(uuid)
{ {
var callback = function(json) { var callback = function(json) {
StatusWatchCallBack(uuid, json.value); StatusWatchCallBack(uuid, json);
} }
var $xmlthing = CallMethod("status", null, uuid, null); var $xmlthing = CallMethod("status", null, uuid, null);
$xmlthing.done(callback); $xmlthing.done(callback);
...@@ -49,13 +49,17 @@ function StartStatusWatch(uuid) ...@@ -49,13 +49,17 @@ function StartStatusWatch(uuid)
} }
// Call back for above. // Call back for above.
function StatusWatchCallBack(uuid, status) function StatusWatchCallBack(uuid, json)
{ {
// Check to see if the static variable has been initialized // Check to see if the static variable has been initialized
if (typeof StatusWatchCallBack.laststatus == 'undefined') { if (typeof StatusWatchCallBack.laststatus == 'undefined') {
// It has not... perform the initilization // It has not... perform the initilization
StatusWatchCallBack.laststatus = ""; StatusWatchCallBack.laststatus = "";
} }
var status = json.value;
if (json.code) {
status = "terminated";
}
console.log(status); console.log(status);
if (status != StatusWatchCallBack.laststatus) { if (status != StatusWatchCallBack.laststatus) {
...@@ -72,6 +76,8 @@ function StatusWatchCallBack(uuid, status) ...@@ -72,6 +76,8 @@ function StatusWatchCallBack(uuid, status)
$("#quickvm_progress").addClass("uk-progress-success"); $("#quickvm_progress").addClass("uk-progress-success");
$("#quickvm_progress_bar").width("100%"); $("#quickvm_progress_bar").width("100%");
} }
$("#terminate_button").prop("disabled", false);
$("#extend_button").prop("disabled", false);
ShowTopo(uuid); ShowTopo(uuid);
} }
else if (status == 'failed') { else if (status == 'failed') {
...@@ -83,15 +89,16 @@ function StatusWatchCallBack(uuid, status) ...@@ -83,15 +89,16 @@ function StatusWatchCallBack(uuid, status)
$("#quickvm_progress_bar").width("100%"); $("#quickvm_progress_bar").width("100%");
} }
} }
else if (status == 'terminating') { else if (status == 'terminating' || status == 'terminated') {
status_html = "<font color=red>failed</font>"; status_html = "<font color=red>" + status + "</font>";
$("#terminate_button").prop("disabled", true); $("#terminate_button").prop("disabled", true);
$("#extend_button").prop("disabled", true); $("#extend_button").prop("disabled", true);
StartCountdownClock.stop = 0;
} }
$("#quickvm_status").html(status_html); $("#quickvm_status").html(status_html);
} }
StatusWatchCallBack.laststatus = status; StatusWatchCallBack.laststatus = status;
if (status != "terminating") { if (! (status == 'terminating' || status == 'terminated')) {
setTimeout(function f() { GetStatus(uuid) }, 5000); setTimeout(function f() { GetStatus(uuid) }, 5000);
} }
} }
...@@ -103,6 +110,7 @@ function Terminate(uuid, url) ...@@ -103,6 +110,7 @@ function Terminate(uuid, url)
} }
$("#terminate_button").prop("disabled", true); $("#terminate_button").prop("disabled", true);
$("#extend_button").prop("disabled", true); $("#extend_button").prop("disabled", true);
$('#terminate_modal').hide();
var $xmlthing = CallMethod("terminate", null, uuid, null); var $xmlthing = CallMethod("terminate", null, uuid, null);
$xmlthing.done(callback); $xmlthing.done(callback);
...@@ -150,11 +158,26 @@ function RequestExtension(uuid) ...@@ -150,11 +158,26 @@ function RequestExtension(uuid)
{ {
var reason = $("#why_extend").val(); var reason = $("#why_extend").val();
console.log(reason); console.log(reason);
if (reason == "") { if (reason.length < 30) {
alert("Your reason is too short! Say more please.");
return; return;
} }
var callback = function(json) { var callback = function(json) {
alert("Your request has been sent"); console.log(json.value);
if (json.code) {
if (json.code < 0) {
alert("Could not extend experiment. Please try again later");
}
else {
alert("Could not extend experiment: " + json.value);
}
return;
}
$("#quickvm_expires").html(json.value);
// Reset the countdown clock.
StartCountdownClock.reset = json.value;
} }
var $xmlthing = CallMethod("request_extension", null, uuid, reason); var $xmlthing = CallMethod("request_extension", null, uuid, reason);
$('#extend_modal').hide(); $('#extend_modal').hide();
...@@ -169,7 +192,7 @@ function Extend(uuid) ...@@ -169,7 +192,7 @@ function Extend(uuid)
return; return;
} }
var callback = function(json) { var callback = function(json) {
alert("Your request has been sent"); console.log(json.value);
} }
var $xmlthing = CallMethod("extend", null, uuid, code); var $xmlthing = CallMethod("extend", null, uuid, code);
$('#extend_modal').hide(); $('#extend_modal').hide();
...@@ -232,21 +255,39 @@ function StartGateOne(sshurl) ...@@ -232,21 +255,39 @@ function StartGateOne(sshurl)
// //
function StartCountdownClock(when) function StartCountdownClock(when)
{ {
// Use this static variable to force clock reset.
StartCountdownClock.reset = when;
// Use this static variable to force clock stop
StartCountdownClock.stop = 0;
// set the date we're counting down to // set the date we're counting down to
var target_date = new Date(when).getTime(); var target_date = new Date(when).getTime();
// variables for time units // variables for time units
var days, hours, minutes, seconds; var days, hours, minutes, seconds;
// update the tag with id "countdown" every 1 second // update the tag with id "countdown" every 1 second
setInterval(function () { var updater = setInterval(function () {
// Clock stop
if (StartCountdownClock.stop) {
// Amazing that this works!
clearInterval(updater);
}
// Clock reset
if (StartCountdownClock.reset != when) {
when = StartCountdownClock.reset;
target_date = new Date(when).getTime();
}
// find the amount of "seconds" between now and target // find the amount of "seconds" between now and target
var current_date = new Date().getTime(); var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000; var seconds_left = (target_date - current_date) / 1000;
if (seconds_left <= 0) { if (seconds_left <= 0) {
$("#terminate_button").prop("disabled", true); // Amazing that this works!
$("#extend_button").prop("disabled", true); clearInterval(updater);
return; return;
} }
......
...@@ -27,7 +27,7 @@ function SPITHEADER($thinheader = 0) ...@@ -27,7 +27,7 @@ function SPITHEADER($thinheader = 0)
echo "<html> echo "<html>
<head> <head>
<title>AptLab.io - SSH</title> <title>AptLab</title>
<!-- UIKit --> <!-- UIKit -->
<link rel='stylesheet' href='uikit/css/uikit.almost-flat.css'> <link rel='stylesheet' href='uikit/css/uikit.almost-flat.css'>
<link rel='stylesheet' href='quickvm.css'> <link rel='stylesheet' href='quickvm.css'>
...@@ -73,17 +73,15 @@ function SPITAJAX_RESPONSE($value) ...@@ -73,17 +73,15 @@ function SPITAJAX_RESPONSE($value)
'value' => $value 'value' => $value
); );
echo json_encode($results); echo json_encode($results);
exit();
} }