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

Checkpoint.

parent fbeb0a2b
......@@ -22,3 +22,11 @@ body > #bodycontainer { height: auto; min-height: 100%; }
height: 1.0em;
}
/* Extra wide modal /*/
.uk-modal-dialog-wide {
width: 800px;
/* 3 */
margin-left: -200px;
/* 4 */
}
......@@ -25,7 +25,7 @@ chdir("..");
include("defs.php3");
include_once("osinfo_defs.php");
include_once("geni_defs.php");
chdir("aptui");
chdir("apt");
include("quickvm_sup.php");
#
......@@ -197,9 +197,9 @@ function SPITFORM($username, $email, $sshkey, $imageid, $newuser, $errors)
else {
$stuffing = substr(GENHASH(), 0, 16);
}
mail($email, "Confirm your email to create your Sandbox",
"Here is your new user verification code. Please copy and\n".
"paste this code into the box on the sandbox page.\n\n".
mail($email, "Confirm your email to create your Experiment",
"Here is your user verification code. Please copy and\n".
"paste this code into the box on the experiment page.\n\n".
" $stuffing\n",
"From: $TBMAIL_OPS");
echo "<input type='hidden' name='stuffing' value='$stuffing' />";
......@@ -223,6 +223,7 @@ if (!isset($create)) {
#
$username = null;
$email = null;
$sshkey = null;
if (isset($_COOKIE['quickvm_user'])) {
$geniuser = GeniUser::Lookup("sa", $_COOKIE['quickvm_user']);
......@@ -315,27 +316,44 @@ $args["username"] = $username;
$args["email"] = $email;
$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
# 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($verify) && $verify == $stuffing)) {
SPITFORM($username, $email, $sshkey, $imageid, $stuffing, $errors);
SPITFOOTER();
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.
$args["auth_token"] = $stuffing;
}
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();
return;
}
......
......@@ -25,7 +25,7 @@ chdir("..");
include("defs.php3");
include_once("osinfo_defs.php");
include_once("geni_defs.php");
chdir("aptui");
chdir("apt");
include("quickvm_sup.php");
$ajax_request = 0;
......@@ -39,7 +39,7 @@ $reqargs = OptionalPageArguments("uuid", PAGEARG_STRING,
"ajax_argument", PAGEARG_STRING);
if (!isset($uuid)) {
if ($ajax_request) {
SPITAJAX_ERROR("must provide uuid");
SPITAJAX_ERROR(1, "must provide uuid");
exit();
}
SPITHEADER(1);
......@@ -59,7 +59,7 @@ if (!isset($uuid)) {
$quickvm = QuickVM::Lookup($uuid);
if (!$quickvm) {
if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid");
SPITAJAX_ERROR(1, "no such quickvm uuid");
exit();
}
SPITHEADER(1);
......@@ -78,7 +78,7 @@ if (!$quickvm) {
$creator = GeniUser::Lookup("sa", $quickvm->creator_uuid());
if (!$creator) {
if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid");
SPITAJAX_ERROR(1, "no such quickvm uuid");
exit();
}
SPITHEADER(1);
......@@ -95,7 +95,7 @@ if (!$creator) {
$slice = GeniSlice::Lookup("sa", $quickvm->slice_uuid());
if (!$slice) {
if ($ajax_request) {
SPITAJAX_ERROR("no such quickvm uuid");
SPITAJAX_ERROR(1, "no slice for quickvm ");
exit();
}
SPITHEADER(1);
......@@ -138,12 +138,39 @@ if (isset($ajax_request)) {
SPITAJAX_RESPONSE(GateOneAuthObject($creator->uid()));
}
elseif ($ajax_method == "request_extension") {
TBMAIL($TBMAIL_OPS, "Request Extension", $ajax_argument);
SPITAJAX_RESPONSE("");
# Only extend for 24 hours. More later.
$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") {
TBMAIL($TBMAIL_OPS, "Extend", $ajax_argument);
SPITAJAX_RESPONSE("");
SPITAJAX_ERROR(1, "Not implemented yet!");
}
exit();
}
......@@ -159,6 +186,7 @@ $creator_email = $creator->email();
$quickvm_profile = $quickvm->profile();
$slice_url = "";
$color = "";
$disabled = "disabled";
$spin = 1;
if ($quickvm_status == "failed") {
$color = "color=red";
......@@ -167,6 +195,7 @@ if ($quickvm_status == "failed") {
elseif ($quickvm_status == "ready") {
$color = "color=green";
$spin = 0;
$disabled = "";
}
elseif ($quickvm_status == "created") {
$spinwidth = "33";
......@@ -209,7 +238,8 @@ echo "<td class='uk-width-4-5' $style>$quickvm_profile</td>\n";
echo "</tr>\n";
echo "<tr>\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";
echo "</tr>\n";
echo "</table>\n";
......@@ -218,11 +248,11 @@ echo " <button class='uk-button uk-button-primary'
id='register_button' type=button
onclick=\"ShowModal('#register_modal'); return false;\">
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
onclick=\"ShowModal('#extend_modal'); return false;\">
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
onclick=\"ShowModal('#terminate_modal'); return false;\">
Terminate</button>\n";
......@@ -259,18 +289,18 @@ echo "<!-- This is a modal -->
#
echo "<!-- This is a 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>
<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
not self-terminate at the time shown, you can request an
extension code from us. Just tell us why. A reply will
arrive via email as soon as possible.
not self-terminate at the time shown, just tell us why
and we will extend it for another 24 hours.
Watch for an email message that says its been done.
<form id='extend_request_form'>
<div class='uk-form-controls'>
<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'
rows=5></textarea>
<br>
......@@ -281,15 +311,17 @@ echo "<!-- This is a modal -->
</div>
</form>
</div>
<div class='uk-width-1-3'>
<form id='extend_form'>
<center>Got your code?</center><br>
<div class='uk-width-1-2'>
To extend your experiment for more then another 24 hours,
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'>
<input id='extend_code' name='extend_code'
class='uk-form-width-small uk-align-center'
placeholder='Extension code' autofocus type='text' />
<br>
<button class='uk-button uk-button-primary uk-button-small
<br>
<button class='uk-button uk-button-primary uk-button-small
uk-align-center'
onclick=\"Extend('$uuid'); return false;\"
type='submit' name='extend'>Extend</button>
......
......@@ -8,7 +8,7 @@ function ShowModal(which)
function HideModal(which)
{
$( which ).hide();
console.log('Showing modal ' + which);
console.log('Hide modal ' + which);
}
function CallMethod(method, callback, uuid, arg)
......@@ -26,7 +26,7 @@ function CallMethod(method, callback, uuid, arg)
},
// whether this is a POST or GET request
type: "GET",
type: (arg ? "POST" : "GET"),
// the type of data we expect back
dataType : "json",
......@@ -36,7 +36,7 @@ function CallMethod(method, callback, uuid, arg)
function GetStatus(uuid)
{
var callback = function(json) {
StatusWatchCallBack(uuid, json.value);
StatusWatchCallBack(uuid, json);
}
var $xmlthing = CallMethod("status", null, uuid, null);
$xmlthing.done(callback);
......@@ -49,13 +49,17 @@ function StartStatusWatch(uuid)
}
// Call back for above.
function StatusWatchCallBack(uuid, status)
function StatusWatchCallBack(uuid, json)
{
// Check to see if the static variable has been initialized
if (typeof StatusWatchCallBack.laststatus == 'undefined') {
// It has not... perform the initilization
StatusWatchCallBack.laststatus = "";
}
var status = json.value;
if (json.code) {
status = "terminated";
}
console.log(status);
if (status != StatusWatchCallBack.laststatus) {
......@@ -72,6 +76,8 @@ function StatusWatchCallBack(uuid, status)
$("#quickvm_progress").addClass("uk-progress-success");
$("#quickvm_progress_bar").width("100%");
}
$("#terminate_button").prop("disabled", false);
$("#extend_button").prop("disabled", false);
ShowTopo(uuid);
}
else if (status == 'failed') {
......@@ -83,15 +89,16 @@ function StatusWatchCallBack(uuid, status)
$("#quickvm_progress_bar").width("100%");
}
}
else if (status == 'terminating') {
status_html = "<font color=red>failed</font>";
else if (status == 'terminating' || status == 'terminated') {
status_html = "<font color=red>" + status + "</font>";
$("#terminate_button").prop("disabled", true);
$("#extend_button").prop("disabled", true);
StartCountdownClock.stop = 0;
}
$("#quickvm_status").html(status_html);
}
StatusWatchCallBack.laststatus = status;
if (status != "terminating") {
if (! (status == 'terminating' || status == 'terminated')) {
setTimeout(function f() { GetStatus(uuid) }, 5000);
}
}
......@@ -103,6 +110,7 @@ function Terminate(uuid, url)
}
$("#terminate_button").prop("disabled", true);
$("#extend_button").prop("disabled", true);
$('#terminate_modal').hide();
var $xmlthing = CallMethod("terminate", null, uuid, null);
$xmlthing.done(callback);
......@@ -150,11 +158,26 @@ function RequestExtension(uuid)
{
var reason = $("#why_extend").val();
console.log(reason);
if (reason == "") {
if (reason.length < 30) {
alert("Your reason is too short! Say more please.");
return;
}
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);
$('#extend_modal').hide();
......@@ -169,7 +192,7 @@ function Extend(uuid)
return;
}
var callback = function(json) {
alert("Your request has been sent");
console.log(json.value);
}
var $xmlthing = CallMethod("extend", null, uuid, code);
$('#extend_modal').hide();
......@@ -232,21 +255,39 @@ function StartGateOne(sshurl)
//
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
var target_date = new Date(when).getTime();
// variables for time units
var days, hours, minutes, seconds;
// 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
var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000;
if (seconds_left <= 0) {
$("#terminate_button").prop("disabled", true);
$("#extend_button").prop("disabled", true);
// Amazing that this works!
clearInterval(updater);
return;
}
......
......@@ -27,7 +27,7 @@ function SPITHEADER($thinheader = 0)
echo "<html>
<head>
<title>AptLab.io - SSH</title>
<title>AptLab</title>
<!-- UIKit -->
<link rel='stylesheet' href='uikit/css/uikit.almost-flat.css'>
<link rel='stylesheet' href='quickvm.css'>
......@@ -73,17 +73,15 @@ function SPITAJAX_RESPONSE($value)
'value' => $value
);
echo json_encode($results);
exit();
}
function SPITAJAX_ERROR($msg)
function SPITAJAX_ERROR($code, $msg)
{
$results = array(
'code' => 1,
'code' => code,
'value' => $msg
);
echo json_encode($results);
exit();
}
function GateOneAuthObject($uid)
......
......@@ -534,6 +534,7 @@ class QuickVM
function status() { return $this->field('status'); }
function profile() { return $this->field('profile'); }
function manifest() { return $this->field('manifest'); }
function extension_code() { return $this->field('extension_code'); }
function LookupByName($token) {
$dblink = GetDBLink("sa");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment