def get_target_info(self, run_state, path, dep_paths, args, reply_fn):
        """
        Return target_info of path in bundle as a message on the reply_fn
        """
        bundle_uuid = run_state.bundle['uuid']
        target_info = None

        # if path is a dependency raise an error
        if path and os.path.normpath(path) in dep_paths:
            err = (httplib.NOT_FOUND,
                   '{} not found in bundle {}'.format(path, bundle_uuid))
            reply_fn(err, None, None)
            return
        else:
            try:
                target_info = download_util.get_target_info(
                    run_state.bundle_path, bundle_uuid, path, args['depth'])
            except PathException as e:
                err = (httplib.NOT_FOUND, e.message)
                reply_fn(err, None, None)
                return

        if not path and args['depth'] > 0:
            target_info['contents'] = [
                child for child in target_info['contents']
                if child['name'] not in dep_paths
            ]

        reply_fn(None, {'target_info': target_info}, None)
    def _get_target_info(self, uuid, path, depth):
        """
        Returns information about an individual target inside the bundle, or
        None if the target or bundle doesn't exist.

        For information about the format of the return value, see
        worker.download_util.get_target_info.
        """
        try:
            bundle_state = self.get_bundle_state(uuid)
        except NotFoundError:
            bundle_state = None

        # Return None if invalid bundle reference
        if bundle_state is None:
            return None

        if self._is_available_locally(uuid):
            bundle_path = self.get_bundle_location(uuid)
            try:
                key = (bundle_path, uuid, path, depth)
                return self._cached_if_stable(
                    uuid, 'target_info', key,
                    lambda: download_util.get_target_info(*key))
            except download_util.PathException as e:
                raise UsageError(e.message)
        else:
            # TODO: validate that this is a reasonable approach
            worker = self.get_bundle_worker(uuid)
            response_socket_id = self._worker_model.allocate_socket(
                worker['user_id'], worker['worker_id'])
            try:
                read_args = {
                    'type': 'get_target_info',
                    'depth': depth,
                }
                self._send_read_message(worker, response_socket_id, uuid, path,
                                        read_args)
                with closing(
                        self._worker_model.start_listening(
                            response_socket_id)) as sock:
                    result = self._worker_model.get_json_message(sock, 60)
                if result is None:  # dead workers are a fact of life now
                    logging.info(
                        'Unable to reach worker, bundle state {}'.format(
                            bundle_state))
                    return None
                elif 'error_code' in result:
                    raise http_error_to_exception(result['error_code'],
                                                  result['error_message'])
                return result['target_info']
            finally:
                self._worker_model.deallocate_socket(response_socket_id)
Esempio n. 3
0
    def get_target_info(self, uuid, path, depth):
        """
        Returns information about an individual target inside the bundle, or
        None if the target or bundle doesn't exist.

        For information about the format of the return value, see
        worker.download_util.get_target_info.
        """
        try:
            bundle_state = self._bundle_model.get_bundle_state(uuid)
        except NotFoundError:
            bundle_state = None

        # Return None if invalid bundle reference
        if bundle_state is None:
            return None
        elif bundle_state != State.RUNNING:
            bundle_path = self._bundle_store.get_bundle_location(uuid)
            try:
                return download_util.get_target_info(bundle_path, uuid, path,
                                                     depth)
            except download_util.PathException as e:
                raise UsageError(e.message)
        else:
            # get_target_info calls are sent to the worker even on a shared file
            # system since 1) due to NFS caching the worker has more up to date
            # information on directory contents, and 2) the logic of hiding
            # the dependency paths doesn't need to be re-implemented here.
            worker = self._worker_model.get_bundle_worker(uuid)
            response_socket_id = self._worker_model.allocate_socket(
                worker['user_id'], worker['worker_id'])
            try:
                read_args = {
                    'type': 'get_target_info',
                    'depth': depth,
                }
                self._send_read_message(worker, response_socket_id, uuid, path,
                                        read_args)
                with closing(
                        self._worker_model.start_listening(
                            response_socket_id)) as sock:
                    result = self._worker_model.get_json_message(sock, 60)
                if result is None:  # dead workers are a fact of life now
                    logging.info(
                        'Unable to reach worker, bundle state {}'.format(
                            bundle_state))
                    return None
                elif 'error_code' in result:
                    raise http_error_to_exception(result['error_code'],
                                                  result['error_message'])
                return result['target_info']
            finally:
                self._worker_model.deallocate_socket(response_socket_id)
Esempio n. 4
0
    def get_target_info(self, uuid, path, depth):
        """
        Returns information about an individual target inside the bundle,
        Raises NotFoundError if the bundle or the path within the bundle is not found

        For information about the format of the return value, see
        worker.download_util.get_target_info.
        """
        bundle_state = self._bundle_model.get_bundle_state(uuid)
        # Raises NotFoundException if uuid is invalid

        if bundle_state == State.PREPARING:
            raise NotFoundError(
                "Bundle {} hasn't started running yet, files not available".format(uuid)
            )
        elif bundle_state != State.RUNNING:
            bundle_path = self._bundle_store.get_bundle_location(uuid)
            try:
                return download_util.get_target_info(bundle_path, uuid, path, depth)
            except download_util.PathException as e:
                raise NotFoundError(e.message)
        else:
            # get_target_info calls are sent to the worker even on a shared file
            # system since 1) due to NFS caching the worker has more up to date
            # information on directory contents, and 2) the logic of hiding
            # the dependency paths doesn't need to be re-implemented here.
            worker = self._worker_model.get_bundle_worker(uuid)
            response_socket_id = self._worker_model.allocate_socket(
                worker['user_id'], worker['worker_id']
            )
            try:
                read_args = {'type': 'get_target_info', 'depth': depth}
                self._send_read_message(worker, response_socket_id, uuid, path, read_args)
                with closing(self._worker_model.start_listening(response_socket_id)) as sock:
                    result = self._worker_model.get_json_message(sock, 60)
                if result is None:  # dead workers are a fact of life now
                    logging.info('Unable to reach worker, bundle state {}'.format(bundle_state))
                    raise NotFoundError(
                        'Unable to reach worker of running bundle with bundle state {}'.format(
                            bundle_state
                        )
                    )
                elif 'error_code' in result:
                    raise http_error_to_exception(result['error_code'], result['error_message'])
                return result['target_info']
            finally:
                self._worker_model.deallocate_socket(response_socket_id)