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)
    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)