Commit 86cd8b72 authored by segfault's avatar segfault
Browse files

Fix and improve tails-upgrade-frontend-wrapper

 - Fix xhost access not actually granted
 - Use psutil to check available memory
parent ecd9b7f2
......@@ -19,9 +19,9 @@ import os
import sys
import time
from gettext import gettext
from contextlib import contextmanager
import sh
import psutil
os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
os.environ['TEXTDOMAIN'] = 'tails'
......@@ -30,7 +30,7 @@ CMD = os.path.basename(sys.argv[0])
TORDATE_DIR = '/run/tordate'
TORDATE_DONE_FILE = '{}/done'.format(TORDATE_DIR)
INOTIFY_TIMEOUT = 60
MIN_REAL_MEMFREE = (300 * 1024)
MIN_AVAILABLE_MEMORY = (300 * 1024 * 1024) # In Bytes
RUN_AS_USER = 'tails-upgrade-frontend'
ERROR_MESSAGE = gettext('''\"<b>Not enough memory available to check for upgrades.</b>
......@@ -46,21 +46,22 @@ See https://tails.boum.org/doc/first_steps/upgrade#manual\"''')
def main(*args):
time.sleep(30)
check_free_memory(MIN_REAL_MEMFREE)
check_free_memory(MIN_AVAILABLE_MEMORY)
# Go to a place where everyone, especially Archive::Tar::Wrapper called by
# tails-install-iuk, can chdir back after it has chdir'd elsewhere to do
# its job.
os.chdir('/')
os.execv('/usr/bin/sudo', ('/usr/bin/sudo', '-u', RUN_AS_USER, '/usr/bin/tails-upgrade-frontend', *args))
@contextmanager
def allow_x_connection():
sh.xhost('+SI:localuser:{}'.format(RUN_AS_USER))
yield
sh.xhost('-SI:localuser:{}'.format(RUN_AS_USER))
os.execv(
"/bin/sh",
(
"/bin/sh", "-c",
"xhost +SI:localuser:{user};"
"sudo -u {user} /usr/bin/tails-upgrade-frontend {args};"
"xhost -SI:localuser:{user}".format(user=RUN_AS_USER, args=" ".join(args))
)
)
def error(msg):
......@@ -80,35 +81,17 @@ def error(msg):
sys.exit(1)
def check_free_memory(min_real_memfree):
def check_free_memory(min_available_memory):
"""Check for enough free memory.
>>> check_free_memory(MIN_REAL_MEMFREE)
>>> check_free_memory(MIN_AVAILABLE_MEMORY)
"""
memfree = buffers = cached = None
with open('/proc/meminfo') as f:
for line in f:
if line.startswith('MemFree:'):
fields = line.split()
memfree = int(fields[1])
elif line.startswith('Buffers:'):
fields = line.split()
buffers = int(fields[1])
elif line.startswith('Cached:'):
fields = line.split()
cached = int(fields[1])
if not all((memfree, buffers, cached)):
raise RuntimeError("Parsing /proc/meminfo failed")
df_text = sh.df('--type=tmpfs', '--local', '--output=used', '--total').stdout.decode()
tmpfs = int(df_text.strip().split('\n')[-1])
real_memfree = (memfree + buffers + cached) - tmpfs
if real_memfree < min_real_memfree:
print('Only {} MemFree + Buffers + Cached - usage of tmpfs, while {} is needed'.format(
real_memfree, MIN_REAL_MEMFREE, file=sys.stderr
))
available_memory = psutil.virtual_memory().available
if available_memory < min_available_memory:
print('Only {} Bytes memory available, while {} is needed'.format(
available_memory, min_available_memory), file=sys.stderr)
error(ERROR_MESSAGE)
......
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