Commit 2d509734 authored by Joshua Tauberer's avatar Joshua Tauberer

move the package update check into the system status checks

parent 294d19e0
...@@ -210,14 +210,11 @@ def system_status(): ...@@ -210,14 +210,11 @@ def system_status():
@app.route('/system/updates') @app.route('/system/updates')
@authorized_personnel_only @authorized_personnel_only
def show_updates(): def show_updates():
utils.shell("check_call", ["/usr/bin/apt-get", "-qq", "update"]) from status_checks import list_apt_updates
simulated_install = utils.shell("check_output", ["/usr/bin/apt-get", "-qq", "-s", "upgrade"]) return "".join(
pkgs = [] "%s (%s)\n"
for line in simulated_install.split('\n'): % (p["package"], p["version"])
if re.match(r'^Conf .*', line): continue # remove these lines, not informative for p in list_apt_updates())
line = re.sub(r'^Inst (.*) \[(.*)\] \((\S*).*', r'Updated Package Available: \1 (\3)', line) # make these lines prettier
pkgs.append(line)
return "\n".join(pkgs)
@app.route('/system/update-packages', methods=["POST"]) @app.route('/system/update-packages', methods=["POST"])
@authorized_personnel_only @authorized_personnel_only
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
__ALL__ = ['check_certificate'] __ALL__ = ['check_certificate']
import os, os.path, re, subprocess import os, os.path, re, subprocess, datetime
import dns.reversename, dns.resolver import dns.reversename, dns.resolver
...@@ -36,6 +36,17 @@ def run_system_checks(env): ...@@ -36,6 +36,17 @@ def run_system_checks(env):
else: else:
env['out'].print_ok("SSH disallows password-based login.") env['out'].print_ok("SSH disallows password-based login.")
# Check for any software package updates.
pkgs = list_apt_updates()
if os.path.exists("/var/run/reboot-required"):
env['out'].print_error("System updates have been installed and a reboot of the machine is required.")
elif len(pkgs) == 0:
env['out'].print_ok("System software is up to date.")
else:
env['out'].print_error("There are %d software packages that can be updated." % len(pkgs))
for p in pkgs:
env['out'].print_line("%s (%s)" % (p["package"], p["version"]))
# Check that the administrator alias exists since that's where all # Check that the administrator alias exists since that's where all
# admin email is automatically directed. # admin email is automatically directed.
check_alias_exists("administrator@" + env['PRIMARY_HOSTNAME'], env) check_alias_exists("administrator@" + env['PRIMARY_HOSTNAME'], env)
...@@ -433,6 +444,39 @@ def check_certificate(domain, ssl_certificate, ssl_private_key): ...@@ -433,6 +444,39 @@ def check_certificate(domain, ssl_certificate, ssl_private_key):
else: else:
return verifyoutput.strip() return verifyoutput.strip()
_apt_updates = None
def list_apt_updates():
# See if we have this information cached recently.
# Keep the information for 8 hours.
global _apt_updates
if _apt_updates is not None and _apt_updates[0] > datetime.datetime.now() - datetime.timedelta(hours=8):
return _apt_updates[1]
# Run apt-get update to refresh package list.
shell("check_call", ["/usr/bin/apt-get", "-qq", "update"])
# Run apt-get upgrade in simulate mode to get a list of what
# it would do.
simulated_install = shell("check_output", ["/usr/bin/apt-get", "-qq", "-s", "upgrade"])
pkgs = []
for line in simulated_install.split('\n'):
if line.strip() == "":
continue
if re.match(r'^Conf .*', line):
# remove these lines, not informative
continue
m = re.match(r'^Inst (.*) \[(.*)\] \((\S*)', line)
if m:
pkgs.append({ "package": m.group(1), "version": m.group(3), "current_version": m.group(2) })
else:
pkgs.append({ "package": "[" + line + "]", "version": "", "current_version": "" })
# Cache for future requests.
_apt_updates = (datetime.datetime.now(), pkgs)
return pkgs
try: try:
terminal_columns = int(shell('check_output', ['stty', 'size']).split()[1]) terminal_columns = int(shell('check_output', ['stty', 'size']).split()[1])
except: except:
......
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