)]}'
{"nova/api/openstack/placement/objects/resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"70821a863dea67c395c92f24a0c21591114604d3","unresolved":false,"context_lines":[{"line_number":722,"context_line":""},{"line_number":723,"context_line":"        :raises NotFound if no such provider could be found"},{"line_number":724,"context_line":"        :param uuid: UUID of the provider to search for"},{"line_number":725,"context_line":"        :param do_migration: If True, allow data migration to be performed"},{"line_number":726,"context_line":"                (legacy records are rewritten to bring them up to the latest"},{"line_number":727,"context_line":"                database schema). This requires the caller to be in a writer"},{"line_number":728,"context_line":"                context. If False, the (correct) data is returned without"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f6a8fd7_fa8365a8","line":725,"updated":"2018-04-26 11:37:01.000000000","message":"As discussed in irc I think we should explore instating the planned blocker migration (see http://p.anticdent.org/8r8 ) instead of adding this do_migration stuff","commit_id":"9fd175eb78b503ef1ffc29c08df59d5f0aac5c85"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0ace3deb60631d8c6861953de957f97a02750b5e","unresolved":false,"context_lines":[{"line_number":722,"context_line":""},{"line_number":723,"context_line":"        :raises NotFound if no such provider could be found"},{"line_number":724,"context_line":"        :param uuid: UUID of the provider to search for"},{"line_number":725,"context_line":"        :param do_migration: If True, allow data migration to be performed"},{"line_number":726,"context_line":"                (legacy records are rewritten to bring them up to the latest"},{"line_number":727,"context_line":"                database schema). This requires the caller to be in a writer"},{"line_number":728,"context_line":"                context. If False, the (correct) data is returned without"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f6a8fd7_999a456c","line":725,"in_reply_to":"9f6a8fd7_88aaf516","updated":"2018-04-29 15:11:15.000000000","message":"dang","commit_id":"9fd175eb78b503ef1ffc29c08df59d5f0aac5c85"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"95706bd3dcee3368bcf465dad59cfee59f5767af","unresolved":false,"context_lines":[{"line_number":722,"context_line":""},{"line_number":723,"context_line":"        :raises NotFound if no such provider could be found"},{"line_number":724,"context_line":"        :param uuid: UUID of the provider to search for"},{"line_number":725,"context_line":"        :param do_migration: If True, allow data migration to be performed"},{"line_number":726,"context_line":"                (legacy records are rewritten to bring them up to the latest"},{"line_number":727,"context_line":"                database schema). This requires the caller to be in a writer"},{"line_number":728,"context_line":"                context. If False, the (correct) data is returned without"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f6a8fd7_88aaf516","line":725,"in_reply_to":"9f6a8fd7_fa8365a8","updated":"2018-04-28 19:39:45.000000000","message":"Based on subsequent discussions, it looks like that\u0027s gonna take a couple of releases to happen.","commit_id":"9fd175eb78b503ef1ffc29c08df59d5f0aac5c85"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"70821a863dea67c395c92f24a0c21591114604d3","unresolved":false,"context_lines":[{"line_number":3694,"context_line":"                                                required_trait_map,"},{"line_number":3695,"context_line":"                                                forbidden_trait_map,"},{"line_number":3696,"context_line":"                                                member_of)"},{"line_number":3697,"context_line":"            alloc_request_objs, summary_objs \u003d _alloc_candidates_no_shared("},{"line_number":3698,"context_line":"                context, resources, rp_ids)"},{"line_number":3699,"context_line":"        else:"},{"line_number":3700,"context_line":"            if required_trait_map:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f6a8fd7_9aa90926","line":3697,"updated":"2018-04-26 11:37:01.000000000","message":"This is the source of the test failures.","commit_id":"9fd175eb78b503ef1ffc29c08df59d5f0aac5c85"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"95706bd3dcee3368bcf465dad59cfee59f5767af","unresolved":false,"context_lines":[{"line_number":3694,"context_line":"                                                required_trait_map,"},{"line_number":3695,"context_line":"                                                forbidden_trait_map,"},{"line_number":3696,"context_line":"                                                member_of)"},{"line_number":3697,"context_line":"            alloc_request_objs, summary_objs \u003d _alloc_candidates_no_shared("},{"line_number":3698,"context_line":"                context, resources, rp_ids)"},{"line_number":3699,"context_line":"        else:"},{"line_number":3700,"context_line":"            if required_trait_map:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f6a8fd7_48305d08","line":3697,"in_reply_to":"9f6a8fd7_9aa90926","updated":"2018-04-28 19:39:45.000000000","message":"Done","commit_id":"9fd175eb78b503ef1ffc29c08df59d5f0aac5c85"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a88fb5dcc330d604670820cc4b52e4dba676dc14","unresolved":false,"context_lines":[{"line_number":766,"context_line":"        self.obj_reset_changes()"},{"line_number":767,"context_line":""},{"line_number":768,"context_line":"    @classmethod"},{"line_number":769,"context_line":"    def get_by_uuid(cls, context, uuid, do_migration\u003dTrue):"},{"line_number":770,"context_line":"        \"\"\"Returns a new ResourceProvider object with the supplied UUID."},{"line_number":771,"context_line":""},{"line_number":772,"context_line":"        :raises NotFound if no such provider could be found"},{"line_number":773,"context_line":"        :param uuid: UUID of the provider to search for"},{"line_number":774,"context_line":"        :param do_migration: If True, allow data migration to be performed"},{"line_number":775,"context_line":"                (legacy records are rewritten to bring them up to the latest"},{"line_number":776,"context_line":"                database schema). This requires the caller to be in a writer"},{"line_number":777,"context_line":"                context. If False, the (correct) data is returned without"},{"line_number":778,"context_line":"                attempting data migration. This can safely be done from a"},{"line_number":779,"context_line":"                reader context."},{"line_number":780,"context_line":"        \"\"\""},{"line_number":781,"context_line":"        rp_rec \u003d _get_provider_by_uuid(context, uuid)"},{"line_number":782,"context_line":"        meth \u003d (cls._from_db_object if do_migration"},{"line_number":783,"context_line":"                else cls._from_db_object_no_migration)"},{"line_number":784,"context_line":"        return meth(context, cls(), rp_rec)"},{"line_number":785,"context_line":""},{"line_number":786,"context_line":"    def add_inventory(self, inventory):"},{"line_number":787,"context_line":"        \"\"\"Add one new Inventory to the resource provider."},{"line_number":788,"context_line":""},{"line_number":789,"context_line":"        Fails if Inventory of the provided resource class is"},{"line_number":790,"context_line":"        already present."},{"line_number":791,"context_line":"        \"\"\""},{"line_number":792,"context_line":"        _add_inventory(self._context, self, inventory)"},{"line_number":793,"context_line":"        self.obj_reset_changes()"},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"    def delete_inventory(self, resource_class):"},{"line_number":796,"context_line":"        \"\"\"Delete Inventory of provided resource_class.\"\"\""},{"line_number":797,"context_line":"        _delete_inventory(self._context, self, resource_class)"},{"line_number":798,"context_line":"        self.obj_reset_changes()"},{"line_number":799,"context_line":""},{"line_number":800,"context_line":"    def set_inventory(self, inv_list):"},{"line_number":801,"context_line":"        \"\"\"Set all resource provider Inventory to be the provided list.\"\"\""},{"line_number":802,"context_line":"        exceeded \u003d _set_inventory(self._context, self, inv_list)"},{"line_number":803,"context_line":"        for uuid, rclass in exceeded:"},{"line_number":804,"context_line":"            LOG.warning(\u0027Resource provider %(uuid)s is now over-\u0027"},{"line_number":805,"context_line":"                        \u0027capacity for %(resource)s\u0027,"},{"line_number":806,"context_line":"                        {\u0027uuid\u0027: uuid, \u0027resource\u0027: rclass})"},{"line_number":807,"context_line":"        self.obj_reset_changes()"},{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def update_inventory(self, inventory):"},{"line_number":810,"context_line":"        \"\"\"Update one existing Inventory of the same resource class."},{"line_number":811,"context_line":""},{"line_number":812,"context_line":"        Fails if no Inventory of the same class is present."},{"line_number":813,"context_line":"        \"\"\""},{"line_number":814,"context_line":"        exceeded \u003d _update_inventory(self._context, self, inventory)"},{"line_number":815,"context_line":"        for uuid, rclass in exceeded:"},{"line_number":816,"context_line":"            LOG.warning(\u0027Resource provider %(uuid)s is now over-\u0027"},{"line_number":817,"context_line":"                        \u0027capacity for %(resource)s\u0027,"},{"line_number":818,"context_line":"                        {\u0027uuid\u0027: uuid, \u0027resource\u0027: rclass})"},{"line_number":819,"context_line":"        self.obj_reset_changes()"},{"line_number":820,"context_line":""},{"line_number":821,"context_line":"    def get_aggregates(self):"},{"line_number":822,"context_line":"        \"\"\"Get the aggregate uuids associated with this resource provider.\"\"\""},{"line_number":823,"context_line":"        return _get_aggregates_by_provider_id(self._context, self.id)"},{"line_number":824,"context_line":""},{"line_number":825,"context_line":"    def set_aggregates(self, aggregate_uuids, increment_generation\u003dFalse):"},{"line_number":826,"context_line":"        \"\"\"Set the aggregate uuids associated with this resource provider."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        If an aggregate does not exist, one will be created using the"},{"line_number":829,"context_line":"        provided uuid."},{"line_number":830,"context_line":""},{"line_number":831,"context_line":"        The resource provider generation is incremented if and only if the"},{"line_number":832,"context_line":"        increment_generation parameter is True."},{"line_number":833,"context_line":"        \"\"\""},{"line_number":834,"context_line":"        _set_aggregates(self._context, self, aggregate_uuids,"},{"line_number":835,"context_line":"                        increment_generation\u003dincrement_generation)"},{"line_number":836,"context_line":""},{"line_number":837,"context_line":"    def set_traits(self, traits):"},{"line_number":838,"context_line":"        \"\"\"Replaces the set of traits associated with the resource provider"},{"line_number":839,"context_line":"        with the given list of Trait objects."},{"line_number":840,"context_line":""},{"line_number":841,"context_line":"        :param traits: A list of Trait objects representing the traits to"},{"line_number":842,"context_line":"                       associate with the provider."},{"line_number":843,"context_line":"        \"\"\""},{"line_number":844,"context_line":"        _set_traits(self._context, self, traits)"},{"line_number":845,"context_line":"        self.obj_reset_changes()"},{"line_number":846,"context_line":""},{"line_number":847,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":848,"context_line":"    def _create_in_db(self, context, updates):"},{"line_number":849,"context_line":"        parent_id \u003d None"},{"line_number":850,"context_line":"        root_id \u003d None"},{"line_number":851,"context_line":"        # User supplied a parent, let\u0027s make sure it exists"},{"line_number":852,"context_line":"        parent_uuid \u003d updates.pop(\u0027parent_provider_uuid\u0027)"},{"line_number":853,"context_line":"        if parent_uuid is not None:"},{"line_number":854,"context_line":"            # Setting parent to ourselves doesn\u0027t make any sense"},{"line_number":855,"context_line":"            if parent_uuid \u003d\u003d self.uuid:"},{"line_number":856,"context_line":"                raise exception.ObjectActionError("},{"line_number":857,"context_line":"                        action\u003d\u0027create\u0027,"},{"line_number":858,"context_line":"                        reason\u003d_(\u0027parent provider UUID cannot be same as \u0027"},{"line_number":859,"context_line":"                                 \u0027UUID. Please set parent provider UUID to \u0027"},{"line_number":860,"context_line":"                                 \u0027None if there is no parent.\u0027))"},{"line_number":861,"context_line":""},{"line_number":862,"context_line":"            parent_ids \u003d _provider_ids_from_uuid(context, parent_uuid)"},{"line_number":863,"context_line":"            if parent_ids is None:"},{"line_number":864,"context_line":"                raise exception.ObjectActionError("},{"line_number":865,"context_line":"                        action\u003d\u0027create\u0027,"},{"line_number":866,"context_line":"                        reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":867,"context_line":""},{"line_number":868,"context_line":"            parent_id \u003d parent_ids.id"},{"line_number":869,"context_line":"            root_id \u003d parent_ids.root_id"},{"line_number":870,"context_line":"            updates[\u0027root_provider_id\u0027] \u003d root_id"},{"line_number":871,"context_line":"            updates[\u0027parent_provider_id\u0027] \u003d parent_id"},{"line_number":872,"context_line":"            self.root_provider_uuid \u003d parent_ids.root_uuid"},{"line_number":873,"context_line":""},{"line_number":874,"context_line":"        db_rp \u003d models.ResourceProvider()"},{"line_number":875,"context_line":"        db_rp.update(updates)"},{"line_number":876,"context_line":"        context.session.add(db_rp)"},{"line_number":877,"context_line":"        context.session.flush()"},{"line_number":878,"context_line":""},{"line_number":879,"context_line":"        self.id \u003d db_rp.id"},{"line_number":880,"context_line":"        self.generation \u003d db_rp.generation"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"        if root_id is None:"},{"line_number":883,"context_line":"            # User did not specify a parent when creating this provider, so the"},{"line_number":884,"context_line":"            # root_provider_id needs to be set to this provider\u0027s newly-created"},{"line_number":885,"context_line":"            # internal ID"},{"line_number":886,"context_line":"            db_rp.root_provider_id \u003d db_rp.id"},{"line_number":887,"context_line":"            context.session.add(db_rp)"},{"line_number":888,"context_line":"            context.session.flush()"},{"line_number":889,"context_line":"            self.root_provider_uuid \u003d self.uuid"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    @staticmethod"},{"line_number":892,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":893,"context_line":"    def _delete(context, _id):"},{"line_number":894,"context_line":"        # Do a quick check to see if the provider is a parent. If it is, don\u0027t"},{"line_number":895,"context_line":"        # allow deleting the provider. Note that the foreign key constraint on"},{"line_number":896,"context_line":"        # resource_providers.parent_provider_id will prevent deletion of the"},{"line_number":897,"context_line":"        # parent within the transaction below. This is just a quick"},{"line_number":898,"context_line":"        # short-circuit outside of the transaction boundary."},{"line_number":899,"context_line":"        if _has_child_providers(context, _id):"},{"line_number":900,"context_line":"            raise exception.CannotDeleteParentResourceProvider()"},{"line_number":901,"context_line":""},{"line_number":902,"context_line":"        # Don\u0027t delete the resource provider if it has allocations."},{"line_number":903,"context_line":"        rp_allocations \u003d context.session.query(models.Allocation).\\"},{"line_number":904,"context_line":"             filter(models.Allocation.resource_provider_id \u003d\u003d _id).\\"},{"line_number":905,"context_line":"             count()"},{"line_number":906,"context_line":"        if rp_allocations:"},{"line_number":907,"context_line":"            raise exception.ResourceProviderInUse()"},{"line_number":908,"context_line":"        # Delete any inventory associated with the resource provider"},{"line_number":909,"context_line":"        context.session.query(models.Inventory).\\"},{"line_number":910,"context_line":"            filter(models.Inventory.resource_provider_id \u003d\u003d _id).\\"},{"line_number":911,"context_line":"            delete(synchronize_session\u003dFalse)"},{"line_number":912,"context_line":"        # Delete any aggregate associations for the resource provider"},{"line_number":913,"context_line":"        # The name substitution on the next line is needed to satisfy pep8"},{"line_number":914,"context_line":"        RPA_model \u003d models.ResourceProviderAggregate"},{"line_number":915,"context_line":"        context.session.query(RPA_model).\\"},{"line_number":916,"context_line":"                filter(RPA_model.resource_provider_id \u003d\u003d _id).delete()"},{"line_number":917,"context_line":"        # delete any trait associations for the resource provider"},{"line_number":918,"context_line":"        RPT_model \u003d models.ResourceProviderTrait"},{"line_number":919,"context_line":"        context.session.query(RPT_model).\\"},{"line_number":920,"context_line":"                filter(RPT_model.resource_provider_id \u003d\u003d _id).delete()"},{"line_number":921,"context_line":"        # set root_provider_id to null to make deletion possible"},{"line_number":922,"context_line":"        context.session.query(models.ResourceProvider).\\"},{"line_number":923,"context_line":"            filter(models.ResourceProvider.id \u003d\u003d _id,"},{"line_number":924,"context_line":"                   models.ResourceProvider.root_provider_id \u003d\u003d _id).\\"},{"line_number":925,"context_line":"            update({\u0027root_provider_id\u0027: None})"},{"line_number":926,"context_line":"        # Now delete the RP record"},{"line_number":927,"context_line":"        try:"},{"line_number":928,"context_line":"            result \u003d _delete_rp_record(context, _id)"},{"line_number":929,"context_line":"        except sqla_exc.IntegrityError:"},{"line_number":930,"context_line":"            # NOTE(jaypipes): Another thread snuck in and parented this"},{"line_number":931,"context_line":"            # resource provider in between the above check for"},{"line_number":932,"context_line":"            # _has_child_providers() and our attempt to delete the record"},{"line_number":933,"context_line":"            raise exception.CannotDeleteParentResourceProvider()"},{"line_number":934,"context_line":"        if not result:"},{"line_number":935,"context_line":"            raise exception.NotFound()"},{"line_number":936,"context_line":""},{"line_number":937,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":938,"context_line":"    def _update_in_db(self, context, id, updates):"},{"line_number":939,"context_line":"        if \u0027parent_provider_uuid\u0027 in updates:"},{"line_number":940,"context_line":"            # TODO(jaypipes): For now, \"re-parenting\" and \"un-parenting\" are"},{"line_number":941,"context_line":"            # not possible. If the provider already had a parent, we don\u0027t"},{"line_number":942,"context_line":"            # allow changing that parent due to various issues, including:"},{"line_number":943,"context_line":"            #"},{"line_number":944,"context_line":"            # * if the new parent is a descendant of this resource provider, we"},{"line_number":945,"context_line":"            #   introduce the possibility of a loop in the graph, which would"},{"line_number":946,"context_line":"            #   be very bad"},{"line_number":947,"context_line":"            # * potentially orphaning heretofore-descendants"},{"line_number":948,"context_line":"            #"},{"line_number":949,"context_line":"            # So, for now, let\u0027s just prevent re-parenting..."},{"line_number":950,"context_line":"            my_ids \u003d _provider_ids_from_uuid(context, self.uuid)"},{"line_number":951,"context_line":"            parent_uuid \u003d updates.pop(\u0027parent_provider_uuid\u0027)"},{"line_number":952,"context_line":"            if parent_uuid is not None:"},{"line_number":953,"context_line":"                parent_ids \u003d _provider_ids_from_uuid(context, parent_uuid)"},{"line_number":954,"context_line":"                # User supplied a parent, let\u0027s make sure it exists"},{"line_number":955,"context_line":"                if parent_ids is None:"},{"line_number":956,"context_line":"                    raise exception.ObjectActionError("},{"line_number":957,"context_line":"                            action\u003d\u0027create\u0027,"},{"line_number":958,"context_line":"                            reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":959,"context_line":"                if (my_ids.parent_id is not None and"},{"line_number":960,"context_line":"                        my_ids.parent_id !\u003d parent_ids.id):"},{"line_number":961,"context_line":"                    raise exception.ObjectActionError("},{"line_number":962,"context_line":"                            action\u003d\u0027update\u0027,"},{"line_number":963,"context_line":"                            reason\u003d_(\u0027re-parenting a provider is not \u0027"},{"line_number":964,"context_line":"                                     \u0027currently allowed.\u0027))"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"                updates[\u0027root_provider_id\u0027] \u003d parent_ids.root_id"},{"line_number":967,"context_line":"                updates[\u0027parent_provider_id\u0027] \u003d parent_ids.id"},{"line_number":968,"context_line":"                self.root_provider_uuid \u003d parent_ids.root_uuid"},{"line_number":969,"context_line":"            else:"},{"line_number":970,"context_line":"                if my_ids.parent_id is not None:"},{"line_number":971,"context_line":"                    raise exception.ObjectActionError("},{"line_number":972,"context_line":"                            action\u003d\u0027update\u0027,"},{"line_number":973,"context_line":"                            reason\u003d_(\u0027un-parenting a provider is not \u0027"},{"line_number":974,"context_line":"                                     \u0027currently allowed.\u0027))"},{"line_number":975,"context_line":""},{"line_number":976,"context_line":"        db_rp \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":977,"context_line":"            id\u003did).first()"},{"line_number":978,"context_line":"        db_rp.update(updates)"},{"line_number":979,"context_line":"        try:"},{"line_number":980,"context_line":"            db_rp.save(context.session)"},{"line_number":981,"context_line":"        except sqla_exc.IntegrityError:"},{"line_number":982,"context_line":"            # NOTE(jaypipes): Another thread snuck in and deleted the parent"},{"line_number":983,"context_line":"            # for this resource provider in between the above check for a valid"},{"line_number":984,"context_line":"            # parent provider and here..."},{"line_number":985,"context_line":"            raise exception.ObjectActionError("},{"line_number":986,"context_line":"                    action\u003d\u0027update\u0027,"},{"line_number":987,"context_line":"                    reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":988,"context_line":""},{"line_number":989,"context_line":"    @staticmethod"},{"line_number":990,"context_line":"    def _from_db_object_migration_choice(context, resource_provider,"},{"line_number":991,"context_line":"                                         db_resource_provider, do_migration):"},{"line_number":992,"context_line":"        # TODO(jaypipes): Remove when all root_provider_id values are NOT NULL"},{"line_number":993,"context_line":"        if db_resource_provider[\u0027root_provider_uuid\u0027] is None:"},{"line_number":994,"context_line":"            rp_id \u003d db_resource_provider[\u0027id\u0027]"},{"line_number":995,"context_line":"            uuid \u003d db_resource_provider[\u0027uuid\u0027]"},{"line_number":996,"context_line":"            # We want the return value to have the root provider UUID even if"},{"line_number":997,"context_line":"            # we don\u0027t push it back to the database."},{"line_number":998,"context_line":"            db_resource_provider[\u0027root_provider_uuid\u0027] \u003d uuid"},{"line_number":999,"context_line":"            if do_migration:"},{"line_number":1000,"context_line":"                # Online data migration to populate root_provider_id"},{"line_number":1001,"context_line":"                _set_root_provider_id(context, rp_id, rp_id)"},{"line_number":1002,"context_line":"        for field in resource_provider.fields:"},{"line_number":1003,"context_line":"            setattr(resource_provider, field, db_resource_provider[field])"},{"line_number":1004,"context_line":"        resource_provider._context \u003d context"},{"line_number":1005,"context_line":"        resource_provider.obj_reset_changes()"},{"line_number":1006,"context_line":"        return resource_provider"},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"    @classmethod"},{"line_number":1009,"context_line":"    @db_api.api_context_manager.writer  # Needed for online data migration"},{"line_number":1010,"context_line":"    def _from_db_object(cls, context, resource_provider, db_resource_provider):"},{"line_number":1011,"context_line":"        # NOTE(efried): By default (i.e. wherever possible) we want to migrate"},{"line_number":1012,"context_line":"        # legacy records, populating null root provider ID fields, so this"},{"line_number":1013,"context_line":"        # method needs to use a writer context."},{"line_number":1014,"context_line":"        return cls._from_db_object_migration_choice("},{"line_number":1015,"context_line":"                context, resource_provider, db_resource_provider, True)"},{"line_number":1016,"context_line":""},{"line_number":1017,"context_line":"    @classmethod"},{"line_number":1018,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":1019,"context_line":"    def _from_db_object_no_migration(cls, context, resource_provider,"},{"line_number":1020,"context_line":"                                     db_resource_provider):"},{"line_number":1021,"context_line":"        # NOTE(efried): This method exists so we can look up resource provider"},{"line_number":1022,"context_line":"        # information from within a reader context without running afoul of"},{"line_number":1023,"context_line":"        # data migration."},{"line_number":1024,"context_line":"        return cls._from_db_object_migration_choice("},{"line_number":1025,"context_line":"                context, resource_provider, db_resource_provider, False)"},{"line_number":1026,"context_line":""},{"line_number":1027,"context_line":""},{"line_number":1028,"context_line":"@db_api.api_context_manager.reader"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_a8ed9626","line":1025,"range":{"start_line":769,"start_character":4,"end_line":1025,"end_character":72},"updated":"2018-05-03 21:22:08.000000000","message":"please remove these code changes. it\u0027s not germane to your patch and though I recognize it\u0027s not very palatable to ask for a writer context when we\u0027re mostly reading, the existing data migration isn\u0027t hurting anything and I\u0027d prefer to remove the writer context on the reader operations when we do the final cleanup related to online data migrations (once the data is clean).","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f89e8d657d7ef7e9254ba47d450300dc7092bf34","unresolved":false,"context_lines":[{"line_number":766,"context_line":"        self.obj_reset_changes()"},{"line_number":767,"context_line":""},{"line_number":768,"context_line":"    @classmethod"},{"line_number":769,"context_line":"    def get_by_uuid(cls, context, uuid, do_migration\u003dTrue):"},{"line_number":770,"context_line":"        \"\"\"Returns a new ResourceProvider object with the supplied UUID."},{"line_number":771,"context_line":""},{"line_number":772,"context_line":"        :raises NotFound if no such provider could be found"},{"line_number":773,"context_line":"        :param uuid: UUID of the provider to search for"},{"line_number":774,"context_line":"        :param do_migration: If True, allow data migration to be performed"},{"line_number":775,"context_line":"                (legacy records are rewritten to bring them up to the latest"},{"line_number":776,"context_line":"                database schema). This requires the caller to be in a writer"},{"line_number":777,"context_line":"                context. If False, the (correct) data is returned without"},{"line_number":778,"context_line":"                attempting data migration. This can safely be done from a"},{"line_number":779,"context_line":"                reader context."},{"line_number":780,"context_line":"        \"\"\""},{"line_number":781,"context_line":"        rp_rec \u003d _get_provider_by_uuid(context, uuid)"},{"line_number":782,"context_line":"        meth \u003d (cls._from_db_object if do_migration"},{"line_number":783,"context_line":"                else cls._from_db_object_no_migration)"},{"line_number":784,"context_line":"        return meth(context, cls(), rp_rec)"},{"line_number":785,"context_line":""},{"line_number":786,"context_line":"    def add_inventory(self, inventory):"},{"line_number":787,"context_line":"        \"\"\"Add one new Inventory to the resource provider."},{"line_number":788,"context_line":""},{"line_number":789,"context_line":"        Fails if Inventory of the provided resource class is"},{"line_number":790,"context_line":"        already present."},{"line_number":791,"context_line":"        \"\"\""},{"line_number":792,"context_line":"        _add_inventory(self._context, self, inventory)"},{"line_number":793,"context_line":"        self.obj_reset_changes()"},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"    def delete_inventory(self, resource_class):"},{"line_number":796,"context_line":"        \"\"\"Delete Inventory of provided resource_class.\"\"\""},{"line_number":797,"context_line":"        _delete_inventory(self._context, self, resource_class)"},{"line_number":798,"context_line":"        self.obj_reset_changes()"},{"line_number":799,"context_line":""},{"line_number":800,"context_line":"    def set_inventory(self, inv_list):"},{"line_number":801,"context_line":"        \"\"\"Set all resource provider Inventory to be the provided list.\"\"\""},{"line_number":802,"context_line":"        exceeded \u003d _set_inventory(self._context, self, inv_list)"},{"line_number":803,"context_line":"        for uuid, rclass in exceeded:"},{"line_number":804,"context_line":"            LOG.warning(\u0027Resource provider %(uuid)s is now over-\u0027"},{"line_number":805,"context_line":"                        \u0027capacity for %(resource)s\u0027,"},{"line_number":806,"context_line":"                        {\u0027uuid\u0027: uuid, \u0027resource\u0027: rclass})"},{"line_number":807,"context_line":"        self.obj_reset_changes()"},{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def update_inventory(self, inventory):"},{"line_number":810,"context_line":"        \"\"\"Update one existing Inventory of the same resource class."},{"line_number":811,"context_line":""},{"line_number":812,"context_line":"        Fails if no Inventory of the same class is present."},{"line_number":813,"context_line":"        \"\"\""},{"line_number":814,"context_line":"        exceeded \u003d _update_inventory(self._context, self, inventory)"},{"line_number":815,"context_line":"        for uuid, rclass in exceeded:"},{"line_number":816,"context_line":"            LOG.warning(\u0027Resource provider %(uuid)s is now over-\u0027"},{"line_number":817,"context_line":"                        \u0027capacity for %(resource)s\u0027,"},{"line_number":818,"context_line":"                        {\u0027uuid\u0027: uuid, \u0027resource\u0027: rclass})"},{"line_number":819,"context_line":"        self.obj_reset_changes()"},{"line_number":820,"context_line":""},{"line_number":821,"context_line":"    def get_aggregates(self):"},{"line_number":822,"context_line":"        \"\"\"Get the aggregate uuids associated with this resource provider.\"\"\""},{"line_number":823,"context_line":"        return _get_aggregates_by_provider_id(self._context, self.id)"},{"line_number":824,"context_line":""},{"line_number":825,"context_line":"    def set_aggregates(self, aggregate_uuids, increment_generation\u003dFalse):"},{"line_number":826,"context_line":"        \"\"\"Set the aggregate uuids associated with this resource provider."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        If an aggregate does not exist, one will be created using the"},{"line_number":829,"context_line":"        provided uuid."},{"line_number":830,"context_line":""},{"line_number":831,"context_line":"        The resource provider generation is incremented if and only if the"},{"line_number":832,"context_line":"        increment_generation parameter is True."},{"line_number":833,"context_line":"        \"\"\""},{"line_number":834,"context_line":"        _set_aggregates(self._context, self, aggregate_uuids,"},{"line_number":835,"context_line":"                        increment_generation\u003dincrement_generation)"},{"line_number":836,"context_line":""},{"line_number":837,"context_line":"    def set_traits(self, traits):"},{"line_number":838,"context_line":"        \"\"\"Replaces the set of traits associated with the resource provider"},{"line_number":839,"context_line":"        with the given list of Trait objects."},{"line_number":840,"context_line":""},{"line_number":841,"context_line":"        :param traits: A list of Trait objects representing the traits to"},{"line_number":842,"context_line":"                       associate with the provider."},{"line_number":843,"context_line":"        \"\"\""},{"line_number":844,"context_line":"        _set_traits(self._context, self, traits)"},{"line_number":845,"context_line":"        self.obj_reset_changes()"},{"line_number":846,"context_line":""},{"line_number":847,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":848,"context_line":"    def _create_in_db(self, context, updates):"},{"line_number":849,"context_line":"        parent_id \u003d None"},{"line_number":850,"context_line":"        root_id \u003d None"},{"line_number":851,"context_line":"        # User supplied a parent, let\u0027s make sure it exists"},{"line_number":852,"context_line":"        parent_uuid \u003d updates.pop(\u0027parent_provider_uuid\u0027)"},{"line_number":853,"context_line":"        if parent_uuid is not None:"},{"line_number":854,"context_line":"            # Setting parent to ourselves doesn\u0027t make any sense"},{"line_number":855,"context_line":"            if parent_uuid \u003d\u003d self.uuid:"},{"line_number":856,"context_line":"                raise exception.ObjectActionError("},{"line_number":857,"context_line":"                        action\u003d\u0027create\u0027,"},{"line_number":858,"context_line":"                        reason\u003d_(\u0027parent provider UUID cannot be same as \u0027"},{"line_number":859,"context_line":"                                 \u0027UUID. Please set parent provider UUID to \u0027"},{"line_number":860,"context_line":"                                 \u0027None if there is no parent.\u0027))"},{"line_number":861,"context_line":""},{"line_number":862,"context_line":"            parent_ids \u003d _provider_ids_from_uuid(context, parent_uuid)"},{"line_number":863,"context_line":"            if parent_ids is None:"},{"line_number":864,"context_line":"                raise exception.ObjectActionError("},{"line_number":865,"context_line":"                        action\u003d\u0027create\u0027,"},{"line_number":866,"context_line":"                        reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":867,"context_line":""},{"line_number":868,"context_line":"            parent_id \u003d parent_ids.id"},{"line_number":869,"context_line":"            root_id \u003d parent_ids.root_id"},{"line_number":870,"context_line":"            updates[\u0027root_provider_id\u0027] \u003d root_id"},{"line_number":871,"context_line":"            updates[\u0027parent_provider_id\u0027] \u003d parent_id"},{"line_number":872,"context_line":"            self.root_provider_uuid \u003d parent_ids.root_uuid"},{"line_number":873,"context_line":""},{"line_number":874,"context_line":"        db_rp \u003d models.ResourceProvider()"},{"line_number":875,"context_line":"        db_rp.update(updates)"},{"line_number":876,"context_line":"        context.session.add(db_rp)"},{"line_number":877,"context_line":"        context.session.flush()"},{"line_number":878,"context_line":""},{"line_number":879,"context_line":"        self.id \u003d db_rp.id"},{"line_number":880,"context_line":"        self.generation \u003d db_rp.generation"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"        if root_id is None:"},{"line_number":883,"context_line":"            # User did not specify a parent when creating this provider, so the"},{"line_number":884,"context_line":"            # root_provider_id needs to be set to this provider\u0027s newly-created"},{"line_number":885,"context_line":"            # internal ID"},{"line_number":886,"context_line":"            db_rp.root_provider_id \u003d db_rp.id"},{"line_number":887,"context_line":"            context.session.add(db_rp)"},{"line_number":888,"context_line":"            context.session.flush()"},{"line_number":889,"context_line":"            self.root_provider_uuid \u003d self.uuid"},{"line_number":890,"context_line":""},{"line_number":891,"context_line":"    @staticmethod"},{"line_number":892,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":893,"context_line":"    def _delete(context, _id):"},{"line_number":894,"context_line":"        # Do a quick check to see if the provider is a parent. If it is, don\u0027t"},{"line_number":895,"context_line":"        # allow deleting the provider. Note that the foreign key constraint on"},{"line_number":896,"context_line":"        # resource_providers.parent_provider_id will prevent deletion of the"},{"line_number":897,"context_line":"        # parent within the transaction below. This is just a quick"},{"line_number":898,"context_line":"        # short-circuit outside of the transaction boundary."},{"line_number":899,"context_line":"        if _has_child_providers(context, _id):"},{"line_number":900,"context_line":"            raise exception.CannotDeleteParentResourceProvider()"},{"line_number":901,"context_line":""},{"line_number":902,"context_line":"        # Don\u0027t delete the resource provider if it has allocations."},{"line_number":903,"context_line":"        rp_allocations \u003d context.session.query(models.Allocation).\\"},{"line_number":904,"context_line":"             filter(models.Allocation.resource_provider_id \u003d\u003d _id).\\"},{"line_number":905,"context_line":"             count()"},{"line_number":906,"context_line":"        if rp_allocations:"},{"line_number":907,"context_line":"            raise exception.ResourceProviderInUse()"},{"line_number":908,"context_line":"        # Delete any inventory associated with the resource provider"},{"line_number":909,"context_line":"        context.session.query(models.Inventory).\\"},{"line_number":910,"context_line":"            filter(models.Inventory.resource_provider_id \u003d\u003d _id).\\"},{"line_number":911,"context_line":"            delete(synchronize_session\u003dFalse)"},{"line_number":912,"context_line":"        # Delete any aggregate associations for the resource provider"},{"line_number":913,"context_line":"        # The name substitution on the next line is needed to satisfy pep8"},{"line_number":914,"context_line":"        RPA_model \u003d models.ResourceProviderAggregate"},{"line_number":915,"context_line":"        context.session.query(RPA_model).\\"},{"line_number":916,"context_line":"                filter(RPA_model.resource_provider_id \u003d\u003d _id).delete()"},{"line_number":917,"context_line":"        # delete any trait associations for the resource provider"},{"line_number":918,"context_line":"        RPT_model \u003d models.ResourceProviderTrait"},{"line_number":919,"context_line":"        context.session.query(RPT_model).\\"},{"line_number":920,"context_line":"                filter(RPT_model.resource_provider_id \u003d\u003d _id).delete()"},{"line_number":921,"context_line":"        # set root_provider_id to null to make deletion possible"},{"line_number":922,"context_line":"        context.session.query(models.ResourceProvider).\\"},{"line_number":923,"context_line":"            filter(models.ResourceProvider.id \u003d\u003d _id,"},{"line_number":924,"context_line":"                   models.ResourceProvider.root_provider_id \u003d\u003d _id).\\"},{"line_number":925,"context_line":"            update({\u0027root_provider_id\u0027: None})"},{"line_number":926,"context_line":"        # Now delete the RP record"},{"line_number":927,"context_line":"        try:"},{"line_number":928,"context_line":"            result \u003d _delete_rp_record(context, _id)"},{"line_number":929,"context_line":"        except sqla_exc.IntegrityError:"},{"line_number":930,"context_line":"            # NOTE(jaypipes): Another thread snuck in and parented this"},{"line_number":931,"context_line":"            # resource provider in between the above check for"},{"line_number":932,"context_line":"            # _has_child_providers() and our attempt to delete the record"},{"line_number":933,"context_line":"            raise exception.CannotDeleteParentResourceProvider()"},{"line_number":934,"context_line":"        if not result:"},{"line_number":935,"context_line":"            raise exception.NotFound()"},{"line_number":936,"context_line":""},{"line_number":937,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":938,"context_line":"    def _update_in_db(self, context, id, updates):"},{"line_number":939,"context_line":"        if \u0027parent_provider_uuid\u0027 in updates:"},{"line_number":940,"context_line":"            # TODO(jaypipes): For now, \"re-parenting\" and \"un-parenting\" are"},{"line_number":941,"context_line":"            # not possible. If the provider already had a parent, we don\u0027t"},{"line_number":942,"context_line":"            # allow changing that parent due to various issues, including:"},{"line_number":943,"context_line":"            #"},{"line_number":944,"context_line":"            # * if the new parent is a descendant of this resource provider, we"},{"line_number":945,"context_line":"            #   introduce the possibility of a loop in the graph, which would"},{"line_number":946,"context_line":"            #   be very bad"},{"line_number":947,"context_line":"            # * potentially orphaning heretofore-descendants"},{"line_number":948,"context_line":"            #"},{"line_number":949,"context_line":"            # So, for now, let\u0027s just prevent re-parenting..."},{"line_number":950,"context_line":"            my_ids \u003d _provider_ids_from_uuid(context, self.uuid)"},{"line_number":951,"context_line":"            parent_uuid \u003d updates.pop(\u0027parent_provider_uuid\u0027)"},{"line_number":952,"context_line":"            if parent_uuid is not None:"},{"line_number":953,"context_line":"                parent_ids \u003d _provider_ids_from_uuid(context, parent_uuid)"},{"line_number":954,"context_line":"                # User supplied a parent, let\u0027s make sure it exists"},{"line_number":955,"context_line":"                if parent_ids is None:"},{"line_number":956,"context_line":"                    raise exception.ObjectActionError("},{"line_number":957,"context_line":"                            action\u003d\u0027create\u0027,"},{"line_number":958,"context_line":"                            reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":959,"context_line":"                if (my_ids.parent_id is not None and"},{"line_number":960,"context_line":"                        my_ids.parent_id !\u003d parent_ids.id):"},{"line_number":961,"context_line":"                    raise exception.ObjectActionError("},{"line_number":962,"context_line":"                            action\u003d\u0027update\u0027,"},{"line_number":963,"context_line":"                            reason\u003d_(\u0027re-parenting a provider is not \u0027"},{"line_number":964,"context_line":"                                     \u0027currently allowed.\u0027))"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"                updates[\u0027root_provider_id\u0027] \u003d parent_ids.root_id"},{"line_number":967,"context_line":"                updates[\u0027parent_provider_id\u0027] \u003d parent_ids.id"},{"line_number":968,"context_line":"                self.root_provider_uuid \u003d parent_ids.root_uuid"},{"line_number":969,"context_line":"            else:"},{"line_number":970,"context_line":"                if my_ids.parent_id is not None:"},{"line_number":971,"context_line":"                    raise exception.ObjectActionError("},{"line_number":972,"context_line":"                            action\u003d\u0027update\u0027,"},{"line_number":973,"context_line":"                            reason\u003d_(\u0027un-parenting a provider is not \u0027"},{"line_number":974,"context_line":"                                     \u0027currently allowed.\u0027))"},{"line_number":975,"context_line":""},{"line_number":976,"context_line":"        db_rp \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":977,"context_line":"            id\u003did).first()"},{"line_number":978,"context_line":"        db_rp.update(updates)"},{"line_number":979,"context_line":"        try:"},{"line_number":980,"context_line":"            db_rp.save(context.session)"},{"line_number":981,"context_line":"        except sqla_exc.IntegrityError:"},{"line_number":982,"context_line":"            # NOTE(jaypipes): Another thread snuck in and deleted the parent"},{"line_number":983,"context_line":"            # for this resource provider in between the above check for a valid"},{"line_number":984,"context_line":"            # parent provider and here..."},{"line_number":985,"context_line":"            raise exception.ObjectActionError("},{"line_number":986,"context_line":"                    action\u003d\u0027update\u0027,"},{"line_number":987,"context_line":"                    reason\u003d_(\u0027parent provider UUID does not exist.\u0027))"},{"line_number":988,"context_line":""},{"line_number":989,"context_line":"    @staticmethod"},{"line_number":990,"context_line":"    def _from_db_object_migration_choice(context, resource_provider,"},{"line_number":991,"context_line":"                                         db_resource_provider, do_migration):"},{"line_number":992,"context_line":"        # TODO(jaypipes): Remove when all root_provider_id values are NOT NULL"},{"line_number":993,"context_line":"        if db_resource_provider[\u0027root_provider_uuid\u0027] is None:"},{"line_number":994,"context_line":"            rp_id \u003d db_resource_provider[\u0027id\u0027]"},{"line_number":995,"context_line":"            uuid \u003d db_resource_provider[\u0027uuid\u0027]"},{"line_number":996,"context_line":"            # We want the return value to have the root provider UUID even if"},{"line_number":997,"context_line":"            # we don\u0027t push it back to the database."},{"line_number":998,"context_line":"            db_resource_provider[\u0027root_provider_uuid\u0027] \u003d uuid"},{"line_number":999,"context_line":"            if do_migration:"},{"line_number":1000,"context_line":"                # Online data migration to populate root_provider_id"},{"line_number":1001,"context_line":"                _set_root_provider_id(context, rp_id, rp_id)"},{"line_number":1002,"context_line":"        for field in resource_provider.fields:"},{"line_number":1003,"context_line":"            setattr(resource_provider, field, db_resource_provider[field])"},{"line_number":1004,"context_line":"        resource_provider._context \u003d context"},{"line_number":1005,"context_line":"        resource_provider.obj_reset_changes()"},{"line_number":1006,"context_line":"        return resource_provider"},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"    @classmethod"},{"line_number":1009,"context_line":"    @db_api.api_context_manager.writer  # Needed for online data migration"},{"line_number":1010,"context_line":"    def _from_db_object(cls, context, resource_provider, db_resource_provider):"},{"line_number":1011,"context_line":"        # NOTE(efried): By default (i.e. wherever possible) we want to migrate"},{"line_number":1012,"context_line":"        # legacy records, populating null root provider ID fields, so this"},{"line_number":1013,"context_line":"        # method needs to use a writer context."},{"line_number":1014,"context_line":"        return cls._from_db_object_migration_choice("},{"line_number":1015,"context_line":"                context, resource_provider, db_resource_provider, True)"},{"line_number":1016,"context_line":""},{"line_number":1017,"context_line":"    @classmethod"},{"line_number":1018,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":1019,"context_line":"    def _from_db_object_no_migration(cls, context, resource_provider,"},{"line_number":1020,"context_line":"                                     db_resource_provider):"},{"line_number":1021,"context_line":"        # NOTE(efried): This method exists so we can look up resource provider"},{"line_number":1022,"context_line":"        # information from within a reader context without running afoul of"},{"line_number":1023,"context_line":"        # data migration."},{"line_number":1024,"context_line":"        return cls._from_db_object_migration_choice("},{"line_number":1025,"context_line":"                context, resource_provider, db_resource_provider, False)"},{"line_number":1026,"context_line":""},{"line_number":1027,"context_line":""},{"line_number":1028,"context_line":"@db_api.api_context_manager.reader"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_628ea879","line":1025,"range":{"start_line":769,"start_character":4,"end_line":1025,"end_character":72},"in_reply_to":"5f7c97a3_a8ed9626","updated":"2018-05-04 16:04:17.000000000","message":"Done","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a88fb5dcc330d604670820cc4b52e4dba676dc14","unresolved":false,"context_lines":[{"line_number":2722,"context_line":"class AllocationRequest(base.VersionedObject):"},{"line_number":2723,"context_line":""},{"line_number":2724,"context_line":"    fields \u003d {"},{"line_number":2725,"context_line":"        # UUID of (the root of the tree including) the non-sharing resource"},{"line_number":2726,"context_line":"        # provider associated with this AllocationRequest. Internal use only,"},{"line_number":2727,"context_line":"        # not included when the object is serialized for output."},{"line_number":2728,"context_line":"        \u0027anchor_root_provider_uuid\u0027: fields.UUIDField(),"},{"line_number":2729,"context_line":"        # Whether all AllocationRequestResources in this AllocationRequest are"},{"line_number":2730,"context_line":"        # required to be satisfied by the same provider (based on the"},{"line_number":2731,"context_line":"        # corresponding RequestGroup\u0027s use_same_provider attribute). Internal"},{"line_number":2732,"context_line":"        # use only, not included when the object is serialized for output."},{"line_number":2733,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(),"},{"line_number":2734,"context_line":"        \u0027resource_requests\u0027: fields.ListOfObjectsField("},{"line_number":2735,"context_line":"            \u0027AllocationRequestResource\u0027"},{"line_number":2736,"context_line":"        ),"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_a87a7685","line":2733,"range":{"start_line":2725,"start_character":0,"end_line":2733,"end_character":51},"updated":"2018-05-03 21:22:08.000000000","message":"Something feels a bit weird putting internal logic/switch fields like this into an object definition that gets returned to callers of AllocationCandidates.get_by_requests().\n\nAlso, if use_same_provider is the same attribute as that from the RequestGroup, why aren\u0027t we simply passing the RequestGroup object to the merging functions and reference this attribute from there?","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f89e8d657d7ef7e9254ba47d450300dc7092bf34","unresolved":false,"context_lines":[{"line_number":2722,"context_line":"class AllocationRequest(base.VersionedObject):"},{"line_number":2723,"context_line":""},{"line_number":2724,"context_line":"    fields \u003d {"},{"line_number":2725,"context_line":"        # UUID of (the root of the tree including) the non-sharing resource"},{"line_number":2726,"context_line":"        # provider associated with this AllocationRequest. Internal use only,"},{"line_number":2727,"context_line":"        # not included when the object is serialized for output."},{"line_number":2728,"context_line":"        \u0027anchor_root_provider_uuid\u0027: fields.UUIDField(),"},{"line_number":2729,"context_line":"        # Whether all AllocationRequestResources in this AllocationRequest are"},{"line_number":2730,"context_line":"        # required to be satisfied by the same provider (based on the"},{"line_number":2731,"context_line":"        # corresponding RequestGroup\u0027s use_same_provider attribute). Internal"},{"line_number":2732,"context_line":"        # use only, not included when the object is serialized for output."},{"line_number":2733,"context_line":"        \u0027use_same_provider\u0027: fields.BooleanField(),"},{"line_number":2734,"context_line":"        \u0027resource_requests\u0027: fields.ListOfObjectsField("},{"line_number":2735,"context_line":"            \u0027AllocationRequestResource\u0027"},{"line_number":2736,"context_line":"        ),"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_22d7504e","line":2733,"range":{"start_line":2725,"start_character":0,"end_line":2733,"end_character":51},"in_reply_to":"5f7c97a3_a87a7685","updated":"2018-05-04 16:04:17.000000000","message":"I did start there, but a) we have to correlate the RequestGroup with its AllocationRequest, which is awkward (dict? [named]tuple?); and b) I found myself having to pass it through many layers of method calls, which seemed really ugly.  This let me change one LOC in two places.","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a88fb5dcc330d604670820cc4b52e4dba676dc14","unresolved":false,"context_lines":[{"line_number":2744,"context_line":"        \u0027resource_class\u0027: rc_fields.ResourceClassField(read_only\u003dTrue),"},{"line_number":2745,"context_line":"        \u0027capacity\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2746,"context_line":"        \u0027used\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2747,"context_line":"        # Internal use only; not included when the object is serialized for"},{"line_number":2748,"context_line":"        # output."},{"line_number":2749,"context_line":"        \u0027max_unit\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2750,"context_line":"    }"},{"line_number":2751,"context_line":""},{"line_number":2752,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_c8b7b23a","line":2749,"range":{"start_line":2747,"start_character":0,"end_line":2749,"end_character":53},"updated":"2018-05-03 21:22:08.000000000","message":"Similar taste in my mouth about adding this internal field to the AllocationRequestResource object definition. This is internal information that is only used/generated in a particular iteration of merging candidate stuff. I feel like it should be either part of a different object (non-versioned) that should hold the state of placement/fitness decisions that are being made in the merge candidates iterations...","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"ba2420bfda78a564d139209003628ac08cc68fcb","unresolved":false,"context_lines":[{"line_number":2744,"context_line":"        \u0027resource_class\u0027: rc_fields.ResourceClassField(read_only\u003dTrue),"},{"line_number":2745,"context_line":"        \u0027capacity\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2746,"context_line":"        \u0027used\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2747,"context_line":"        # Internal use only; not included when the object is serialized for"},{"line_number":2748,"context_line":"        # output."},{"line_number":2749,"context_line":"        \u0027max_unit\u0027: fields.NonNegativeIntegerField(),"},{"line_number":2750,"context_line":"    }"},{"line_number":2751,"context_line":""},{"line_number":2752,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_2d52e114","line":2749,"range":{"start_line":2747,"start_character":0,"end_line":2749,"end_character":53},"in_reply_to":"5f7c97a3_c8b7b23a","updated":"2018-05-04 16:48:23.000000000","message":"This one I did because the alternative was going back to the database from _exceeds_capacity.  Which I could do, but it seemed wasteful given that we had already gone there to build the rest of this stuff.\n\nAnother possibility is for ProviderSummaryResource to contain the Inventory object.  Then `capacity` would be a @property that calculates on the fly from that Inventory; and I could access `max_unit` directly from the Inventory when I need it.","commit_id":"acebc3f588b5f0dfa84027c9631c809f3d72e49e"}]}
