summaryrefslogtreecommitdiff
path: root/src/launcher.py
blob: a47d697c21631bd95975620786a2025bfe20b445 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import os
import shutil
import platform
import time
import threading
import ConfigParser

from leap.bitmask.app import start_app as bitmask_client
from leap.common.events import server, signal
from leap.common.events import events_pb2 as proto

import tuf.client.updater

bundles_per_platform = {
    "Windows": "windows",
    "Darwin": "darwin",
    "Linux": "linux",
}

GENERAL_SECTION = "General"
DELAY_KEY = "updater_delay"


class TUF(threading.Thread):
    def __init__(self, config):
        """
        Initialize the list of mirrors, paths and other TUF dependencies from the config file
        """
        if config.has_section(GENERAL_SECTION) and \
                config.has_option(GENERAL_SECTION, DELAY_KEY):
            self.delay = config.getint(GENERAL_SECTION, DELAY_KEY)
        else:
            self.delay = 60

        self._load_mirrors(config)
        if not self.mirrors:
            print "ERROR: No updater mirrors found (missing or not well formed launcher.conf)"

        self.bundle_path = os.getcwd()
        self.source_path = self.bundle_path
        self.dest_path = os.path.join(self.bundle_path, 'tmp')
        self.update_path = os.path.join(self.bundle_path, 'updates')

        threading.Thread.__init__(self)

    def run(self):
        """
        Check for updates periodically
        """
        if not self.mirrors:
            return

        while True:
            try:
                tuf.conf.repository_directory = os.path.join(self.bundle_path, 'repo')

                updater = tuf.client.updater.Updater('leap-updater', self.mirrors)
                updater.refresh()

                targets = updater.all_targets()
                updated_targets = updater.updated_targets(targets, self.source_path)
                for target in updated_targets:
                    updater.download_target(target, self.dest_path)
                    self._set_permissions(target)
                if os.path.isdir(self.dest_path):
                    if os.path.isdir(self.update_path):
                        shutil.rmtree(self.update_path)
                    shutil.move(self.dest_path, self.update_path)
                    signal(proto.UPDATER_NEW_UPDATES,
                           content=", ".join(sorted([f['filepath'] for f in updated_targets])))
                    return
            except Exception as e:
                print "ERROR:", e
            finally:
                time.sleep(self.delay)

    def _load_mirrors(self, config):
        self.mirrors = {}
        for section in config.sections():
            if section[:6] != 'Mirror':
                continue
            url_prefix = config.get(section, 'url_prefix')
            metadata_path = bundles_per_platform[platform.system()] + '/metadata'
            targets_path = bundles_per_platform[platform.system()] + '/targets'
            self.mirrors[section[7:]] = {'url_prefix': url_prefix,
                                         'metadata_path': metadata_path,
                                         'targets_path': targets_path,
                                         'confined_target_dirs': ['']}

    def _set_permissions(self, target):
        file_permisions = int(target["fileinfo"]["custom"]["file_permissions"], 8)
        filepath = target['filepath']
        if filepath[0] == '/':
            filepath = filepath[1:]
        file_path = os.path.join(self.dest_path, filepath)
        os.chmod(file_path, file_permisions)


if __name__ == "__main__":
    server.ensure_server(port=8090)

    config = ConfigParser.ConfigParser()
    config.read("launcher.conf")

    tuf_thread = TUF(config)
    tuf_thread.daemon = True
    tuf_thread.start()

    bitmask_client()