Commit 67555679 authored by Joshua Tauberer's avatar Joshua Tauberer

move the reboot button, fix grammar, refactor check for DRY, add changelog entry

parent b71ad85e
CHANGELOG CHANGELOG
========= =========
* When a reboot is required (due to Ubuntu security updates automatically installed), a Reboot Box button now appears.
v0.17 (February 25, 2016) v0.17 (February 25, 2016)
------------------------- -------------------------
......
...@@ -456,10 +456,12 @@ def do_updates(): ...@@ -456,10 +456,12 @@ def do_updates():
"DEBIAN_FRONTEND": "noninteractive" "DEBIAN_FRONTEND": "noninteractive"
}) })
@app.route('/system/reboot', methods=["GET"]) @app.route('/system/reboot', methods=["GET"])
@authorized_personnel_only @authorized_personnel_only
def needs_reboot(): def needs_reboot():
if os.path.isfile("/var/run/reboot-required"): from status_checks import is_reboot_needed_due_to_package_installation
if is_reboot_needed_due_to_package_installation():
return json_response(True) return json_response(True)
else: else:
return json_response(False) return json_response(False)
...@@ -467,10 +469,12 @@ def needs_reboot(): ...@@ -467,10 +469,12 @@ def needs_reboot():
@app.route('/system/reboot', methods=["POST"]) @app.route('/system/reboot', methods=["POST"])
@authorized_personnel_only @authorized_personnel_only
def do_reboot(): def do_reboot():
if os.path.isfile("/var/run/reboot-required"): # To keep the attack surface low, we don't allow a remote reboot if one isn't necessary.
from status_checks import is_reboot_needed_due_to_package_installation
if is_reboot_needed_due_to_package_installation():
return utils.shell("check_output", ["/sbin/shutdown", "-r", "now"], capture_stderr=True) return utils.shell("check_output", ["/sbin/shutdown", "-r", "now"], capture_stderr=True)
else: else:
return "No reboot is required" return "No reboot is required, so it is not allowed."
@app.route('/system/backup/status') @app.route('/system/backup/status')
......
...@@ -185,10 +185,13 @@ def check_ssh_password(env, output): ...@@ -185,10 +185,13 @@ def check_ssh_password(env, output):
else: else:
output.print_ok("SSH disallows password-based login.") output.print_ok("SSH disallows password-based login.")
def is_reboot_needed_due_to_package_installation():
return os.path.exists("/var/run/reboot-required")
def check_software_updates(env, output): def check_software_updates(env, output):
# Check for any software package updates. # Check for any software package updates.
pkgs = list_apt_updates(apt_update=False) pkgs = list_apt_updates(apt_update=False)
if os.path.exists("/var/run/reboot-required"): if is_reboot_needed_due_to_package_installation():
output.print_error("System updates have been installed and a reboot of the machine is required.") output.print_error("System updates have been installed and a reboot of the machine is required.")
elif len(pkgs) == 0: elif len(pkgs) == 0:
output.print_ok("System software is up to date.") output.print_ok("System software is up to date.")
......
<h2>System Status Checks</h2> <h2>System Status Checks</h2>
<div id="system-reboot-required" style="display: none">
<button type="button" class="btn btn-danger" onclick="confirm_reboot(); return false;">Reboot required</button>
</div>
<style> <style>
#system-checks .heading td { #system-checks .heading td {
font-weight: bold; font-weight: bold;
...@@ -38,22 +34,24 @@ ...@@ -38,22 +34,24 @@
font-family: monospace; font-family: monospace;
white-space: pre-wrap; white-space: pre-wrap;
} }
#system-reboot-required {
max-width: 20em;
margin-bottom: 1em;
}
#system-privacy-setting {
float: right;
max-width: 20em;
margin-bottom: 1em;
}
</style> </style>
<div class="row">
<div class="col-md-push-9 col-md-3">
<div id="system-reboot-required" style="display: none; margin-bottom: 1em;">
<button type="button" class="btn btn-danger" onclick="confirm_reboot(); return false;">Reboot Box</button>
<div>No reboot is necessary.</div>
</div>
<div id="system-privacy-setting" style="display: none"> <div id="system-privacy-setting" style="display: none">
<div><a onclick="return enable_privacy(!current_privacy_setting)" href="#"><span>Enable/Disable</span> New-Version Check</a></div> <div><a onclick="return enable_privacy(!current_privacy_setting)" href="#"><span>Enable/Disable</span> New-Version Check</a></div>
<p style="line-height: 125%"><small>(When enabled, status checks phone-home to check for a new release of Mail-in-a-Box.)</small></p> <p style="line-height: 125%"><small>(When enabled, status checks phone-home to check for a new release of Mail-in-a-Box.)</small></p>
</div> </div>
</div> <!-- /col -->
<div class="col-md-pull-3 col-md-8">
<table id="system-checks" class="table" style="max-width: 60em"> <table id="system-checks" class="table" style="max-width: 60em">
<thead> <thead>
</thead> </thead>
...@@ -61,6 +59,9 @@ ...@@ -61,6 +59,9 @@
</tbody> </tbody>
</table> </table>
</div> <!-- /col -->
</div> <!-- /row -->
<script> <script>
function show_system_status() { function show_system_status() {
$('#system-checks tbody').html("<tr><td colspan='2' class='text-muted'>Loading...</td></tr>") $('#system-checks tbody').html("<tr><td colspan='2' class='text-muted'>Loading...</td></tr>")
...@@ -81,7 +82,9 @@ function show_system_status() { ...@@ -81,7 +82,9 @@ function show_system_status() {
"GET", "GET",
{ }, { },
function(r) { function(r) {
$('#system-reboot-required').toggle(r); $('#system-reboot-required').show(); // show when r becomes available
$('#system-reboot-required').find('button').toggle(r);
$('#system-reboot-required').find('div').toggle(!r);
}); });
api( api(
...@@ -139,16 +142,18 @@ function enable_privacy(status) { ...@@ -139,16 +142,18 @@ function enable_privacy(status) {
function confirm_reboot() { function confirm_reboot() {
show_modal_confirm( show_modal_confirm(
"Reboot server", "Reboot",
$("<p>This will reboot your server, until the server is fully restarted your users will not be able to send and receive email. The reboot can't be cancelled</p>"), $("<p>This will reboot your Mail-in-a-Box <code>{{hostname}}</code>.</p> <p>Until the machine is fully restarted, your users will not be able to send and receive email, and you will not be able to connect to this control panel or with SSH. The reboot cannot be cancelled.</p>"),
"Reboot now", "Reboot Now",
function() { function() {
api( api(
"/system/reboot", "/system/reboot",
"POST", "POST",
{ }, { },
function(r) { function(r) {
show_modal_error("Reboot", "Please refresh the page after a minute or so." + r); var msg = "<p>Please reload this page after a minute or so.</p>";
if (r) msg = "<p>The reboot command said:</p> <pre>" + $("<pre/>").text(r).html() + "</pre>"; // successful reboots don't produce any output; the output must be HTML-escaped
show_modal_error("Reboot", msg);
}); });
}); });
} }
......
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