tails-upgrade-frontend-wrapper 3.16 KB
Newer Older
1 2 3
#! /usr/bin/env python3
"""
Tails upgrade frontend wrapper.
4

5 6 7 8
Test with "python3 tails-upgrade-frontend-wrapper.py doctest".
The tests will start the upgrade process which could pop up a dialog box
so you probably want to use a tester that handles user interaction or
run the tests from the command line and answer prompts as needed.
9

10
goodcrypto.com converted from bash to python and added basic tests.
11

12 13
>>> # run this script (without waiting 30 seconds)
>>> sh.Command(sys.argv[0])("--no-wait")
14 15
<BLANKLINE>
"""
16

17 18 19 20
import os
import sys
import time
from gettext import gettext
21

22
import sh
23
import psutil
24

25 26
os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
os.environ['TEXTDOMAIN'] = 'tails'
27

28
CMD = os.path.basename(sys.argv[0])
29 30 31 32
# While running iuk.git:features/frontend:
#  - tails-upgrade-frontend never uses more than 100 * 10^6 bytes
#  - tails-iuk-get-upgrade-description never uses more than 95 * 10^6 bytes
MIN_AVAILABLE_MEMORY = (200 * 1024 * 1024)  # In Bytes
33
RUN_AS_USER = 'tails-upgrade-frontend'
34

35
ERROR_MESSAGE = gettext('''\"<b>Not enough memory available to check for upgrades.</b>
36

Tails developers's avatar
Tails developers committed
37
Make sure this system satisfies the requirements for running Tails.
38
See file:///usr/share/doc/tails/website/doc/about/requirements.en.html
Tails developers's avatar
Tails developers committed
39

Tails developers's avatar
Tails developers committed
40
Try to restart Tails to check for upgrades again.
Tails developers's avatar
Tails developers committed
41 42

Or do a manual upgrade.
43 44 45 46
See https://tails.boum.org/doc/first_steps/upgrade#manual\"''')


def main(*args):
47 48 49 50 51
    if "--no-wait" not in args:
        time.sleep(30)
    else:
        args = (arg for arg in args if arg != "--no-wait")

52
    check_free_memory(MIN_AVAILABLE_MEMORY)
53 54 55 56 57 58

    # 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('/')

59 60 61 62 63
    os.execv(
        "/bin/sh",
        (
            "/bin/sh", "-c",
            "xhost +SI:localuser:{user};"
64
            "sudo -u {user} /usr/local/bin/tails-upgrade-frontend {args};"
65 66 67
            "xhost -SI:localuser:{user}".format(user=RUN_AS_USER, args=" ".join(args))
        )
    )
68 69 70


def error(msg):
71
    """Show error and exit."""
72 73 74 75
    cli_text = '{}: {} {}'.format(CMD, gettext('error:'), msg)
    dialog_text = '''<b><big>{}</big></b>\n\n{}'''.format(gettext('Error'), msg)
    print(cli_text, file=sys.stderr)

76 77
    sh.zenity('--error', '--ellipsize', '--title', "", '--text', dialog_text,
              _ok_code=[0,1,5])
78 79 80
    sys.exit(1)


81
def check_free_memory(min_available_memory):
82 83
    """Check for enough free memory.

84 85 86 87 88 89 90 91
    # 1 KiB should be available when running the doctest
    >>> check_free_memory(1024)
    # 1 TiB should not be available, an error prompt should be displayed
    >>> try:
    ...     check_free_memory(1024*1024*1024*1024)
    ...     fail()
    ... except SystemExit:
    ...     pass
92
    """
93 94 95 96 97 98

    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)
99 100 101 102 103 104 105 106 107
        error(ERROR_MESSAGE)


if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'doctest':
        import doctest
        doctest.testmod()
    else:
        main(*sys.argv[1:])