Commit 0cdc4807 authored by Leigh Stoller's avatar Leigh Stoller

UI changes to quarantine mode:

* Remove quarantine set/clear from admin extend page, this is a bad
  place for this since you do not get to see the experiment react to
  it. And it duplicates what is on the status page,

* quarantine runs in the background, display info reminding admin about
  that. The experiment state will change to "quarantined" once it
  completes. For users, add a help button explaining what quarantined
  means to them.

* Switch the Warn/Kill button to "Release" when an experiment is in
  quarantine mode.
parent be466a09
......@@ -521,7 +521,7 @@ $(function ()
//
function DoQuarantine(mode)
{
mode = (mode ? 1 : 0);
mode = (mode ? "set" : "clear");
var callback = function(json) {
if (json.code) {
......
......@@ -270,7 +270,7 @@ $(function ()
xmlthing.done(callback);
});
SetupWarnKill();
// Handler for select/deselect all rows in the list view.
$('#select-all').change(function () {
if ($(this).prop("checked")) {
......@@ -595,6 +595,18 @@ $(function ()
if (!status_collapsed) {
$("#status_message").html(status_message);
}
if (instanceStatus == "quarantined") {
$('#explain-quarantine').removeClass("hidden");
$('#warnkill-experiment-button').addClass("hidden");
$('#release-quarantine-button').removeClass("hidden");
$('#quarantine_checkbox').prop("checked", true);
}
else {
$('#explain-quarantine').addClass("hidden");
$('#release-quarantine-button').addClass("hidden");
$('#warnkill-experiment-button').removeClass("hidden");
$('#quarantine_checkbox').prop("checked", false);
}
$("#status_panel")
.removeClass('panel-success panel-danger ' +
'panel-warning panel-default panel-info')
......@@ -654,6 +666,7 @@ $(function ()
var extend;
var snapshot;
var destroy;
var release = 0;
switch (status)
{
......@@ -679,6 +692,12 @@ $(function ()
destroy = 1;
break;
case 'quarantined':
terminate = refresh = reloadtopo = extend = snapshot = 0;
destroy = 0;
release = 1;
break;
case 'failed':
case 'imaging-failed':
refresh = reloadtopo = terminate = destroy = 1;
......@@ -690,18 +709,13 @@ $(function ()
if (expinfo.admin_lockdown || !window.APT_OPTIONS.canterminate) {
terminate = 0;
}
// Or if paniced, most buttons disabled.
if (expinfo.paniced) {
terminate = extend = snapshot = destroy = 0;
refresh = reloadtopo = 0;
}
ButtonState('terminate', terminate);
ButtonState('refresh', refresh);
ButtonState('reloadtopo', reloadtopo);
ButtonState('extend', extend);
ButtonState('snapshot', snapshot);
ButtonState('destroy', destroy);
ButtonState('release', release);
ToggleLinktestButtons(status);
}
function EnableButton(button)
......@@ -723,6 +737,8 @@ $(function ()
}
else if (button == "destroy")
button = "#warnkill-experiment-button";
else if (button == "release")
button = "#release-quarantine-button";
else if (button == "extend")
button = "#extend_button";
else if (button == "refresh")
......@@ -3666,10 +3682,24 @@ $(function ()
*/
function SetupWarnKill()
{
if (expinfo.paniced) {
$('#warnkill-experiment-button').addClass("hidden");
$('#release-quarantine-button').removeClass("hidden");
}
else {
$('#warnkill-experiment-button').removeClass("hidden");
$('#release-quarantine-button').addClass("hidden");
}
$('#warnkill-experiment-button').click(function (event) {
event.preventDefault();
WarnExperiment();
});
$('#release-quarantine-button').click(function () {
sup.ShowModal('#disable-quarantine-modal');
});
$('#confirm-disable-quarantine').click(function () {
DisableQuarantine();
});
// The Terminate/quarantine is a radio that can be unselected.
$('#destroy-quarantine-checkbox').change(function () {
......@@ -3714,19 +3744,26 @@ $(function ()
}
}
sup.HideModal("#destroy-experiment-modal", function () {
sup.ShowWaitWait();
sup.ShowWaitWait("Patience please!");
sup.CallServerMethod(null, "status", "Warn", args,
function(json) {
console.info("warn/kill", json);
if (json.code) {
sup.HideWaitWait(function () {
sup.SpitOops("oops",
"Could not warn/kill experiment: " +
json.value);
if (json.code) {
sup.SpitOops("oops",
"Could not warn/kill experiment: " +
json.value);
}
});
return;
}
sup.HideWaitWait();
sup.HideWaitWait(function () {
if (panic) {
sup.ShowModal(
'#quarantine-inprogress-modal');
}
});
});
});
});
......@@ -3739,6 +3776,36 @@ $(function ()
sup.ShowModal("#destroy-experiment-modal");
}
/*
* Release from quarantine.
*/
function DisableQuarantine()
{
var args = {"uuid" : uuid,
"quarantine" : "clear"};
sup.HideModal('#disable-quarantine-modal', function () {
sup.ShowWaitWait("Patience please!");
sup.CallServerMethod(null, "status", "Quarantine", args,
function(json) {
console.info("DisableQuarantine", json);
if (json.code) {
sup.HideWaitWait(function () {
if (json.code) {
sup.SpitOops("oops",
"Could not disable quarantine: " +
json.value);
}
});
return;
}
sup.HideWaitWait(function () {
sup.ShowModal('#quarantine-inprogress-modal');
});
});
});
}
// Helper.
function decodejson(id) {
return JSON.parse(_.unescape($(id)[0].textContent));
......
......@@ -1425,7 +1425,11 @@ function Do_Quarantine()
SPITAJAX_ERROR(1, "Missing quarantine value");
return;
}
$which = ($ajax_args["quarantine"] ? "set" : "clear");
$which = $ajax_args["quarantine"];
if ($which != "set" && $which != "clear") {
SPITAJAX_ERROR(1, "Invalid quarantine value");
return;
}
$uuid = $ajax_args["uuid"];
$opt = "";
if (isset($ajax_args["poweroff"]) && $ajax_args["poweroff"]) {
......@@ -1449,7 +1453,7 @@ function Do_Quarantine()
SPITAJAX_ERROR(-1, "Internal error changing quarantine");
}
else {
SPITAJAX_ERROR(1, $webtask->output());
SPITAJAX_ERROR(-1, $webtask->output());
}
$webtask->Delete();
return;
......
......@@ -120,13 +120,15 @@
<tr>
<td>
<span data-toggle='popover'
data-delay='{"hide":500, "show":500}'
data-content="When checked, the experiment is put into
Quarantine (emulab panic) mode.">
data-delay='{"show":500}'
data-content="When checked, the experiment is in
Quarantine (emulab panic) mode. Switch
to the show experiment page
to toggle on/off.">
Quarantine:</span>
</td>
<td>
<input type="checkbox" id="quarantine-checkbox"
<input type="checkbox" id="quarantine-checkbox" disabled
<% if (expinfo.paniced) { %>checked<% } %> >
</td>
</tr>
......
......@@ -44,5 +44,15 @@
</div>
</div>
</div>
<div id='quarantine-inprogress-modal' class='modal fade'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class="modal-body">
<button type='button' class='close' data-dismiss='modal'
aria-hidden='true'>&times;</button>
Changing quarantine mode takes a few minutes, the experiment state
will be updated when complete.
</div>
</div>
</div>
</div>
......@@ -76,9 +76,14 @@ pre {
</span>
<span class="hidden" id="ignore-failure"
style='margin-left: 10px;'>
(<a id='ignore-failure-button'
(<a id='ignore-failure-button' href="#"
data-target='#ignore-failure-modal'
data-toggle='modal'>Ignore this failure?</a>)</span>
data-toggle='modal'>Ignore this failure</a>?)</span>
<span class="hidden" id="explain-quarantine"
style='margin-left: 10px;'>
(<a id='explain-quarantine-button' href="#"
data-target='#explain-quarantine-modal'
data-toggle='modal'>What does this mean</a>?)</span>
</td>
</tr>
<% if (expinfo.profile_uuid) { %>
......@@ -199,14 +204,23 @@ pre {
</div>
<% if (isadmin) { %>
<div class='pull-left'>
<button class='btn btn-xs btn-danger' disabled
<button class='btn btn-xs btn-danger' disabled hidden
style='margin-left: 10px;'
style='margin-right: 10px;'
id='warnkill-experiment-button' type=button
data-delay='{"show":750}'
data-toggle='popover'
data-content='Warn user or terminate experiment with cause
data-content='Warn user or terminate/quarantine
experiment with cause
and optionally freeze the user account.'>
Warn/Kill</button>
<button class='btn btn-xs btn-danger' disabled hidden
style='margin-left: 10px;'
style='margin-right: 10px;'
id='release-quarantine-button' type=button
data-toggle='popover'
data-content='Release experiment from quarantine.'>
Release</button>
</div>
<% } %>
<div class='pull-right'>
......@@ -214,6 +228,7 @@ pre {
class='btn btn-xs btn-info hidden'
style='margin-right: 10px;'
id='confirm-stuff-button' type=button
data-delay='{"show":250}'
data-toggle='popover'
data-content='Explore performance results from a set of
low-level benchmarks characterizing the
......@@ -224,6 +239,7 @@ pre {
<button class='btn btn-xs btn-success hidden' disabled
style='margin-right: 10px;'
id='linktest-stop-button' type=button
data-delay='{"show":750}'
data-toggle='popover'
data-content='Stop a running or wedged linktest'>
Stop Linktest</button>
......@@ -231,7 +247,7 @@ pre {
<button class='btn btn-xs btn-primary hidden' disabled
id='snapshot_button' type=button
data-toggle='popover'
data-delay='{"hide":1000, "show":500}'
data-delay='{"show":750}'
data-html='true'
data-content="Create a disk image from one of your nodes.
Click for more info.">
......@@ -241,7 +257,7 @@ pre {
href='manage_profile.php?action=copy&uuid=<%= expinfo.profile_uuid %>'
id='copy_button' type=button
data-toggle='popover'
data-delay='{"hide":1000, "show":500}'
data-delay='{"show":750}'
data-html='true'
data-content="When you <em>copy</em> a profile,
you are creating a new profile that
......@@ -268,8 +284,8 @@ pre {
<div <% if (expinfo.status == "deferred") { %>
class="exp-running hidden" <% } %>>
<div class='pull-left'
data-delay='{"show":750}'
data-toggle='popover'
data-delay='{"hide":100, "show":500}'
data-content="When checked, only administrators can extend
this experiment. No free time is granted to
user at all.">
......@@ -281,8 +297,8 @@ pre {
<div <% if (expinfo.status == "deferred") { %>
class="exp-running hidden" <% } %>>
<div class='pull-left'
data-delay='{"show":750}'
data-toggle='popover'
data-delay='{"hide":100, "show":500}'
data-content="When checked, the experiment
cannot be terminated by the user unless the
user verifies
......@@ -301,8 +317,8 @@ pre {
<div <% if (expinfo.status == "deferred") { %>
class="exp-running hidden" <% } %>>
<div class='pull-left'
data-delay='{"show":750}'
data-toggle='popover'
data-delay='{"hide":100, "show":500}'
data-content="When checked, the experiment
cannot be terminated by the user. Only an
admin can do it.">
......@@ -312,12 +328,28 @@ pre {
Admin Lockdown</label>
</div>
</div>
<% if (0) { %>
<div <% if (expinfo.status == "deferred") { %>
class="exp-running hidden" <% } %>>
<div class='pull-left'
data-delay='{"show":750}'
data-toggle='popover'
data-content="When checked, the experiment is in
Quarantine (emulab panic) mode.">
<label class="checkbox-inline" style='margin-right: 10px;'>
<input type="checkbox" id="quarantine_checkbox" disabled
<% if (expinfo.paniced) { %>checked<% } %>
<span <% if (expinfo.paniced) { %>class="text-danger"<% } %> >
Quarantined</span></label>
</div>
</div>
<% } %>
<div <% if (expinfo.status == "deferred") { %>
class="exp-running hidden" <% } %>>
<div class='pull-left'>
<span <% if (expinfo.admin_notes == "") { %>hidden<% } %>'
data-delay='{"show":750}'
data-toggle='popover'
data-delay='{"hide":500, "show":500}'
data-content="This experiment has admin notes">
<a target="_blank"
href='adminextend.php?uuid=<%= uuid %>'>Admin Notes</a>
......@@ -1454,6 +1486,46 @@ class='fixedsize-panel with-3d-shadow with-transitions'>
</div>
</div>
</div>
<!-- Explain quarantine mode -->
<div id='explain-quarantine-modal' class='modal fade'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-body'>
<button type='button' class="close"
data-dismiss='modal' aria-hidden='true'>&times;</button>
<p>
Your experiment has been quarantined by an administrator.
Typically, this action would be taken because your experiment was
doing something that is prohibited. Your nodes have either
been powered off, or they were rebooted into a safe mode so
that you can log in and investigate. For more info, please contact
<%= window.APTMAILTO %>.
</p>
</div>
</div>
</div>
</div>
<!-- Confirm disable Quarantine -->
<div id='disable-quarantine-modal' class='modal fade'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-body'>
<button type='button' class='close' data-dismiss='modal'
aria-hidden='true'>&times;</button>
<center>
<h3>Confirm to release from Quarantine</h3>
<div style="margin-top: 10px;">
<button style='margin-right: 10px;'
class='btn btn-primary btn-sm'
data-dismiss='modal' aria-hidden='true'>Cancel</button>
<button class='btn btn-danger btn-sm'
id='confirm-disable-quarantine'>Confirm</button>
</div>
</center>
</div>
</div>
</div>
</div>
<!-- Ignore failures modal-->
<div id='ignore-failure-modal' class='modal fade'>
<div class='modal-dialog'>
......@@ -1512,3 +1584,6 @@ class='fixedsize-panel with-3d-shadow with-transitions'>
<div id='destroy_div'></div>
</div>
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