)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fbf4e246948538e944aa66cc28f98a2b40821adf","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add delete_, update_ and add_ inventory to ResourceProvider"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Each of these reuses the methods used by set_inventory to for"},{"line_number":10,"context_line":"deleting, updating or adding just one Inventory to a"},{"line_number":11,"context_line":"ResourceProvider."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7aa08908_2c54cbc8","line":9,"range":{"start_line":9,"start_character":55,"end_line":9,"end_character":61},"updated":"2016-06-15 18:53:54.000000000","message":"six eight?","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"cb2e97c9ef22a0af4e94f787ace53682c3fc2b4d","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add delete_, update_ and add_ inventory to ResourceProvider"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Each of these reuses the methods used by set_inventory to for"},{"line_number":10,"context_line":"deleting, updating or adding just one Inventory to a"},{"line_number":11,"context_line":"ResourceProvider."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7aa08908_80948244","line":9,"in_reply_to":"7aa08908_2c54cbc8","updated":"2016-06-16 10:41:47.000000000","message":"We appreciate Dan for reviewing?","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"ece478485f7fed925cb39fb3bc0b85e25bd1573a","unresolved":false,"context_lines":[{"line_number":76,"context_line":"            _INV_TBL.c.resource_provider_id \u003d\u003d rp.id,"},{"line_number":77,"context_line":"            _INV_TBL.c.resource_class_id.in_(to_delete)))"},{"line_number":78,"context_line":"    res \u003d conn.execute(del_stmt)"},{"line_number":79,"context_line":"    return res.rowcount"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def _add_inventory_to_provider(conn, rp, inv_list, to_add):"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_4950b4d4","line":79,"updated":"2016-06-13 13:46:22.000000000","message":"Why would a delete ever return any records?","commit_id":"38a6fba131850acb44aae6411137497e9e6038ee"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"3cbec945d472d87c6a85ce05cd3b4fc9cfeb70b3","unresolved":false,"context_lines":[{"line_number":76,"context_line":"            _INV_TBL.c.resource_provider_id \u003d\u003d rp.id,"},{"line_number":77,"context_line":"            _INV_TBL.c.resource_class_id.in_(to_delete)))"},{"line_number":78,"context_line":"    res \u003d conn.execute(del_stmt)"},{"line_number":79,"context_line":"    return res.rowcount"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def _add_inventory_to_provider(conn, rp, inv_list, to_add):"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_e2e535a4","line":79,"in_reply_to":"7aa08908_4950b4d4","updated":"2016-06-13 14:03:34.000000000","message":"rowcount, when doing a delete, is the number of rows matched by the where clause in the delete\n\nWe want this count so we can know if any deleting actually happened and raise a NotFound if that was the case.","commit_id":"38a6fba131850acb44aae6411137497e9e6038ee"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"ece478485f7fed925cb39fb3bc0b85e25bd1573a","unresolved":false,"context_lines":[{"line_number":169,"context_line":"            raise exception.ConcurrentUpdateDetected"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"    rp.generation \u003d rp.generation + 1"},{"line_number":172,"context_line":"    rp.obj_reset_changes()"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"@db_api.api_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_29d0c81e","line":172,"updated":"2016-06-13 13:46:22.000000000","message":"I think it would be cleaner to keep all the calls and generation checks in one place, and just have this method check that there is inventory to delete, and that there are no allocations. IOW, do the checks for these, raise the exceptions if required, and then pass the rest on to _set_inventory.","commit_id":"38a6fba131850acb44aae6411137497e9e6038ee"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"3cbec945d472d87c6a85ce05cd3b4fc9cfeb70b3","unresolved":false,"context_lines":[{"line_number":169,"context_line":"            raise exception.ConcurrentUpdateDetected"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"    rp.generation \u003d rp.generation + 1"},{"line_number":172,"context_line":"    rp.obj_reset_changes()"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"@db_api.api_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_0224c1c2","line":172,"in_reply_to":"7aa08908_29d0c81e","updated":"2016-06-13 14:03:34.000000000","message":"In the patchset just pushed up, there\u0027s some more duplication happening which should make the options for how to tidy this up a bit more clear.","commit_id":"38a6fba131850acb44aae6411137497e9e6038ee"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"1c0de152cfb60928534b49e58d53d0a5fe11ff86","unresolved":false,"context_lines":[{"line_number":163,"context_line":"@db_api.api_context_manager.writer"},{"line_number":164,"context_line":"def _add_inventory(context, rp, inventory):"},{"line_number":165,"context_line":"    \"\"\"Add one Inventory that wasn\u0027t already on the provider.\"\"\""},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"    resource_class_id \u003d fields.ResourceClass.index(inventory.resource_class)"},{"line_number":168,"context_line":"    inv_list \u003d InventoryList(objects\u003d[inventory])"},{"line_number":169,"context_line":"    conn \u003d context.session.connection()"}],"source_content_type":"text/x-python","patch_set":9,"id":"7aa08908_cb2f23f4","line":166,"updated":"2016-06-14 21:42:42.000000000","message":"Nit: extra blank line after docstring","commit_id":"345681dc602840f778cc517d02e0bac54a0ccbf9"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fbf4e246948538e944aa66cc28f98a2b40821adf","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        # TODO(cdent): Usage doesn\u0027t exist yet"},{"line_number":123,"context_line":"        # if inv_record.capacity \u003c rp.usage[res_class]:"},{"line_number":124,"context_line":"        #     raise ObjectActionError(action\u003d\u0027update inventory\u0027,"},{"line_number":125,"context_line":"        #                             reason\u003d\u0027capacity usage mismatch\u0027"},{"line_number":126,"context_line":"        upd_stmt \u003d _INV_TBL.update().where(sa.and_("},{"line_number":127,"context_line":"                _INV_TBL.c.resource_provider_id \u003d\u003d rp.id,"},{"line_number":128,"context_line":"                _INV_TBL.c.resource_class_id \u003d\u003d res_class)).values("}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_4cbdd7d6","line":125,"updated":"2016-06-15 18:53:54.000000000","message":"I\u0027d prefer not adding commented-out code. It\u0027s confusing to read especially without syntax highlighting. Just stack this in a WIP on top or something.","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"cb2e97c9ef22a0af4e94f787ace53682c3fc2b4d","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        # TODO(cdent): Usage doesn\u0027t exist yet"},{"line_number":123,"context_line":"        # if inv_record.capacity \u003c rp.usage[res_class]:"},{"line_number":124,"context_line":"        #     raise ObjectActionError(action\u003d\u0027update inventory\u0027,"},{"line_number":125,"context_line":"        #                             reason\u003d\u0027capacity usage mismatch\u0027"},{"line_number":126,"context_line":"        upd_stmt \u003d _INV_TBL.update().where(sa.and_("},{"line_number":127,"context_line":"                _INV_TBL.c.resource_provider_id \u003d\u003d rp.id,"},{"line_number":128,"context_line":"                _INV_TBL.c.resource_class_id \u003d\u003d res_class)).values("}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_a099be7b","line":125,"in_reply_to":"7aa08908_4cbdd7d6","updated":"2016-06-16 10:41:47.000000000","message":"Done","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fbf4e246948538e944aa66cc28f98a2b40821adf","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        # TODO(cdent): Usage doesn\u0027t exist yet"},{"line_number":194,"context_line":"        # if rp.usage[resource_class_id] \u003e 0:"},{"line_number":195,"context_line":"        #     raise ObjectActionError(action\u003d\u0027delete inventory\u0027,"},{"line_number":196,"context_line":"        #                             reason\u003d\u0027inventory has allocations\u0027"},{"line_number":197,"context_line":"        if not _delete_inventory_from_provider(conn, rp, [resource_class_id]):"},{"line_number":198,"context_line":"            raise exception.NotFound("},{"line_number":199,"context_line":"                \u0027No inventory of class %s found for delete\u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_0c72af49","line":196,"updated":"2016-06-15 18:53:54.000000000","message":"Here too.","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"cb2e97c9ef22a0af4e94f787ace53682c3fc2b4d","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        # TODO(cdent): Usage doesn\u0027t exist yet"},{"line_number":194,"context_line":"        # if rp.usage[resource_class_id] \u003e 0:"},{"line_number":195,"context_line":"        #     raise ObjectActionError(action\u003d\u0027delete inventory\u0027,"},{"line_number":196,"context_line":"        #                             reason\u003d\u0027inventory has allocations\u0027"},{"line_number":197,"context_line":"        if not _delete_inventory_from_provider(conn, rp, [resource_class_id]):"},{"line_number":198,"context_line":"            raise exception.NotFound("},{"line_number":199,"context_line":"                \u0027No inventory of class %s found for delete\u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_0087f212","line":196,"in_reply_to":"7aa08908_0c72af49","updated":"2016-06-16 10:41:47.000000000","message":"Done","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fbf4e246948538e944aa66cc28f98a2b40821adf","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        return cls._from_db_object(context, cls(), db_resource_provider)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"    @base.remotable"},{"line_number":293,"context_line":"    def add_inventory(self, inventory):"},{"line_number":294,"context_line":"        \"\"\"Add one Inventory."},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"        Fails if Inventory of the provided resource class is"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_8cb33fe9","line":293,"updated":"2016-06-15 18:53:54.000000000","message":"This is \"add one inventory item to the current list\" where update_inventory is \"replace the inventory list with this one\" ? The docstring is dangerously similar to the one on update_inventory(). Maybe you can add words to fix that?","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"cb2e97c9ef22a0af4e94f787ace53682c3fc2b4d","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        return cls._from_db_object(context, cls(), db_resource_provider)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"    @base.remotable"},{"line_number":293,"context_line":"    def add_inventory(self, inventory):"},{"line_number":294,"context_line":"        \"\"\"Add one Inventory."},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"        Fails if Inventory of the provided resource class is"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_e090e644","line":293,"in_reply_to":"7aa08908_8cb33fe9","updated":"2016-06-16 10:41:47.000000000","message":"I\u0027ve tried to spruce up the docstring on all four of the public *_inventory methods.","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ab25e6776aa9a924777e28780ddb244bca561a2e","unresolved":false,"context_lines":[{"line_number":293,"context_line":""},{"line_number":294,"context_line":"    @base.remotable"},{"line_number":295,"context_line":"    def delete_inventory(self, resource_class):"},{"line_number":296,"context_line":"        \"\"\"Delete Inventory of provided resource_class.\"\"\""},{"line_number":297,"context_line":"        resource_class_id \u003d fields.ResourceClass.index(resource_class)"},{"line_number":298,"context_line":"        _delete_inventory(self._context, self, resource_class_id)"},{"line_number":299,"context_line":"        self.obj_reset_changes()"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a9d85d2_df7cc174","line":296,"range":{"start_line":296,"start_character":11,"end_line":296,"end_character":27},"updated":"2016-06-20 17:50:21.000000000","message":"This sounds like \"Delete all inventory\" but it\u0027s actually \"Delete inventory of $class\"","commit_id":"7402d134e1fe6bb62c7e56e09f16f163b0b89f01"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ab25e6776aa9a924777e28780ddb244bca561a2e","unresolved":false,"context_lines":[{"line_number":416,"context_line":"    }"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    @property"},{"line_number":419,"context_line":"    def capacity(self):"},{"line_number":420,"context_line":"        \"\"\"Inventory capacity, adjusted by allocation_ratio.\"\"\""},{"line_number":421,"context_line":"        return int((self.total - self.reserved) * self.allocation_ratio)"},{"line_number":422,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a9d85d2_3f9d0566","line":419,"updated":"2016-06-20 17:50:21.000000000","message":"I like this as an easy-to-use property, but I\u0027m worried that people will think it means \"available capacity\" and not what it really is, which is \"allocatable capacity (which may be fully committed)\". But, I don\u0027t really have a better name off the top of my head.","commit_id":"7402d134e1fe6bb62c7e56e09f16f163b0b89f01"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ab25e6776aa9a924777e28780ddb244bca561a2e","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        self.assertEqual(1, len(new_inv_list))"},{"line_number":220,"context_line":"        self.assertEqual(2048, new_inv_list[0].total)"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        # fail when inventory bad"},{"line_number":223,"context_line":"        disk_inv \u003d objects.Inventory("},{"line_number":224,"context_line":"                resource_provider\u003drp,"},{"line_number":225,"context_line":"                resource_class\u003dfields.ResourceClass.DISK_GB,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a9d85d2_5f5611d3","line":222,"range":{"start_line":222,"start_character":10,"end_line":222,"end_character":33},"updated":"2016-06-20 17:50:21.000000000","message":"While I appreciate the terseness of this, if you respin maybe throw an \"is\" in there at least to make it read a little smoother :)","commit_id":"7402d134e1fe6bb62c7e56e09f16f163b0b89f01"}],"nova/tests/unit/objects/test_objects.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"fbf4e246948538e944aa66cc28f98a2b40821adf","unresolved":false,"context_lines":[{"line_number":1180,"context_line":"    \u0027Quotas\u0027: \u00271.2-1fe4cd50593aaf5d36a6dc5ab3f98fb3\u0027,"},{"line_number":1181,"context_line":"    \u0027QuotasNoOp\u0027: \u00271.2-e041ddeb7dc8188ca71706f78aad41c1\u0027,"},{"line_number":1182,"context_line":"    \u0027RequestSpec\u0027: \u00271.6-c1cb516acdf120d367a42d343ed695b5\u0027,"},{"line_number":1183,"context_line":"    \u0027ResourceProvider\u0027: \u00271.0-421c968ee9b2341dd78b0c19c904d4de\u0027,"},{"line_number":1184,"context_line":"    \u0027S3ImageMapping\u0027: \u00271.0-7dd7366a890d82660ed121de9092276e\u0027,"},{"line_number":1185,"context_line":"    \u0027SchedulerLimits\u0027: \u00271.0-249c4bd8e62a9b327b7026b7f19cc641\u0027,"},{"line_number":1186,"context_line":"    \u0027SchedulerRetries\u0027: \u00271.1-3c9c8b16143ebbb6ad7030e999d14cc0\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_8c5dff7b","line":1183,"updated":"2016-06-15 18:53:54.000000000","message":"Again, it\u0027d be nice if we have a note in the commit message that we\u0027re intentionally not bumping the version. A year from now, we won\u0027t remember that the ordering of things was such that we can cheat.\n\nIf you\u0027re going to cheat, be proud and own it.","commit_id":"3ff83f849de191930650d9ae12556f4247e1334b"}],"nova/tests/unit/objects/test_resource_provider.py":[{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"1c0de152cfb60928534b49e58d53d0a5fe11ff86","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        inv.reserved \u003d 15"},{"line_number":220,"context_line":"        self.assertEqual(1, inv.capacity)"},{"line_number":221,"context_line":"        inv.allocation_ratio \u003d 2.0"},{"line_number":222,"context_line":"        self.assertEqual(2, inv.capacity)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"class TestInventoryNoDB(test_objects._LocalTest,"}],"source_content_type":"text/x-python","patch_set":9,"id":"7aa08908_8e4ec935","line":222,"updated":"2016-06-14 21:42:42.000000000","message":"Nit (or more of a personal preference): I really dislike \"magic\" numbers in tests. It\u0027s better to use a variable and actually do the math. E.g.:\n\n    orig_capacity \u003d inv.capacity\n    self.assertEqual(0, orig_capacity)\n    inv_change \u003d 3\n    inv.reserved -\u003d inv_change\n    exp_capacity \u003d orig_capacity + inv_change\n    self.assertEqual(exp_capacity, inv.capacity)\n    orig_capacity \u003d inv.capacity\n    alloc_factor \u003d 2.0\n    inv.allocation_ratio *\u003d alloc_factor\n    exp_capacity \u003d orig_capacity * alloc_factor\n    self.assertEqual(exp_capacity, inv.capacity)\n\nOK, that\u0027s a little sloppy, but it should illustrate what I mean.","commit_id":"345681dc602840f778cc517d02e0bac54a0ccbf9"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"3f77b223777df25b1a468e86be4a244f6b2cf604","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        inv.reserved \u003d 15"},{"line_number":220,"context_line":"        self.assertEqual(1, inv.capacity)"},{"line_number":221,"context_line":"        inv.allocation_ratio \u003d 2.0"},{"line_number":222,"context_line":"        self.assertEqual(2, inv.capacity)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"class TestInventoryNoDB(test_objects._LocalTest,"}],"source_content_type":"text/x-python","patch_set":9,"id":"7aa08908_52a3bb00","line":222,"in_reply_to":"7aa08908_04ebbf79","updated":"2016-06-15 15:44:48.000000000","message":"That\u0027s ok; I fought against magic numbers early on in OpenStack, and didn\u0027t prevail then, so I\u0027m kind of used to it.","commit_id":"345681dc602840f778cc517d02e0bac54a0ccbf9"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"a8b2f8e11b921ded37b56169b5b45429f081f2cf","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        inv.reserved \u003d 15"},{"line_number":220,"context_line":"        self.assertEqual(1, inv.capacity)"},{"line_number":221,"context_line":"        inv.allocation_ratio \u003d 2.0"},{"line_number":222,"context_line":"        self.assertEqual(2, inv.capacity)"},{"line_number":223,"context_line":""},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"class TestInventoryNoDB(test_objects._LocalTest,"}],"source_content_type":"text/x-python","patch_set":9,"id":"7aa08908_04ebbf79","line":222,"in_reply_to":"7aa08908_8e4ec935","updated":"2016-06-15 11:37:59.000000000","message":"I\u0027ve tried a few time to make a version of of this that I found readable and I just couldn\u0027t do it, so I\u0027ve stuck with what I\u0027ve got (for now).","commit_id":"345681dc602840f778cc517d02e0bac54a0ccbf9"}]}
