Ejemplo n.º 1
0
    def _retrieve_tarball(self, ctx):
        ''' Retrieve tarball for a given version '''

        # TODO make this function more robust wrt unexpected errors

        if not 'result' in ctx:
            logging.error('updater_runner: no result')
            self._schedule()
            return

        length, body, error = ctx.pop('result')
        if length == -1:
            logging.error('updater_runner: error: %s', str(error))
            self._schedule()
            return
        sha256 = updater_utils.sha256sum_extract(ctx['vinfo'], body)
        if not sha256:
            logging.error('updater_runner: invalid sha256')
            self._schedule()
            return

        # XXX We should not reuse the same CTX here
        ctx['sha256'] = sha256
        ctx['uri'] = updater_utils.tarball_get_uri(self.channel, ctx['vinfo'])

        RUNNER_CORE.run('dload', self._process_files, False, ctx)
Ejemplo n.º 2
0
    def _retrieve_tarball(self, ctx):
        ''' Retrieve tarball for a given version '''

        if not 'result' in ctx:
            logging.error('updater_runner: no result')
            self._schedule()
            return

        length, body, error = ctx.pop('result')
        if length == -1:
            logging.info('updater_runner: %s', str(error))
            self._schedule()
            return

        logging.info('updater_runner: signature (base64): %s',
                     base64.b64encode(body))

        ctx['signature'] = body
        ctx['uri'] = updater_utils.tarball_get_uri(self.system, ctx['vinfo'])

        logging.info('updater_runner: GET %s', ctx['uri'])

        deferred = Deferred()
        deferred.add_callback(self._process_files)
        deferred.add_errback(self._handle_failure)

        RUNNER_CORE.run('dload', deferred, False, ctx)
Ejemplo n.º 3
0
 def run(self):
     ''' Periodically run rendezvous '''
     logging.info('background_rendezvous: automatic rendezvous...')
     deferred = Deferred()
     deferred.add_callback(self._after_rendezvous)
     deferred.add_errback(self._schedule)
     RUNNER_CORE.run('rendezvous', deferred, False, None)
Ejemplo n.º 4
0
    def run(self):
        ''' Periodically run rendezvous '''

        if not privacy.allowed_to_run():
            _open_browser_on_windows('privacy.html')
            # Except from opening the browser, privacy actions are
            # now performed by RUNNER_CORE

        RUNNER_CORE.run('rendezvous', self._after_rendezvous)
Ejemplo n.º 5
0
    def run(self):
        ''' Periodically run rendezvous '''

        #
        # Except from opening the browser, privacy actions are
        # now performed by RUNNER_CORE
        #
        if not privacy.allowed_to_run():
            self._open_browser_on_windows('privacy.html')

        logging.info('background_rendezvous: automatic rendezvous...')
        RUNNER_CORE.run('rendezvous', self._after_rendezvous)
 def run(self):
     ''' Periodically run rendezvous '''
     #
     # Except from opening the browser, privacy actions are
     # now performed by RUNNER_CORE
     #
     if not privacy.allowed_to_run():
         self._open_browser_on_windows('privacy.html')
     logging.info('background_rendezvous: automatic rendezvous...')
     deferred = Deferred()
     deferred.add_callback(self._after_rendezvous)
     deferred.add_errback(self._schedule)
     RUNNER_CORE.run('rendezvous', deferred, False, None)
    def _after_rendezvous(self, unused):
        ''' After rendezvous actions '''

        #
        # This function is invoked both when the rendezvous fails
        # and succeeds.  If it succeeds, OK we have fresh information
        # on available tests and updates and we use it.  Otherwise,
        # if rendezvous fails, we may either have old information, or
        # no information, if this is the first rendezvous.  In any
        # case, we do our best to use the available information.
        #

        logging.info('background_rendezvous: automatic rendezvous... done')

        # Inform the user when we have updates
        new_version = RUNNER_UPDATES.get_update_version()
        new_uri = RUNNER_UPDATES.get_update_uri()
        if new_version and new_uri and not CONFIG['win32_updater']:
            logging.info('runner_rendezvous: version %s available at %s',
                         new_version, new_uri)
            STATE.update('update', {'version': new_version,
                                    'uri': new_uri})
            self._open_browser_on_windows('update.html')

        #
        # Choose the test we would like to run even if
        # we're not going to run it because tests are
        # disabled.  So we can print the test name also
        # when tests are disabled.
        #
        test = RUNNER_POLICY.get_next_test()
        logging.info('background_rendezvous: chosen test: %s', test)

        # Are we allowed to run a test?
        if not CONFIG['enabled']:
            raise RuntimeError('background_rendezvous: automatic '
                               'tests disabled')

        #
        # RAW test requires auto_discover to be True, since it uses mlab-ns
        # to discover servers.  Other tests don't need that, since, at the
        # moment, they discover servers during the rendezvous.  So, if their
        # auto_discover were True, they'd end up running two rendezvous in
        # a row for no good reason.
        #
        auto_discover = (test == 'raw')

        # Actually run the test
        deferred = Deferred()
        deferred.add_callback(self._schedule)
        RUNNER_CORE.run(test, deferred, auto_discover, None)
Ejemplo n.º 8
0
    def retrieve_files(self, ctx, vinfo):
        ''' Retrieve files for a given version '''
        # Note: this is a separate function for testability

        uri = updater_utils.signature_get_uri(self.system, vinfo)
        ctx['uri'] = uri
        ctx['vinfo'] = vinfo
        logging.info('updater_runner: GET %s', uri)

        deferred = Deferred()
        deferred.add_callback(self._retrieve_tarball)
        deferred.add_errback(self._handle_failure)

        RUNNER_CORE.run('dload', deferred, False, ctx)
Ejemplo n.º 9
0
    def retrieve_versioninfo(self):
        ''' Retrieve version information '''

        #
        # The windows updater is still experimental, so it
        # is disabled by default and one needs to enable it
        # explicitly using the Web UI.
        #
        if not CONFIG['win32_updater']:
            self._schedule()
            return

        ctx = { 'uri': updater_utils.versioninfo_get_uri(self.channel) }
        RUNNER_CORE.run('dload', self._process_versioninfo, False, ctx)
Ejemplo n.º 10
0
    def _after_rendezvous(self, unused):
        ''' After rendezvous actions '''

        #
        # This function is invoked both when the rendezvous fails
        # and succeeds.  If it succeeds, OK we have fresh information
        # on available tests and updates and we use it.  Otherwise,
        # if rendezvous fails, we may either have old information, or
        # no information, if this is the first rendezvous.  In any
        # case, we do our best to use the available information.
        #

        logging.info('background_rendezvous: automatic rendezvous... done')

        # Inform the user when we have updates
        new_version = RUNNER_UPDATES.get_update_version()
        new_uri = RUNNER_UPDATES.get_update_uri()
        if new_version and new_uri and not CONFIG['win32_updater']:
            logging.info('runner_rendezvous: version %s available at %s',
                         new_version, new_uri)
            STATE.update('update', {'version': new_version,
                                    'uri': new_uri})

        #
        # Choose the test we would like to run even if
        # we're not going to run it because tests are
        # disabled.  So we can print the test name also
        # when tests are disabled.
        #
        # Note: we pick a test at random because now we
        # have a fixed probability of running a test.
        #
        test = RUNNER_POLICY.get_random_test()
        logging.info('background_rendezvous: chosen test: %s', test)

        # Are we allowed to run a test?
        if not CONFIG['enabled']:
            raise RuntimeError('background_rendezvous: automatic '
                               'tests disabled')

        #
        # The two legacy tests, speedtest and bittorent, use the rendezvous
        # to discover the servers. Other tests use mlab-ns.
        #
        use_mlabns = (test != 'speedtest' and test != 'bittorrent')

        # Actually run the test
        deferred = Deferred()
        deferred.add_callback(self._schedule)
        RUNNER_CORE.run(test, deferred, use_mlabns, None)
Ejemplo n.º 11
0
    def _after_rendezvous(self):
        ''' After rendezvous actions '''

        # TODO Make this function more robust wrt unexpected errors

        #
        # This function is invoked both when the rendezvous fails
        # and succeeds.  If it succeeds, OK we have fresh information
        # on available tests and updates and we use it.  Otherwise,
        # if rendezvous fails, we may either have old information, or
        # no information, if this is the first rendezvous.  In any
        # case, we do our best to use the available information.
        #

        logging.info('background_rendezvous: automatic rendezvous... done')

        # Inform the user when we have updates
        new_version = RUNNER_UPDATES.get_update_version()
        new_uri = RUNNER_UPDATES.get_update_uri()
        if new_version and new_uri and not CONFIG['win32_updater']:
            logging.info('runner_rendezvous: version %s available at %s',
                         new_version, new_uri)
            STATE.update('update', {'version': new_version,
                                    'uri': new_uri})
            self._open_browser_on_windows('update.html')

        #
        # Choose the test we would like to run even if
        # we're not going to run it because tests are
        # disabled.  So we can print the test name also
        # when tests are disabled.
        #
        test = RUNNER_TESTS.get_next_test()
        if not test:
            logging.warning('background_rendezvous: no test available')
            self._schedule()
            return

        logging.info('background_rendezvous: chosen test: %s', test)

        # Are we allowed to run a test?
        if not CONFIG['enabled']:
            logging.info('background_rendezvous: automatic tests are disabled')
            self._schedule()
            return

        # Actually run the test
        RUNNER_CORE.run(test, self._schedule)
Ejemplo n.º 12
0
    def _after_rendezvous(self):
        ''' After rendezvous actions '''

        #
        # If rendezvous fails, RUNNER_UPDATES and RUNNER_TESTS
        # may be empty.  In such case, this function becomes just
        # a no operation and nothing happens.
        #

        # Inform the user when we have updates
        new_version = RUNNER_UPDATES.get_update_version()
        new_uri = RUNNER_UPDATES.get_update_uri()
        if new_version and new_uri:
            logging.info("Version %s available at %s", new_version, new_uri)
            STATE.update("update", {"version": new_version,
                                    "uri": new_uri})
            _open_browser_on_windows('update.html')

        #
        # Choose the test we would like to run even if
        # we're not going to run it because we're running
        # in debug mode or tests are disabled.
        # This allows us to print to the logger the test
        # we /would/ have choosen if we were allowed to
        # run tests.
        #
        test = RUNNER_TESTS.get_next_test()
        if not test:
            logging.warning("No test available")
            self._schedule()
            return

        logging.info("* Chosen test: %s", test)

        # Are we allowed to run a test?
        if not CONFIG["enabled"]:
            logging.info("Tests are disabled... not running")
            self._schedule()
            return

        # Actually run the test
        RUNNER_CORE.run(test, self._schedule)
Ejemplo n.º 13
0
    def retrieve_versioninfo(self):
        ''' Retrieve version information '''

        #
        # The windows updater is still experimental, so it
        # is disabled by default and one needs to enable it
        # explicitly using the Web UI.
        #
        if not CONFIG['win32_updater']:
            self._schedule()
            return

        channel = CONFIG['win32_updater_channel']
        ctx = { 'uri': updater_utils.versioninfo_get_uri(self.system,
                                                         channel) }

        deferred = Deferred()
        deferred.add_callback(self._process_versioninfo)
        deferred.add_errback(self._handle_failure)

        RUNNER_CORE.run('dload', deferred, False, ctx)
Ejemplo n.º 14
0
def runner_api(stream, request, query):

    ''' Implements /api/runner '''

    response = Message()

    #
    # DO NOT allow to start a test when another test is in
    # progress because I have noticed that is confusing both
    # from
    # command line and WUI.
    #
    if RUNNER_CORE.test_is_running():
        raise ConfigError('A test is already in progress, try again later')

    #
    # If there is not a query string this API is just
    # a no-operation and returns an empty JSON body to
    # keep happy the AJAX code.
    #
    if not query:
        response.compose(code='200', reason='Ok', body='{}',
                         mimetype='application/json')
        stream.send_response(request, response)
        return

    options = cgi.parse_qs(query)

    #
    # If the query does not contain the name of the
    # test, this is an error and we must notify that
    # to the caller.  Raise ConfigError, which will
    # be automatically transformed into a 500 message
    # with the proper body and reason.
    #
    if not 'test' in options:
        raise ConfigError('Missing "test" option in query string')

    test = options['test'][0]

    #
    # Simple case: the caller does not want to follow the
    # test via log streaming.  We can immediately start
    # the test using the runner and, if everything is OK,
    # we can send a succesful response, with an empty JSON
    # body to keep happy the AJAX code.
    #
    if not 'streaming' in options or not utils.intify(options['streaming'][0]):
        RUNNER_CORE.run(test, runner_api_done)
        response.compose(code='200', reason='Ok', body='{}',
                         mimetype='application/json')
        stream.send_response(request, response)
        return

    #
    # More interesting case: the caller wants to see the log
    # messages during the test via the log streaming API.
    # We prepare a succesful response terminated by EOF and
    # then arrange things so that every new log message will
    # be copied to the HTTP response.
    # Then we kick off the runner, and note that we do that
    # AFTER we setup the response for eventual runner errors
    # to be copied to the HTTP response.
    # The runner core will automatically close all attached
    # streams at the end of the test.
    #
    response.compose(code='200', reason='Ok',
      up_to_eof=True, mimetype='text/plain')
    stream.send_response(request, response)
    LOG.start_streaming(stream)
    RUNNER_CORE.run(test, runner_api_done)
Ejemplo n.º 15
0
 def retrieve_files(self, vinfo):
     ''' Retrieve files for a given version '''
     # Note: this is a separate function for testability
     uri = updater_utils.sha256sum_get_uri(self.channel, vinfo)
     ctx = {'vinfo': vinfo, 'uri': uri}
     RUNNER_CORE.run('dload', self._retrieve_tarball, False, ctx)