Commit 5fedee7f authored by Leigh Stoller's avatar Leigh Stoller

Store details of all extension requests in an ongoing text field in

the apt_instance table record, and display that in on the admin extension
page so that we have it all in one place instead of email messages.
Also show the cluster usage graph in on the admin extend modal.
parent 503f3fd1
......@@ -38,6 +38,18 @@ $urn_mapping =
"urn:publicid:IDN+emulab.net+authority+cm" => "MS",
"urn:publicid:IDN+utahddc.geniracks.net+authority+cm" => "DDC");
$freenodes_mapping =
array("urn:publicid:IDN+utah.cloudlab.us+authority+cm" =>
"https://www.utah.cloudlab.us/node_usage/freenodes.svg",
"urn:publicid:IDN+wisc.cloudlab.us+authority+cm" =>
"https://www.wisc.cloudlab.us/node_usage/freenodes.svg",
"urn:publicid:IDN+clemson.cloudlab.us+authority+cm" =>
"https://www.clemson.cloudlab.us/node_usage/freenodes.svg",
"urn:publicid:IDN+apt.emulab.net+authority+cm" =>
"https://www.apt.emulab.net/node_usage/freenodes.svg",
"urn:publicid:IDN+emulab.net+authority+cm" =>
"https://www.emulab.net/node_usage/freenodes.svg");
class Instance
{
var $instance;
......@@ -78,7 +90,10 @@ class Instance
function manifest() { return $this->field('manifest'); }
function admin_lockdown() { return $this->field('admin_lockdown'); }
function user_lockdown(){ return $this->field('user_lockdown'); }
function extension_count() { return $this->field('extension_count'); }
function extension_days() { return $this->field('extension_days'); }
function extension_reason() { return $this->field('extension_reason'); }
function extension_history() { return $this->field('extension_history'); }
function extension_lockout() { return $this->field('extension_adminonly'); }
function servername() { return $this->field('servername'); }
function aggregate_urn(){ return $this->field('aggregate_urn'); }
......@@ -316,6 +331,17 @@ class Instance
"where uuid='$uuid'");
}
function AddExtensionHistory($text)
{
$uuid = $this->uuid();
$safe_text = mysql_escape_string($text);
DBQueryWarn("update apt_instances set ".
"extension_history=CONCAT('$safe_text',".
"IFNULL(extension_history,'')) ".
"where uuid='$uuid'");
}
function BumpExtensionCount($granted)
{
$uuid = $this->uuid();
......
......@@ -261,6 +261,7 @@ define(['underscore', 'js/quickvm_sup',
"we really do read these!");
return;
}
$('#extension_reason').val(reason);
}
sup.HideModal('#extend_modal');
sup.ShowModal("#waitwait-modal");
......@@ -295,7 +296,7 @@ define(['underscore', 'js/quickvm_sup',
$(button).attr("disabled", "disabled");
}
}
return function(thisuuid, func, admin, guest, extendfor)
return function(thisuuid, func, admin, guest, extendfor, url)
{
isadmin = admin;
isguest = guest;
......@@ -317,6 +318,13 @@ define(['underscore', 'js/quickvm_sup',
$("#why_extend").val($('#extension_reason').val());
$("#why_extend_div").removeClass("hidden");
}
if (admin && $('#extension_history').length) {
$("#extend_history").text($('#extension_history').text());
$("#extend_history_div").removeClass("hidden");
}
if (admin && url) {
$("#extend_graphs_img").attr("src", url);
}
$(modalname).off('shown.bs.modal');
});
$(modalname).modal('show');
......
......@@ -151,7 +151,8 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
// Setup the extend modal.
$('button#extend_button').click(function (event) {
event.preventDefault();
ShowExtendModal(uuid, RequestExtensionCallback, isadmin, isguest);
ShowExtendModal(uuid, RequestExtensionCallback, isadmin,
isguest, null, window.APT_OPTIONS.freenodesurl);
});
// Handler for the refresh button
......@@ -299,7 +300,8 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
}
else if (window.APT_OPTIONS.extend) {
ShowExtendModal(uuid, RequestExtensionCallback, isadmin, isguest,
window.APT_OPTIONS.extend);
window.APT_OPTIONS.extend,
window.APT_OPTIONS.freenodesurl);
}
}
......
......@@ -27,6 +27,7 @@ $APTHOST = "$WWWHOST";
$COOKDIEDOMAIN = "$WWWHOST";
$APTBASE = "$TBBASE/apt";
$APTMAIL = $TBMAIL_OPS;
$EXTENSIONS = $TBMAIL_OPS;
$APTTITLE = "APT";
$FAVICON = "aptlab.ico";
$APTLOGO = "aptlogo.png";
......@@ -78,6 +79,7 @@ if ($TBMAINSITE && $_SERVER["SERVER_NAME"] == "www.aptlab.net") {
$APTMAIL = "APT Operations <portal-ops@aptlab.net>";
$GOOGLEUA = 'UA-42844769-3';
$TBMAILTAG = "aptlab.net";
$EXTENSIONS = "portal-extensions@aptlab.net";
# For devel trees
if (preg_match("/\/([\w\/]+)$/", $WWW, $matches)) {
$APTBASE .= "/" . $matches[1];
......@@ -99,6 +101,7 @@ elseif (0 || ($TBMAINSITE && $_SERVER["SERVER_NAME"] == "www.cloudlab.us")) {
$ISCLOUD = 1;
$GOOGLEUA = 'UA-42844769-2';
$TBMAILTAG = "cloudlab.us";
$EXTENSIONS = "portal-extensions@cloudlab.us";
# For devel trees
if (preg_match("/\/([\w\/]+)$/", $WWW, $matches)) {
$APTBASE .= "/" . $matches[1];
......
......@@ -244,7 +244,7 @@ function Do_RequestExtension()
{
global $instance, $creator, $this_user, $suexec_output;
global $ajax_args;
global $TBMAIL_OPS, $APTMAIL, $APTBASE;
global $TBMAIL_OPS, $APTMAIL, $EXTENSIONS, $APTBASE;
$autoextend_maximum = TBGetSiteVar("aptui/autoextend_maximum");
$autoextend_maxage = TBGetSiteVar("aptui/autoextend_maxage");
$reason = "";
......@@ -294,6 +294,11 @@ function Do_RequestExtension()
}
$reason = $ajax_args["reason"];
if (!TBvalid_fulltext($reason)) {
SPITAJAX_ERROR(1, "Illegal characters in reason");
goto bad;
}
#
# Guest users are treated differently.
#
......@@ -385,18 +390,33 @@ function Do_RequestExtension()
}
if ($retval == 0) {
if ($needapproval) {
needAdminApproval($wanted, $granted, $reason, $message);
if (!$granted)
goto delay;
return;
}
# Refresh.
$slice = GeniSlice::Lookup("sa", $instance->slice_uuid());
$new_expires = date("Y-m-d H:i:s T", strtotime($slice->expires()));
$created = date("Y-m-d H:i:s T", strtotime($instance->created()));
$before = date("Y-m-d H:i:s T", strtotime($expires_time));
$now = date("Y-m-d H:i:s T", strtotime(time()));
list($cluster) = Instance::ParseURN($instance->aggregate_urn());
#
# We store each extension request in an ongoing text field.
#
$text =
"Date: $now\n".
"Wanted: $wanted, Granted: $granted\n".
"Before: $before\n".
"After $new_expires\n".
"Reason:\n".
$reason . "\n\n".
"-----------------------------------------------\n";
$instance->AddExtensionHistory($text);
if ($needapproval) {
needAdminApproval($wanted, $granted, $reason, $message);
if (!$granted)
goto delay;
return;
}
SPITAJAX_RESPONSE($new_expires);
$instance->SendEmail($creator->email(),
......@@ -408,8 +428,8 @@ function Do_RequestExtension()
"Your experiment will now expire at $new_expires\n".
"It is running on $cluster\n\n\n".
"$APTBASE/status.php?uuid=$uuid\n",
"From: $APTMAIL\n" .
"BCC: $TBMAIL_OPS");
"From: $EXTENSIONS\n" .
"BCC: $EXTENSIONS");
#
# We do not want to overwrite the reason in the DB if this
# was an admin extension, we want to keep whatever the user
......@@ -440,7 +460,7 @@ delay:
function needAdminApproval($wanted, $granted, $reason, $message)
{
global $instance, $creator, $this_user, $suexec_output;
global $TBMAIL_OPS, $APTMAIL, $APTBASE;
global $EXTENSIONS, $APTBASE;
$uuid = $instance->uuid();
# Subtract out the extra time we added above.
......@@ -454,7 +474,7 @@ function needAdminApproval($wanted, $granted, $reason, $message)
$created = date("Y-m-d H:i:s T", strtotime($instance->created()));
list($cluster) = Instance::ParseURN($instance->aggregate_urn());
$instance->SendEmail($APTMAIL,
$instance->SendEmail($EXTENSIONS,
"Experiment Extension Request: $uuid",
"A request to extend this experiment was made but requires\n".
"administrator approval" .
......
......@@ -155,6 +155,9 @@ $lockdown = ($instance->admin_lockdown() ||
$instance->user_lockdown() ? 1 : 0);
$extension_reason= ($instance->extension_reason() ?
CleanString($instance->extension_reason()) : "");
$extension_history= ($instance->extension_history() ?
CleanString($instance->extension_history()) : "");
$freenodes_url = $freenodes_mapping[$instance->aggregate_urn()];
$lockout = $instance->extension_lockout();
#
......@@ -210,6 +213,7 @@ echo " window.APT_OPTIONS.publicURL = $public_url;\n";
echo " window.APT_OPTIONS.lockdown = $lockdown;\n";
echo " window.APT_OPTIONS.lockout = $lockout;\n";
echo " window.APT_OPTIONS.AJAXURL = 'server-ajax.php';\n";
echo " window.APT_OPTIONS.freenodesurl = '$freenodes_url';\n";
if (isset($extend) && $extend != "") {
echo " window.APT_OPTIONS.extend = $extend;\n";
}
......@@ -226,6 +230,7 @@ echo "<link rel='stylesheet'
echo "<link rel='stylesheet' href='css/progress.css'>\n";
echo "<link rel='stylesheet' href='css/codemirror.css'>\n";
echo "<div class='hidden'><textarea id='extension_reason'>$extension_reason</textarea></div>\n";
echo "<pre class='hidden' id='extension_history'>$extension_history</pre>\n";
SPITFOOTER();
?>
......@@ -25,6 +25,26 @@
class='form-control align-center-inline'
rows=5></textarea>
</center>
</div>
<div id='cluster_graphs'>
<h5>
<a data-toggle="collapse"
href="#graphs">Cluster Graph</a>
</h5>
<div id="graphs" class="collapse">
<img id='extend_graphs_img' width=350 class='center-block'>
</div>
</div>
<div id='extend_history_div' class='hidden'>
<h5>
<a data-toggle="collapse"
href="#history">Extension History</a>
</h5>
<div id="history" class="panel-collapse collapse">
<div class="well">
<pre id="extend_history"></pre>
</div>
</div>
<br>
</div>
<button class='btn btn-primary btn-sm align-center'
......
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