Exemplo n.º 1
0
    def get_by_filters(cls,
                       context,
                       filters,
                       limit=None,
                       marker=None,
                       sort_keys=None,
                       sort_dirs=None):
        if limit == 0:
            return cls(context, objects=[])
        # 'deleted' records can not be returned from here since build_requests
        # are not soft deleted.
        if filters.get('deleted', False):
            return cls(context, objects=[])
        # 'cleaned' records won't exist as they would need to be deleted.
        if filters.get('cleaned', False):
            return cls(context, objects=[])

        # Because the build_requests table stores an instance as a serialized
        # versioned object it is not feasible to do the filtering and sorting
        # in the database. Just get all potentially relevant records and
        # process them here. It should be noted that build requests are short
        # lived so there should not be a lot of results to deal with.
        build_requests = cls.get_all(context)

        # Fortunately some filters do not apply here.
        # 'tags' can not be applied at boot time so will not be set for an
        # instance here.
        # 'changes-since' works off of the updated_at field which has not yet
        # been set at the point in the boot process where build_request still
        # exists. So it can be ignored.
        # 'deleted' and 'cleaned' are handled above.

        sort_keys, sort_dirs = db.process_sort_params(sort_keys,
                                                      sort_dirs,
                                                      default_dir='desc')

        # For other filters that don't match this, we will do regexp matching
        # Taken from db/sqlalchemy/api.py
        exact_match_filter_names = [
            'project_id', 'user_id', 'image_ref', 'vm_state',
            'instance_type_id', 'uuid', 'metadata', 'host', 'task_state',
            'system_metadata'
        ]
        exact_filters = {}
        regex_filters = {}
        for key, value in filters.items():
            if key in exact_match_filter_names:
                exact_filters[key] = value
            else:
                regex_filters[key] = value

        # As much as possible this copies the logic from db/sqlalchemy/api.py
        # instance_get_all_by_filters_sort. The main difference is that method
        # builds a sql query and this filters in python.
        filtered_build_reqs = []

        for build_req in build_requests:
            instance = build_req.instance

            filter_result = cls._pass_exact_filters(instance, exact_filters)
            if filter_result is None:
                # The filter condition is such that nothing will match.
                # Bail early.
                return cls(context, objects=[])
            if filter_result is False:
                continue

            if not cls._pass_regex_filters(instance, regex_filters):
                continue

            filtered_build_reqs.append(build_req)

        if (len(filtered_build_reqs) < 2) or (not sort_keys):
            # No need to sort
            return cls(context, objects=filtered_build_reqs)

        sorted_build_reqs = cls._sort_build_requests(filtered_build_reqs,
                                                     sort_keys, sort_dirs)

        marker_index = 0
        if marker:
            for i, build_req in enumerate(sorted_build_reqs):
                if build_req.instance.uuid == marker:
                    marker_index = i
                    break
        len_build_reqs = len(sorted_build_reqs)
        limit_index = len_build_reqs
        if limit:
            limit_index = marker_index + limit
            if limit_index > len_build_reqs:
                limit_index = len_build_reqs

        return cls(context,
                   objects=sorted_build_reqs[marker_index:limit_index])
Exemplo n.º 2
0
    def get_by_filters(cls, context, filters, limit=None, marker=None,
                       sort_keys=None, sort_dirs=None):
        if limit == 0:
            return cls(context, objects=[])
        # 'deleted' records can not be returned from here since build_requests
        # are not soft deleted.
        if filters.get('deleted', False):
            return cls(context, objects=[])
        # 'cleaned' records won't exist as they would need to be deleted.
        if filters.get('cleaned', False):
            return cls(context, objects=[])

        # Because the build_requests table stores an instance as a serialized
        # versioned object it is not feasible to do the filtering and sorting
        # in the database. Just get all potentially relevant records and
        # process them here. It should be noted that build requests are short
        # lived so there should not be a lot of results to deal with.
        build_requests = cls.get_all(context)

        # Fortunately some filters do not apply here.
        # 'changes-since' works off of the updated_at field which has not yet
        # been set at the point in the boot process where build_request still
        # exists. So it can be ignored.
        # 'deleted' and 'cleaned' are handled above.

        sort_keys, sort_dirs = db.process_sort_params(sort_keys, sort_dirs,
                                                      default_dir='desc')

        # For other filters that don't match this, we will do regexp matching
        # Taken from db/sqlalchemy/api.py
        exact_match_filter_names = ['project_id', 'user_id', 'image_ref',
                                    'vm_state', 'instance_type_id', 'uuid',
                                    'metadata', 'host', 'task_state',
                                    'system_metadata', 'tags', 'tags-any',
                                    'not-tags', 'not-tags-any']
        exact_filters = {}
        regex_filters = {}
        for key, value in filters.items():
            if key in exact_match_filter_names:
                exact_filters[key] = value
            else:
                regex_filters[key] = value

        # As much as possible this copies the logic from db/sqlalchemy/api.py
        # instance_get_all_by_filters_sort. The main difference is that method
        # builds a sql query and this filters in python.
        filtered_build_reqs = []

        for build_req in build_requests:
            instance = build_req.instance

            filter_result = cls._pass_exact_filters(instance, exact_filters)
            if filter_result is None:
                # The filter condition is such that nothing will match.
                # Bail early.
                return cls(context, objects=[])
            if filter_result is False:
                continue

            if not cls._pass_regex_filters(instance, regex_filters):
                continue

            filtered_build_reqs.append(build_req)

        if (len(filtered_build_reqs) < 2) or (not sort_keys):
            # No need to sort
            return cls(context, objects=filtered_build_reqs)

        sorted_build_reqs = cls._sort_build_requests(filtered_build_reqs,
                                                     sort_keys, sort_dirs)

        marker_index = 0
        if marker:
            for i, build_req in enumerate(sorted_build_reqs):
                if build_req.instance.uuid == marker:
                    marker_index = i
                    break
        len_build_reqs = len(sorted_build_reqs)
        limit_index = len_build_reqs
        if limit:
            limit_index = marker_index + limit
            if limit_index > len_build_reqs:
                limit_index = len_build_reqs

        return cls(context,
                   objects=sorted_build_reqs[marker_index:limit_index])