)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8005d5196e37d3fd4667eca811dfdf939f41c240","unresolved":false,"context_lines":[{"line_number":11,"context_line":"expanded as these things are actually used."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"An inventory can be created, updated and retrieved by id or by"},{"line_number":14,"context_line":"resource provider uuid."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"A resource provider can be created and retrieved by uuid."},{"line_number":17,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":25,"id":"bae84128_187b6e29","line":14,"updated":"2016-02-23 15:21:19.000000000","message":"See below. An inventory record will never actually be retrieved via its id. id is a surrogate PK.","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8005d5196e37d3fd4667eca811dfdf939f41c240","unresolved":false,"context_lines":[{"line_number":19,"context_line":"mixin."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Tests are mixed between unit and functional. The functional tests"},{"line_number":22,"context_line":"explore the arc of an expected task."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"Co-Authored-By: Dan Smith \u003cdansmith@redhat.com\u003e"},{"line_number":25,"context_line":"Partially-Implements: blueprint resource-providers"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":25,"id":"bae84128_78743a35","line":22,"updated":"2016-02-23 15:21:19.000000000","message":"ooh, how fancy :)","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    @base.remotable_classmethod"},{"line_number":52,"context_line":"    def get_by_id(cls, context, id):"},{"line_number":53,"context_line":"        db_resource_provider \u003d cls._get_by_id_from_db(id)"},{"line_number":54,"context_line":"        return cls._from_db_object(context, cls(), db_resource_provider)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    @base.remotable_classmethod"},{"line_number":57,"context_line":"    def get_by_uuid(cls, context, uuid):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_f23e7a28","line":54,"updated":"2016-02-09 12:22:56.000000000","message":"Nobody is going to be looking up a resource provider via the integer ID, so let\u0027s just get rid of this method. Further still, it\u0027s questionable that anyone will be asking for the ResourceProvider object at all. The ComputeNode and ResourcePool objects are the concrete objects that people will be asking for. The resource_providers table is literally just a polymorphic base inheritance table that isn\u0027t accessed directly (only through DB joins). So, really, we can and should get rid of this object entirely IMHO.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"655e695b2b5b420f23f8b9e8d0274627f05a9a5c","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    @base.remotable_classmethod"},{"line_number":52,"context_line":"    def get_by_id(cls, context, id):"},{"line_number":53,"context_line":"        db_resource_provider \u003d cls._get_by_id_from_db(id)"},{"line_number":54,"context_line":"        return cls._from_db_object(context, cls(), db_resource_provider)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    @base.remotable_classmethod"},{"line_number":57,"context_line":"    def get_by_uuid(cls, context, uuid):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_b8da2116","line":54,"updated":"2016-02-09 12:56:55.000000000","message":"This actually helps clear up a lot of the confusion when putting this together. The spec says: \"Create the new `nova.objects` models for `ResourceProvider`, `InventoryItem`, and `AllocationItem`\" and it was a bit of grind to figure out the interface for the ResourceProvider itself. If we kill that off it makes things a lot more smooth.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _create_in_db(context, updates):"},{"line_number":63,"context_line":"        db_rp \u003d models.ResourceProvider()"},{"line_number":64,"context_line":"        if \u0027uuid\u0027 not in updates:"},{"line_number":65,"context_line":"            updates[\u0027uuid\u0027] \u003d uuidutils.generate_uuid()"},{"line_number":66,"context_line":"        db_rp.update(updates)"},{"line_number":67,"context_line":"        session \u003d api.get_session()"},{"line_number":68,"context_line":"        with session.begin():"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_123c762e","line":65,"updated":"2016-02-09 12:22:56.000000000","message":"Under no circumstances should a resource_provider.uuid be generated. The uuid column will *always* be the compute_nodes.uuid or the resource_pools.uuid column.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c32797c8448a0314bd45aa2dc4538106820081f9","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def _create_in_db(context, updates):"},{"line_number":63,"context_line":"        db_rp \u003d models.ResourceProvider()"},{"line_number":64,"context_line":"        if \u0027uuid\u0027 not in updates:"},{"line_number":65,"context_line":"            updates[\u0027uuid\u0027] \u003d uuidutils.generate_uuid()"},{"line_number":66,"context_line":"        db_rp.update(updates)"},{"line_number":67,"context_line":"        session \u003d api.get_session()"},{"line_number":68,"context_line":"        with session.begin():"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_c6c4d760","line":65,"in_reply_to":"5a5ae5dd_123c762e","updated":"2016-02-09 15:03:39.000000000","message":"Yep, you\u0027re right, this is my fault sorry. I was on autopilot.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        \u0027allocation_ratio\u0027: fields.FloatField(),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"},{"line_number":100,"context_line":"    def _from_db_object(context, inventory, db_inventory):"},{"line_number":101,"context_line":"        for field in inventory.fields:"},{"line_number":102,"context_line":"            if field not in (\u0027resource_provider\u0027, \u0027resource_class\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_b24802ce","line":99,"updated":"2016-02-09 12:22:56.000000000","message":"Please make this a @classmethod and do not pass in an inventory object. Should be:\n\n @classmethod\n def _from_db_object(cls, context, db_inventory):\n     inv \u003d cls()\n     for field in cls.fields:\n         if field not in (\u0027resource_provider\u0027, \u0027resource_class\u0027):\n             setattr(inv, field, db_inventory[field])\n     \n     res_class_field \u003d cls.fields[\u0027resource_class\u0027]\n     inv.resource_class \u003d res_class_field.from_index(db_inventory[\u0027resource_class_id\u0027])\n     inv.resource_provider \u003d db_inventory[\u0027resource_provider_id\u0027]\n     inv._context \u003d context\n     inv.obj_reset_changes()\n     return inv","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c32797c8448a0314bd45aa2dc4538106820081f9","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        \u0027allocation_ratio\u0027: fields.FloatField(),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    @staticmethod"},{"line_number":100,"context_line":"    def _from_db_object(context, inventory, db_inventory):"},{"line_number":101,"context_line":"        for field in inventory.fields:"},{"line_number":102,"context_line":"            if field not in (\u0027resource_provider\u0027, \u0027resource_class\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_06c74f46","line":99,"in_reply_to":"5a5ae5dd_b24802ce","updated":"2016-02-09 15:03:39.000000000","message":"All of our _from_db_object() methods are staticmethod and follow this pattern. We can\u0027t make it a classmethod and create a new class if we are going to use it to refresh the object, which is how it works in every other place.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        if \u0027resource_class\u0027 not in inventory:"},{"line_number":106,"context_line":"            inventory.resource_class \u003d ("},{"line_number":107,"context_line":"                inventory.fields[\u0027resource_class\u0027].from_index("},{"line_number":108,"context_line":"                    db_inventory[\u0027resource_class_id\u0027]))"},{"line_number":109,"context_line":"        if (\u0027resource_provider\u0027 not in inventory and"},{"line_number":110,"context_line":"            \u0027resource_provider\u0027 in db_inventory):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_d2457eb3","line":107,"updated":"2016-02-09 12:22:56.000000000","message":"good.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":108,"context_line":"                    db_inventory[\u0027resource_class_id\u0027]))"},{"line_number":109,"context_line":"        if (\u0027resource_provider\u0027 not in inventory and"},{"line_number":110,"context_line":"            \u0027resource_provider\u0027 in db_inventory):"},{"line_number":111,"context_line":"            inventory.resource_provider \u003d ResourceProvider()"},{"line_number":112,"context_line":"            ResourceProvider._from_db_object("},{"line_number":113,"context_line":"                context,"},{"line_number":114,"context_line":"                inventory.resource_provider,"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_72112aaf","line":111,"updated":"2016-02-09 12:22:56.000000000","message":"Here, just store the integer resource provider ID. There is no reason to have a ResourceProvider object class as explained above.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c32797c8448a0314bd45aa2dc4538106820081f9","unresolved":false,"context_lines":[{"line_number":108,"context_line":"                    db_inventory[\u0027resource_class_id\u0027]))"},{"line_number":109,"context_line":"        if (\u0027resource_provider\u0027 not in inventory and"},{"line_number":110,"context_line":"            \u0027resource_provider\u0027 in db_inventory):"},{"line_number":111,"context_line":"            inventory.resource_provider \u003d ResourceProvider()"},{"line_number":112,"context_line":"            ResourceProvider._from_db_object("},{"line_number":113,"context_line":"                context,"},{"line_number":114,"context_line":"                inventory.resource_provider,"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_46022771","line":111,"in_reply_to":"5a5ae5dd_72112aaf","updated":"2016-02-09 15:03:39.000000000","message":"Why? How else are we going to get the uuid of a provider for an allocation?","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":121,"context_line":"    @staticmethod"},{"line_number":122,"context_line":"    def _create_in_db(context, updates):"},{"line_number":123,"context_line":"        db_inventory \u003d models.Inventory()"},{"line_number":124,"context_line":"        db_inventory.update(updates)"},{"line_number":125,"context_line":"        session \u003d api.get_session()"},{"line_number":126,"context_line":"        with session.begin():"},{"line_number":127,"context_line":"            session.add(db_inventory)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_921626a6","line":124,"updated":"2016-02-09 12:22:56.000000000","message":"updates should likely include a \u0027resource_provider_uuid\u0027 column, set to the compute node or resource pool\u0027s UUID value. This method here needs to look up the integer key in resource_providers table for that corresponding UUID and create a record in the resource_providers table if no such UUID exists.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2c02785416050aa314dc4bee6a616f8ff3c87c2","unresolved":false,"context_lines":[{"line_number":121,"context_line":"    @staticmethod"},{"line_number":122,"context_line":"    def _create_in_db(context, updates):"},{"line_number":123,"context_line":"        db_inventory \u003d models.Inventory()"},{"line_number":124,"context_line":"        db_inventory.update(updates)"},{"line_number":125,"context_line":"        session \u003d api.get_session()"},{"line_number":126,"context_line":"        with session.begin():"},{"line_number":127,"context_line":"            session.add(db_inventory)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_812a497d","line":124,"in_reply_to":"5a5ae5dd_921626a6","updated":"2016-02-09 15:09:19.000000000","message":"This is handled through the relationship on the SQLA object. When we create this, we do specify a uuid of the resource provider that way.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":151,"context_line":"                reason\u003d\u0027Inventory requires resource_class\u0027)"},{"line_number":152,"context_line":"        updates[\u0027resource_provider_id\u0027] \u003d resource_provider.id"},{"line_number":153,"context_line":"        updates[\u0027resource_class_id\u0027] \u003d \\"},{"line_number":154,"context_line":"                Inventory.fields[\u0027resource_class\u0027].index(resource_class)"},{"line_number":155,"context_line":"        return updates"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_320bb27f","line":154,"updated":"2016-02-09 12:22:56.000000000","message":"No, you need to just pop the resource_provider and resource_class fields from updates and not add the IDs into the updates dict. Those fields should never change.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2c02785416050aa314dc4bee6a616f8ff3c87c2","unresolved":false,"context_lines":[{"line_number":151,"context_line":"                reason\u003d\u0027Inventory requires resource_class\u0027)"},{"line_number":152,"context_line":"        updates[\u0027resource_provider_id\u0027] \u003d resource_provider.id"},{"line_number":153,"context_line":"        updates[\u0027resource_class_id\u0027] \u003d \\"},{"line_number":154,"context_line":"                Inventory.fields[\u0027resource_class\u0027].index(resource_class)"},{"line_number":155,"context_line":"        return updates"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_c147e149","line":154,"in_reply_to":"5a5ae5dd_320bb27f","updated":"2016-02-09 15:09:19.000000000","message":"We\u0027re not updating the ids, we\u0027re using them to handle the relationship on the SQLA object.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":158,"context_line":"    def _get_by_id(context, id_):"},{"line_number":159,"context_line":"        session \u003d api.get_session()"},{"line_number":160,"context_line":"        return session.query(models.Inventory).\\"},{"line_number":161,"context_line":"            options(joinedload(\u0027resource_provider\u0027)).\\"},{"line_number":162,"context_line":"            filter_by(id\u003did_).first()"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_5210aea8","line":161,"updated":"2016-02-09 12:22:56.000000000","message":"There is no reason to join on resource_providers here.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2c02785416050aa314dc4bee6a616f8ff3c87c2","unresolved":false,"context_lines":[{"line_number":158,"context_line":"    def _get_by_id(context, id_):"},{"line_number":159,"context_line":"        session \u003d api.get_session()"},{"line_number":160,"context_line":"        return session.query(models.Inventory).\\"},{"line_number":161,"context_line":"            options(joinedload(\u0027resource_provider\u0027)).\\"},{"line_number":162,"context_line":"            filter_by(id\u003did_).first()"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_e1677de8","line":161,"in_reply_to":"5a5ae5dd_5210aea8","updated":"2016-02-09 15:09:19.000000000","message":"There is, for the relationship. See above.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e6bfe88fbaa35c7645b56509362a4f495cf748b3","unresolved":false,"context_lines":[{"line_number":198,"context_line":"        \u0027used\u0027: fields.IntegerField(),"},{"line_number":199,"context_line":"    }"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def _from_db_object(context, allocation, db_allocation):"},{"line_number":202,"context_line":"        for field in allocation.fields:"},{"line_number":203,"context_line":"            if field \u003d\u003d \u0027resource_provider\u0027:"},{"line_number":204,"context_line":"                allocation.resource_provider \u003d ResourceProvider()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_f2251a0a","line":201,"updated":"2016-02-09 12:22:56.000000000","message":"Needs to be @classmethod. See comment above in Inventory._from_db_object()","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2c02785416050aa314dc4bee6a616f8ff3c87c2","unresolved":false,"context_lines":[{"line_number":198,"context_line":"        \u0027used\u0027: fields.IntegerField(),"},{"line_number":199,"context_line":"    }"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def _from_db_object(context, allocation, db_allocation):"},{"line_number":202,"context_line":"        for field in allocation.fields:"},{"line_number":203,"context_line":"            if field \u003d\u003d \u0027resource_provider\u0027:"},{"line_number":204,"context_line":"                allocation.resource_provider \u003d ResourceProvider()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5ae5dd_619aadc7","line":201,"in_reply_to":"5a5ae5dd_f2251a0a","updated":"2016-02-09 15:09:19.000000000","message":"Again, no, per above.","commit_id":"8e275cd7678f30dc6cd658e8385ecfb755af4740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"class _HasAResourceProvider(object):"},{"line_number":73,"context_line":"    \"\"\"Code shared between Inventory and Allocation"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    Both contain a ResourceProvider."}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_c587d80d","line":72,"updated":"2016-02-15 19:00:00.000000000","message":"I think you should just inherit from NovaObject here and avoid the multiple inheritance for the two subclasses. Only register those and not this.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"72c310dc662a3727e86836e6a5c17377533dc6fe","unresolved":false,"context_lines":[{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"class _HasAResourceProvider(object):"},{"line_number":73,"context_line":"    \"\"\"Code shared between Inventory and Allocation"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    Both contain a ResourceProvider."}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_00cc0e88","line":72,"in_reply_to":"dae33548_c587d80d","updated":"2016-02-15 20:01:50.000000000","message":"Done","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":196,"context_line":""},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":199,"context_line":"class Allocation(base.NovaObject, _HasAResourceProvider):"},{"line_number":200,"context_line":"    # Version 1.0: Initial version"},{"line_number":201,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":202,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e5993c70","line":199,"updated":"2016-02-15 19:00:00.000000000","message":"I wonder if it\u0027s worth even landing this object until we have code above it to care?","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"72c310dc662a3727e86836e6a5c17377533dc6fe","unresolved":false,"context_lines":[{"line_number":196,"context_line":""},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":199,"context_line":"class Allocation(base.NovaObject, _HasAResourceProvider):"},{"line_number":200,"context_line":"    # Version 1.0: Initial version"},{"line_number":201,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":202,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e0abea87","line":199,"in_reply_to":"dae33548_e5993c70","updated":"2016-02-15 20:01:50.000000000","message":"I don\u0027t mind either way. As I\u0027ve said before I\u0027m just checking off the work items from the spec. Anybody else have opions?","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":221,"context_line":"    def destroy(self):"},{"line_number":222,"context_line":"        self._destroy(self._context, self.id)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    # TODO(cdent): Does this mean we need a AllocationsList object?"},{"line_number":225,"context_line":"    @base.remotable_classmethod"},{"line_number":226,"context_line":"    def get_allocations(cls, context, resource_provider, resource_class):"},{"line_number":227,"context_line":"        resource_provider_id \u003d resource_provider.id"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_05c8a054","line":224,"updated":"2016-02-15 19:00:00.000000000","message":"Maybe. That\u0027s how we\u0027ve done it in the past, but as you can see, I added a get_all*() method on the object above. I\u0027m not entirely sure whether it\u0027s worth it at this point. Maybe someone else can chime in with an opinion.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"72c310dc662a3727e86836e6a5c17377533dc6fe","unresolved":false,"context_lines":[{"line_number":221,"context_line":"    def destroy(self):"},{"line_number":222,"context_line":"        self._destroy(self._context, self.id)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    # TODO(cdent): Does this mean we need a AllocationsList object?"},{"line_number":225,"context_line":"    @base.remotable_classmethod"},{"line_number":226,"context_line":"    def get_allocations(cls, context, resource_provider, resource_class):"},{"line_number":227,"context_line":"        resource_provider_id \u003d resource_provider.id"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_2096724c","line":224,"in_reply_to":"dae33548_05c8a054","updated":"2016-02-15 20:01:50.000000000","message":"I\u0027ll leave the comment in until we get additional feedback.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0e3c95a845a78330a9256601a7ca027d828b9505","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    @staticmethod"},{"line_number":98,"context_line":"    def _from_db_object(context, target, source):"},{"line_number":99,"context_line":"        for field in target.fields:"},{"line_number":100,"context_line":"            if field not in (\u0027resource_provider\u0027, \u0027resource_class\u0027):"},{"line_number":101,"context_line":"                setattr(target, field, source[field])"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"        if \u0027resource_class\u0027 not in target:"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_d9f0a969","line":100,"updated":"2016-02-18 17:50:32.000000000","message":"Over time, the special case delta between what is in the object and what is in the DB will change, so eventually sharing this method will probably not be worth it. But, it\u0027s okay for now.","commit_id":"ed7df6815472a2c3cc6f234cbf0fcbe32cbb3b63"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0e3c95a845a78330a9256601a7ca027d828b9505","unresolved":false,"context_lines":[{"line_number":195,"context_line":"            raise exception.NotFound()"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":199,"context_line":"class Allocation(_HasAResourceProvider):"},{"line_number":200,"context_line":"    # Version 1.0: Initial version"},{"line_number":201,"context_line":"    VERSION \u003d \u00271.0\u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_f913ed62","line":198,"updated":"2016-02-18 17:50:32.000000000","message":"I think you should avoid registering this object, or remove it from this patch until we use it.","commit_id":"ed7df6815472a2c3cc6f234cbf0fcbe32cbb3b63"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5beedd1d867238c962f6fa0aee1db151e27a8e96","unresolved":false,"context_lines":[{"line_number":202,"context_line":""},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"# TODO(cdent): dansmith suggested not registering this, but so many"},{"line_number":205,"context_line":"# tests are now using it, that\u0027s rather a pain to do."},{"line_number":206,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":207,"context_line":"class Allocation(_HasAResourceProvider):"},{"line_number":208,"context_line":"    # Version 1.0: Initial version"}],"source_content_type":"text/x-python","patch_set":19,"id":"bae84128_1ee9281b","line":205,"updated":"2016-02-19 17:19:37.000000000","message":"You can\u0027t unregister this once you do, so there\u0027s no point in this TODO.\n\nIf you want to build the object but not register it, then use register_if(False). The tests (minus the remotable ones) should continue working. Also, you can register this in the setUp() of the test case and it will only be registered there, which would be an option.\n\nAlternately, you could remove this object and its tests from the patch.\n\nIf you really want to stick with it here, then I\u0027m -2 on this until we have code above to prove that this object is right, and the interface that we want for the code that\u0027s going to use it. I\u0027d rather not block on that though.","commit_id":"8c1d13a572299b14c4e633e2e185f0ee9d072346"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"24e31b830d2ba5f5a27ec4a50f38f81b6a86ad37","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        result \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":"        if not result:"},{"line_number":71,"context_line":"            raise exception.NotFound()"},{"line_number":72,"context_line":"        return result"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_dc1a1e6e","line":71,"updated":"2016-02-19 22:08:17.000000000","message":"I like the pattern of creating specific exceptions that inherit from NotFound, like ResourceProviderNotFound(NotFound). Not a big deal though.","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5a200c63f21a6876df7b2bf19dcf0812f875dc77","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        result \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":"        if not result:"},{"line_number":71,"context_line":"            raise exception.NotFound()"},{"line_number":72,"context_line":"        return result"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_60d4bc1f","line":71,"in_reply_to":"bae84128_0d3572d9","updated":"2016-02-22 16:08:54.000000000","message":"Yeah it\u0027s really a personal preference, until it\u0027s necessary. But creating specialized exceptions JIT is easy enough when that happens.","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ff4134298add01d438dffc01222cc3719fd62823","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        result \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":"        if not result:"},{"line_number":71,"context_line":"            raise exception.NotFound()"},{"line_number":72,"context_line":"        return result"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_0d3572d9","line":71,"in_reply_to":"bae84128_572b87eb","updated":"2016-02-19 23:14:24.000000000","message":"We\u0027re horribly inconsistent about those behaviors. I\u0027m fine with the exception model if you want, I just hate having to create exceptions.","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"33febb303bf6d77d4f1f36ef8ee63e2714e9edc7","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        result \u003d context.session.query(models.ResourceProvider).filter_by("},{"line_number":69,"context_line":"            uuid\u003duuid).first()"},{"line_number":70,"context_line":"        if not result:"},{"line_number":71,"context_line":"            raise exception.NotFound()"},{"line_number":72,"context_line":"        return result"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_572b87eb","line":71,"in_reply_to":"bae84128_dc1a1e6e","updated":"2016-02-19 22:31:36.000000000","message":"I wondered about that too. Initially some of the getter code as written by Dan returned None instead of doing any NotFound. That didn\u0027t seem right to me so I borrowed the  use of NotFound from one of the update methods.\n\nAs I say below, I\u0027m not clear on what the preferred interface is...","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"24e31b830d2ba5f5a27ec4a50f38f81b6a86ad37","unresolved":false,"context_lines":[{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"},{"line_number":154,"context_line":"                for db_inv in db_inventory_list]"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_bcaf5ae2","line":153,"updated":"2016-02-19 22:08:17.000000000","message":"In the past this has been handled by a *List object. Any reason that wasn\u0027t done here?","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ff4134298add01d438dffc01222cc3719fd62823","unresolved":false,"context_lines":[{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"},{"line_number":154,"context_line":"                for db_inv in db_inventory_list]"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_ed5f6e0c","line":153,"in_reply_to":"bae84128_57b6e7dc","updated":"2016-02-19 23:14:24.000000000","message":"Yeah, we have. In some cases it\u0027s pretty handy, but in others it feels like extra work. So, if you like that model and think we should do it here, I think that\u0027s fine. In fact, I should probably be less lazy and complain-y and say .. yeah we should just keep on keepin\u0027 on unless there is a compelling reason not to.","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"33febb303bf6d77d4f1f36ef8ee63e2714e9edc7","unresolved":false,"context_lines":[{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"},{"line_number":154,"context_line":"                for db_inv in db_inventory_list]"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_57b6e7dc","line":153,"in_reply_to":"bae84128_bcaf5ae2","updated":"2016-02-19 22:31:36.000000000","message":"Dan and I talked about the efficacy of list objects on (the now removed) Allocation object to list allocations and we didn\u0027t really resolve if it was necessary or not. I haven\u0027t been able to figure out what the official contract is of an object, so left the list things just as lists until we figure that out. I\u0027m hoping further comments will clarify it as it has been a question in some of the other efforts to create objects I\u0027ve been doing.","commit_id":"7445eb172fdb28f6ef9019af40ca1a67ba3a1526"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a334c639f86fe9fd57fe8c720ea356feb5aebff3","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":29,"context_line":"        \u0027uuid\u0027: fields.UUIDField(),"},{"line_number":30,"context_line":"    }"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_41ded711","line":28,"updated":"2016-02-22 18:00:52.000000000","message":"should this be read only?","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a334c639f86fe9fd57fe8c720ea356feb5aebff3","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":35,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":36,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":37,"context_line":"        if \u0027uuid\u0027 not in self:"},{"line_number":38,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":39,"context_line":"                                              reason\u003d\u0027uuid is required\u0027)"},{"line_number":40,"context_line":"        updates \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_c1cb0752","line":37,"updated":"2016-02-22 18:00:52.000000000","message":"would nullable\u003dfalse on uuid do the same thing as this?","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"69cf259bbc43a2c5460aba56240d5503b8c253cb","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":35,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":36,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":37,"context_line":"        if \u0027uuid\u0027 not in self:"},{"line_number":38,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":39,"context_line":"                                              reason\u003d\u0027uuid is required\u0027)"},{"line_number":40,"context_line":"        updates \u003d self.obj_get_changes()"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_590c073b","line":37,"in_reply_to":"bae84128_c1cb0752","updated":"2016-02-22 20:26:01.000000000","message":"Tried it, apparently not.","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"8cd5f6c50ce9e6ed7065c64ec17e766bfe65924f","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        self._from_db_object(self._context, self, db_inventory)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    @base.remotable_classmethod"},{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_807100e3","line":150,"updated":"2016-02-22 16:18:54.000000000","message":"Part of what I like about VersionedObjects is that it adds strict typing in places where it was desperately needed. Having an Inventory get method return a list rather than an inventory goes against that. However, it\u0027s clear here that it will return a list rather than an Inventory. And I\u0027m not sure an expectation has been set that get methods like this will definitely return the object versus a list.\n\nSo, I would like to see this change personally but I don\u0027t think it\u0027s a blocker.","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"1615faab8df257c7f9aeda9e95f0a4ae72b1d771","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        self._from_db_object(self._context, self, db_inventory)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    @base.remotable_classmethod"},{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_fb307dea","line":150,"in_reply_to":"bae84128_807100e3","updated":"2016-02-22 16:22:23.000000000","message":"After digesting this I think you\u0027re probably right. Let\u0027s not deviate any more in this patch and save any amount of list-object-optimization discussion for later. I\u0027ll work up a list object for this in a bit. Should be tiny.","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a334c639f86fe9fd57fe8c720ea356feb5aebff3","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        self._from_db_object(self._context, self, db_inventory)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    @base.remotable_classmethod"},{"line_number":150,"context_line":"    def get_all_by_resource_provider_uuid(cls, context, rp_uuid):"},{"line_number":151,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":152,"context_line":"                                                              rp_uuid)"},{"line_number":153,"context_line":"        return [cls._from_db_object(context, cls(), db_inv)"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_c1cf877d","line":150,"in_reply_to":"bae84128_fb307dea","updated":"2016-02-22 18:00:52.000000000","message":"+1 for list object that contains this method, for consistency.","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a334c639f86fe9fd57fe8c720ea356feb5aebff3","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027save\u0027,"},{"line_number":165,"context_line":"                                              reason\u003d\u0027not created\u0027)"},{"line_number":166,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":167,"context_line":"        updates.pop(\u0027id\u0027, None)"},{"line_number":168,"context_line":"        self._update_in_db(self._context, self.id, updates)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_a11c0314","line":167,"updated":"2016-02-22 18:00:52.000000000","message":"Nit: why do we need this when id is read_only, hmm, I must be missing something here?","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"69cf259bbc43a2c5460aba56240d5503b8c253cb","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027save\u0027,"},{"line_number":165,"context_line":"                                              reason\u003d\u0027not created\u0027)"},{"line_number":166,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":167,"context_line":"        updates.pop(\u0027id\u0027, None)"},{"line_number":168,"context_line":"        self._update_in_db(self._context, self.id, updates)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_59a887db","line":167,"in_reply_to":"bae84128_a11c0314","updated":"2016-02-22 20:26:01.000000000","message":"It doesn\u0027t work if we don\u0027t take it out, so I\u0027m guessing obj_get_changes() behaves differently than we think.","commit_id":"d7fcae3e944ec0e7289eebbba77c088ce8bbe88d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9b205c3da0a48f9e1f6700e8649c88233f768528","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    fields \u003d {"},{"line_number":29,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":30,"context_line":"        \u0027uuid\u0027: fields.UUIDField(),"},{"line_number":31,"context_line":"    }"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    @base.remotable"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_52806346","line":30,"updated":"2016-02-22 18:55:13.000000000","message":"I think this has similar issues to my comments on the last patchset.","commit_id":"168c52616d3983a763d89b27b847ea1ce3dc3181"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9b205c3da0a48f9e1f6700e8649c88233f768528","unresolved":false,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":192,"context_line":"class InventoryList(base.ObjectListBase, base.NovaObject):"},{"line_number":193,"context_line":"    # Version 1.0: Initial Version"},{"line_number":194,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":195,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_f291b79a","line":192,"updated":"2016-02-22 18:55:13.000000000","message":"this seems familiar, I like it.","commit_id":"168c52616d3983a763d89b27b847ea1ce3dc3181"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a2a9e9c6b0b264105d302eea3a4a9ed522e2b155","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"class _HasAResourceProvider(base.NovaObject):"},{"line_number":77,"context_line":"    \"\"\"Code shared between Inventory and Allocation"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    Both contain a ResourceProvider."},{"line_number":80,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_fdb31c98","line":77,"range":{"start_line":77,"start_character":27,"end_line":77,"end_character":51},"updated":"2016-02-23 15:14:34.000000000","message":"not sure it\u0027s important now to have a mixin for an object not yet provided - unless I\u0027m wrong ?","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8005d5196e37d3fd4667eca811dfdf939f41c240","unresolved":false,"context_lines":[{"line_number":150,"context_line":"    @base.remotable_classmethod"},{"line_number":151,"context_line":"    def get_by_id(cls, context, id):"},{"line_number":152,"context_line":"        db_inventory \u003d cls._get_by_id(context, id)"},{"line_number":153,"context_line":"        return cls._from_db_object(context, cls(), db_inventory)"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"    @base.remotable"},{"line_number":156,"context_line":"    def save(self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_f87faa14","line":153,"updated":"2016-02-23 15:21:19.000000000","message":"This method will never be used please remove. The inventory.id column is a surrogate primary key for performance reasons (it gets used in indexes on the inventories and allocations table instead of using a (resource_provider_id, resource_class_id) or (resource_provider_id, resource_class_id, consumer_uuid) multi-column tuple for index pointers.","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"32115c28d7ca877bacbe99892d3aa6d8602713ff","unresolved":false,"context_lines":[{"line_number":150,"context_line":"    @base.remotable_classmethod"},{"line_number":151,"context_line":"    def get_by_id(cls, context, id):"},{"line_number":152,"context_line":"        db_inventory \u003d cls._get_by_id(context, id)"},{"line_number":153,"context_line":"        return cls._from_db_object(context, cls(), db_inventory)"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"    @base.remotable"},{"line_number":156,"context_line":"    def save(self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_c472c010","line":153,"in_reply_to":"bae84128_f87faa14","updated":"2016-02-23 16:07:31.000000000","message":"Done","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8005d5196e37d3fd4667eca811dfdf939f41c240","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            filter_by(id\u003did_).first()"},{"line_number":178,"context_line":"        if not result:"},{"line_number":179,"context_line":"            raise exception.NotFound()"},{"line_number":180,"context_line":"        return result"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"    @staticmethod"},{"line_number":183,"context_line":"    @db_api.main_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_d884660c","line":180,"updated":"2016-02-23 15:21:19.000000000","message":"Please remove this.","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"32115c28d7ca877bacbe99892d3aa6d8602713ff","unresolved":false,"context_lines":[{"line_number":177,"context_line":"            filter_by(id\u003did_).first()"},{"line_number":178,"context_line":"        if not result:"},{"line_number":179,"context_line":"            raise exception.NotFound()"},{"line_number":180,"context_line":"        return result"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"    @staticmethod"},{"line_number":183,"context_line":"    @db_api.main_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_212d5efe","line":180,"in_reply_to":"bae84128_d884660c","updated":"2016-02-23 16:07:31.000000000","message":"Done","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8005d5196e37d3fd4667eca811dfdf939f41c240","unresolved":false,"context_lines":[{"line_number":209,"context_line":"        db_inventory_list \u003d cls._get_all_by_resource_provider(context,"},{"line_number":210,"context_line":"                                                              rp_uuid)"},{"line_number":211,"context_line":"        return base.obj_make_list(context, cls(context), objects.Inventory,"},{"line_number":212,"context_line":"                                  db_inventory_list)"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_387e3219","line":212,"updated":"2016-02-23 15:21:19.000000000","message":"Yes, this here is the common way that inventory records will be retrieved. I can envision in the future having a get_by_resource_class() query as well which returns all inventories of a particular type as well as get_all() which returns all inventory records in the system. What definitely will never happen is a Inventory.get_by_id() because that surrogate PK in the inventories table will never be leaked out of the DB layer.","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    def test_create_resource_provider_requires_uuid(self):"},{"line_number":45,"context_line":"        resource_provider \u003d objects.ResourceProvider("},{"line_number":46,"context_line":"            context \u003d self.context"},{"line_number":47,"context_line":"        )"},{"line_number":48,"context_line":"        self.assertRaises(exception.ObjectActionError,"},{"line_number":49,"context_line":"                          resource_provider.create)"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_45d90821","line":47,"updated":"2016-02-15 19:00:00.000000000","message":"I think the prevailing style in nova is not to leave the close paren hanging on a line by itself.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"}],"nova/tests/unit/objects/test_resource_provider.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        self.assertEqual(rp.uuid, retrieved_rp.uuid)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"class TestResourceProviderNoDB(test_objects._LocalTest,"},{"line_number":93,"context_line":"                               _TestResourceProviderNoDB):"},{"line_number":94,"context_line":"    USES_DB \u003d False"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_e50c9c96","line":92,"updated":"2016-02-15 19:00:00.000000000","message":"Can you put this above _TestResourceProvider() ? It took me a while to figure this out, visually.\n\nAlso, you need to be running the remote and local tests on the no-db class. You can skip that (IMHO) for the db-facing one and just have it inherit directly from _LocalTest.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"72c310dc662a3727e86836e6a5c17377533dc6fe","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        self.assertEqual(rp.uuid, retrieved_rp.uuid)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"class TestResourceProviderNoDB(test_objects._LocalTest,"},{"line_number":93,"context_line":"                               _TestResourceProviderNoDB):"},{"line_number":94,"context_line":"    USES_DB \u003d False"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_a0b602da","line":92,"in_reply_to":"dae33548_e50c9c96","updated":"2016-02-15 20:01:50.000000000","message":"okay.\n\nFor future reference what\u0027s the explicit guideline here? That is: What does a test have that requires it should be both local and remote?","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a25afc3e493a518e762c5ac95ba16638abac4454","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":"class TestInventoryNoDB(test_objects._LocalTest,"},{"line_number":217,"context_line":"                        _TestInventoryNoDB):"},{"line_number":218,"context_line":"    USES_DB \u003d False"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"class TestInventory(test_objects._LocalTest,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_6521acfb","line":218,"updated":"2016-02-15 19:00:00.000000000","message":"Same here.","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"72c310dc662a3727e86836e6a5c17377533dc6fe","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":"class TestInventoryNoDB(test_objects._LocalTest,"},{"line_number":217,"context_line":"                        _TestInventoryNoDB):"},{"line_number":218,"context_line":"    USES_DB \u003d False"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"class TestInventory(test_objects._LocalTest,"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_f4ce0f59","line":218,"in_reply_to":"dae33548_6521acfb","updated":"2016-02-15 20:01:50.000000000","message":"Done","commit_id":"31cec4fda87cacbf8ac2da45890cfb2efd2c09db"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a2a9e9c6b0b264105d302eea3a4a9ed522e2b155","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \u0027step_size\u0027: 1,"},{"line_number":39,"context_line":"    \u0027allocation_ratio\u0027: 1.0,"},{"line_number":40,"context_line":"}"},{"line_number":41,"context_line":"_ALLOCATION_ID \u003d 2"},{"line_number":42,"context_line":"_ALLOCATION_DB \u003d {"},{"line_number":43,"context_line":"    \u0027id\u0027: _ALLOCATION_ID,"},{"line_number":44,"context_line":"    \u0027resource_provider_id\u0027: _RESOURCE_PROVIDER_ID,"},{"line_number":45,"context_line":"    \u0027resource_class_id\u0027: _RESOURCE_CLASS_ID,"},{"line_number":46,"context_line":"    \u0027consumer_id\u0027: uuids.fake_compute_node,"},{"line_number":47,"context_line":"    \u0027used\u0027: 8,"},{"line_number":48,"context_line":"}"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class _TestResourceProviderNoDB(object):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_18124e57","line":48,"range":{"start_line":41,"start_character":0,"end_line":48,"end_character":1},"updated":"2016-02-23 15:14:34.000000000","message":"all of that is useless","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"32115c28d7ca877bacbe99892d3aa6d8602713ff","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    \u0027resource_class_id\u0027: _RESOURCE_CLASS_ID,"},{"line_number":46,"context_line":"    \u0027consumer_id\u0027: uuids.fake_compute_node,"},{"line_number":47,"context_line":"    \u0027used\u0027: 8,"},{"line_number":48,"context_line":"}"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class _TestResourceProviderNoDB(object):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bae84128_c41be0c8","line":48,"in_reply_to":"bae84128_18124e57","updated":"2016-02-23 16:07:31.000000000","message":"Done","commit_id":"222e18503a430278de97eb93c8d3e5d40db49a9a"}]}
