)]}'
{"nova/compute/provider_tree.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e7d6eadf1627d24c822ee2ba4cafd670920a150f","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        for key, cur_rec in cur.items():"},{"line_number":88,"context_line":"            new_rec \u003d new[key]"},{"line_number":89,"context_line":"            for rec_key, cur_val in cur_rec.items():"},{"line_number":90,"context_line":"                if rec_key not in new_rec:"},{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"},{"line_number":101,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"df140735_2516b04a","line":98,"range":{"start_line":90,"start_character":0,"end_line":98,"end_character":28},"updated":"2017-06-05 13:19:30.000000000","message":"Copying over discussion from https://review.openstack.org/#/c/415920/9/nova/compute/provider_tree.py@45\n\nEric Fried\nMay 30 3:01 PM\nDoes this assume certain fields (like \u0027total\u0027) are required and will therefore always be present?  I would expect we would want to return True if cur doesn\u0027t have \u0027total\u0027, but new does.\n\nJay Pipes\nMay 31 7:34 PM\nIt means precisely what it says :) We only consider fields that are present in both dicts.\n\nEric Fried\nJun 1 9:36 AM\nRight, so that\u0027s my concern.  If the old inventory didn\u0027t have \u0027total\u0027, but the new inventory does, I would think you would want to return True.  If things like \u0027total\u0027, \u0027min_unit\u0027, and \u0027max_unit\u0027 are guaranteed to be there, that should be mentioned in this comment.  If they\u0027re not guaranteed to be there, then the algorithm should account for the \"important\" fields differently.\nUnless my premise is wrong, and it\u0027s not considered an inventory change when I add total/min_unit/max_unit where it was previously missing.\n\nRodolfo Alonso Hernandez\nJun 2 10:49 AM\nI have just the opposite question. In L115 you are overwriting self.inventory with the new value. What happens with those fields present in the old inventary but not in the new one?\n\nJay Pipes\nJun 2 12:27 PM\nThis is all due to the messed up way we allow some things to be controlled by the resource tracker and other things to be controlled by the virt driver :( I\u0027ll try to pull this out and into a separate patch where we can reason about it.","commit_id":"ade12ca7c8af4d635aef7bae656fa4a42241bc4c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e7d6eadf1627d24c822ee2ba4cafd670920a150f","unresolved":false,"context_lines":[{"line_number":195,"context_line":""},{"line_number":196,"context_line":"    def has_inventory_changed(self, name_or_uuid, inventory):"},{"line_number":197,"context_line":"        \"\"\"Returns True if the supplied inventory is different for the provider"},{"line_number":198,"context_line":"        with the supplied name or UUID."},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":201,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"}],"source_content_type":"text/x-python","patch_set":2,"id":"df140735_c56ed4c7","line":198,"updated":"2017-06-05 13:19:30.000000000","message":"Copying from https://review.openstack.org/#/c/415920/11/nova/compute/provider_tree.py@203\n\nEd Leafe\nJun 2 11:00 AM\nSince this is the public method that people will use, I would add some wording similar to the comment _inventory_has_changed() about only comparing keys that both supplied inv and provider inv have in common.","commit_id":"ade12ca7c8af4d635aef7bae656fa4a42241bc4c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"755440ea89b7eef0d9fe0de8d6675a016facf17d","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            del self.children[provider.uuid]"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def has_inventory_changed(self, new):"},{"line_number":81,"context_line":"        \"\"\"Update the stored inventory for the provider and return whether the"},{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f287b81_f0ad7c9b","line":81,"range":{"start_line":81,"start_character":11,"end_line":81,"end_character":38},"updated":"2017-09-05 21:26:24.000000000","message":"I don\u0027t think this is happening.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e361f992e812e9c56655d4ce6f57a160e7828d0e","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            del self.children[provider.uuid]"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def has_inventory_changed(self, new):"},{"line_number":81,"context_line":"        \"\"\"Update the stored inventory for the provider and return whether the"},{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_6d00cd35","line":81,"range":{"start_line":81,"start_character":11,"end_line":81,"end_character":38},"in_reply_to":"7f287b81_f0ad7c9b","updated":"2017-09-22 17:54:28.000000000","message":"Done","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"755440ea89b7eef0d9fe0de8d6675a016facf17d","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"},{"line_number":85,"context_line":"        if sorted(cur.keys()) !\u003d sorted(new.keys()):"},{"line_number":86,"context_line":"            return True"},{"line_number":87,"context_line":"        for key, cur_rec in cur.items():"},{"line_number":88,"context_line":"            new_rec \u003d new[key]"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f287b81_f0e9fcb6","line":85,"range":{"start_line":85,"start_character":11,"end_line":85,"end_character":51},"updated":"2017-09-05 21:26:24.000000000","message":"More efficient:\n\n if set(cur) !\u003d set(new):\n\nOr (still more efficient than original, though less efficient than above, but more explicit):\n\n if set(cur.keys()) !\u003d set(new.keys()):","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e361f992e812e9c56655d4ce6f57a160e7828d0e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"},{"line_number":85,"context_line":"        if sorted(cur.keys()) !\u003d sorted(new.keys()):"},{"line_number":86,"context_line":"            return True"},{"line_number":87,"context_line":"        for key, cur_rec in cur.items():"},{"line_number":88,"context_line":"            new_rec \u003d new[key]"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_0d95d9e4","line":85,"range":{"start_line":85,"start_character":11,"end_line":85,"end_character":51},"in_reply_to":"7f287b81_f0e9fcb6","updated":"2017-09-22 17:54:28.000000000","message":"Done","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5c4054e0ca2dea5021991201eaaa70be492be594","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            new_rec \u003d new[key]"},{"line_number":89,"context_line":"            for rec_key, cur_val in cur_rec.items():"},{"line_number":90,"context_line":"                if rec_key not in new_rec:"},{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_7892f04d","line":97,"range":{"start_line":91,"start_character":20,"end_line":97,"end_character":76},"updated":"2017-08-17 17:36:33.000000000","message":"so this is why we are not just doing a equals check between now and cur instead of the nested loops and if checks.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e361f992e812e9c56655d4ce6f57a160e7828d0e","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            new_rec \u003d new[key]"},{"line_number":89,"context_line":"            for rec_key, cur_val in cur_rec.items():"},{"line_number":90,"context_line":"                if rec_key not in new_rec:"},{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_d0087829","line":97,"range":{"start_line":91,"start_character":20,"end_line":97,"end_character":76},"in_reply_to":"9f436f4f_7892f04d","updated":"2017-09-22 17:54:28.000000000","message":"correct.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5c4054e0ca2dea5021991201eaaa70be492be594","unresolved":false,"context_lines":[{"line_number":203,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"},{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_78a430ba","line":206,"range":{"start_line":206,"start_character":8,"end_line":206,"end_character":23},"updated":"2017-08-17 17:36:33.000000000","message":"just checking that im following that this is a lockcreate on line 119 which is basically the same as a mutex and not a db table lock on the provider inventory table correct.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"755440ea89b7eef0d9fe0de8d6675a016facf17d","unresolved":false,"context_lines":[{"line_number":203,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"},{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f287b81_be5a254d","line":206,"range":{"start_line":206,"start_character":8,"end_line":206,"end_character":23},"in_reply_to":"9f436f4f_78a430ba","updated":"2017-09-05 21:26:24.000000000","message":"Thread mutex, nothing to do with the DB.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e361f992e812e9c56655d4ce6f57a160e7828d0e","unresolved":false,"context_lines":[{"line_number":203,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"},{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_501c8869","line":206,"range":{"start_line":206,"start_character":8,"end_line":206,"end_character":23},"in_reply_to":"9f436f4f_78a430ba","updated":"2017-09-22 17:54:28.000000000","message":"correct.","commit_id":"94c2a2c53c447df17cadd9134ae81c047a29f844"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a54d221337205821eaa97e150bfc7fc210e8e040","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            del self.children[provider.uuid]"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def has_inventory_changed(self, new):"},{"line_number":81,"context_line":"        \"\"\"Update the stored inventory for the provider and return whether the"},{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_fb3122ee","line":81,"range":{"start_line":81,"start_character":11,"end_line":81,"end_character":55},"updated":"2017-09-22 12:48:51.000000000","message":"Seems like a copy-paste from update_inventory() as this function does not update the inventory.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cc2a222219885421a1d07fffdb035f27e310c0c1","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            del self.children[provider.uuid]"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def has_inventory_changed(self, new):"},{"line_number":81,"context_line":"        \"\"\"Update the stored inventory for the provider and return whether the"},{"line_number":82,"context_line":"        inventory has changed."},{"line_number":83,"context_line":"        \"\"\""},{"line_number":84,"context_line":"        cur \u003d self.inventory"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_ade12501","line":81,"range":{"start_line":81,"start_character":11,"end_line":81,"end_character":55},"in_reply_to":"7f515b1d_fb3122ee","updated":"2017-09-22 17:48:23.000000000","message":"Done","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a54d221337205821eaa97e150bfc7fc210e8e040","unresolved":false,"context_lines":[{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_dbe8a617","line":97,"range":{"start_line":94,"start_character":73,"end_line":97,"end_character":76},"updated":"2017-09-22 12:48:51.000000000","message":"What if the total field values are different and also allocation_ratio field is missing. I think this function will return True. But then at L110 the stored inventory is blindly overwritten with the incoming new inventory that has missing allocation_ratio field. Is this OK?","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"5eca8fcfebb3df20282a22b12dd6a59c659c1b32","unresolved":false,"context_lines":[{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_e40ef9e3","line":97,"range":{"start_line":94,"start_character":73,"end_line":97,"end_character":76},"in_reply_to":"7f515b1d_8dd0a9f9","updated":"2017-09-25 12:25:15.000000000","message":"I guess it is all depends on how nova will use this provider_tree object. I think we only need to add those fields where we see the use of it in the near future. As we can add the other fields later if they are needed. So I vote for only storing the total values for now.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cc2a222219885421a1d07fffdb035f27e310c0c1","unresolved":false,"context_lines":[{"line_number":91,"context_line":"                    # Deliberately don\u0027t want to compare missing keys in the"},{"line_number":92,"context_line":"                    # inventory record. For instance, we will be passing in"},{"line_number":93,"context_line":"                    # fields like allocation_ratio in the current dict but the"},{"line_number":94,"context_line":"                    # resource tracker may only pass in the total field. We"},{"line_number":95,"context_line":"                    # want to return that inventory didn\u0027t change when the"},{"line_number":96,"context_line":"                    # total field values are the same even if the"},{"line_number":97,"context_line":"                    # allocation_ratio field is missing from the new record."},{"line_number":98,"context_line":"                    continue"},{"line_number":99,"context_line":"                if new_rec[rec_key] !\u003d cur_val:"},{"line_number":100,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_8dd0a9f9","line":97,"range":{"start_line":94,"start_character":73,"end_line":97,"end_character":76},"in_reply_to":"7f515b1d_dbe8a617","updated":"2017-09-22 17:48:23.000000000","message":"Yeah, it\u0027s a weird situation for sure. :( I wonder if I should *only* store the total value for the inventory and disregard any of the other fields like min_unit, max_unit and allocation_ratio... what about reserved? Should I keep that?","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a54d221337205821eaa97e150bfc7fc210e8e040","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_7b13f20e","line":209,"range":{"start_line":207,"start_character":1,"end_line":209,"end_character":73},"updated":"2017-09-22 12:48:51.000000000","message":"This looks like a repetitive pattern. Would it be more pythonic to have the _find() function raise the generic ValueError? That could remove a lot of this repetition (e.g. L135, L147, L190)","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"5eca8fcfebb3df20282a22b12dd6a59c659c1b32","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_c4b65dda","line":209,"range":{"start_line":207,"start_character":1,"end_line":209,"end_character":73},"in_reply_to":"7f515b1d_6dcd6d5c","updated":"2017-09-25 12:25:15.000000000","message":"I don\u0027t see why you have to add extra try except blocks. The current expected behavior of remove() is to raise a ValueError if the name_or_uuid is not found. If you move that  raising of the ValueError into _find_with_lock() then you can remove the L134-L135 from remove() and you don\u0027t have to add a try, except block to keep the current behavior.\n\nSame true for update_inventory. If the _find_with_lock() already raises the ValueError exception then you don\u0027t have to do that at all in update_inventory()\n\nOK, exists() needs an extra try except as that function should return a boolean.\n\nIn new_root() you can uses self.exists(uuid) to avoid adding the extra try except block.\n\nIn new_child() you don\u0027t need the extra try except block if _find_with_lock() already raise a ValueError.\n\nSomething like this: http://paste.openstack.org/show/621845/\n\nTo be correct with this change you will loose the way to add a specific error message to the ValueError but if these errors ever reach the end user via an API then we anyhow need an extra translation step up at the API level and there we can add the specific messages. If these errors are ending up in the log only then the stack trace will carry enough information about the specific case.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cc2a222219885421a1d07fffdb035f27e310c0c1","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_6dcd6d5c","line":209,"range":{"start_line":207,"start_character":1,"end_line":209,"end_character":73},"in_reply_to":"7f515b1d_7b13f20e","updated":"2017-09-22 17:48:23.000000000","message":"Well, it\u0027s actually not that much of a repetitive pattern. The _find_with_lock() method returns either None or a _Provider object. The remove(), exists(), update_inventory() new_child() and new_root() methods all handle the return value of None or an object differently. So, if I changed the _find_with_lock() method to raise a ValueError instead of returning None, I\u0027d just have to add more code to various methods that do a try: except ValueError: block. I chose this route because it seemed cleaner.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2a5d86df531596e34c2a794da190bf0d48236b6e","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_ff5ceaed","line":209,"range":{"start_line":207,"start_character":1,"end_line":209,"end_character":73},"in_reply_to":"7f515b1d_c4b65dda","updated":"2017-09-27 18:33:59.000000000","message":"OK, I\u0027ve reworked this to remove the duplicate try/except blocks. Let me know what you think of the latest revision.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"b962a07b4bfd3cc07552653fb5e8b899f8b60186","unresolved":false,"context_lines":[{"line_number":204,"context_line":"                          information."},{"line_number":205,"context_line":"        \"\"\""},{"line_number":206,"context_line":"        with self.lock:"},{"line_number":207,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":208,"context_line":"            if not p:"},{"line_number":209,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_79181d1d","line":209,"range":{"start_line":207,"start_character":1,"end_line":209,"end_character":73},"in_reply_to":"7f515b1d_ff5ceaed","updated":"2017-10-09 09:20:23.000000000","message":"Thanks. I like the new way.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a54d221337205821eaa97e150bfc7fc210e8e040","unresolved":false,"context_lines":[{"line_number":217,"context_line":""},{"line_number":218,"context_line":"        :returns: True if the inventory has changed."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        :note: The provider\u0027s generation is always set to the supplied"},{"line_number":221,"context_line":"               generation, even if there were no changes to the inventory."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":224,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_1b1bde1b","line":221,"range":{"start_line":220,"start_character":1,"end_line":221,"end_character":74},"updated":"2017-09-22 12:48:51.000000000","message":"Why do we need to bump the generation when the inventory does not changed?","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cc2a222219885421a1d07fffdb035f27e310c0c1","unresolved":false,"context_lines":[{"line_number":217,"context_line":""},{"line_number":218,"context_line":"        :returns: True if the inventory has changed."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        :note: The provider\u0027s generation is always set to the supplied"},{"line_number":221,"context_line":"               generation, even if there were no changes to the inventory."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":224,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_4de4f1ac","line":221,"range":{"start_line":220,"start_character":1,"end_line":221,"end_character":74},"in_reply_to":"7f515b1d_1b1bde1b","updated":"2017-09-22 17:48:23.000000000","message":"Because if an external system has changed the resource provider\u0027s generation, we want to make sure we update the ProviderTree\u0027s generation for that _Provider object even if the inventory we previously knew about stayed the same. This is to prevent retries when attempting to set inventory on a provider of some shared resource where multiple threads may have updated a resource provider\u0027s inventory.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"5eca8fcfebb3df20282a22b12dd6a59c659c1b32","unresolved":false,"context_lines":[{"line_number":217,"context_line":""},{"line_number":218,"context_line":"        :returns: True if the inventory has changed."},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"        :note: The provider\u0027s generation is always set to the supplied"},{"line_number":221,"context_line":"               generation, even if there were no changes to the inventory."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":224,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_84e3c505","line":221,"range":{"start_line":220,"start_character":1,"end_line":221,"end_character":74},"in_reply_to":"7f515b1d_4de4f1ac","updated":"2017-09-25 12:25:15.000000000","message":"Now I got it. Generation can change due to changing other then the total values we are care about here.","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a54d221337205821eaa97e150bfc7fc210e8e040","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        :param generation: The resource provider generation to set"},{"line_number":229,"context_line":"        \"\"\""},{"line_number":230,"context_line":"        with self.lock:"},{"line_number":231,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":232,"context_line":"            if not p:"},{"line_number":233,"context_line":"                raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"            return p.update_inventory(inventory, generation)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_fbfec2ac","line":233,"range":{"start_line":231,"start_character":1,"end_line":233,"end_character":73},"updated":"2017-09-22 12:48:51.000000000","message":"ditto","commit_id":"97ae92c7983d0ee94020efdcd051db504dd04778"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f9da527d9a7bed3fdb7ea1489db7d3c621bdac64","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def new_root(self, name, uuid, generation):"},{"line_number":143,"context_line":"        \"\"\"Adds a new root provider to the tree.\"\"\""},{"line_number":144,"context_line":"        if self.exists(uuid):"},{"line_number":145,"context_line":"            err \u003d _(\"Provider %s already exists as a root.\")"},{"line_number":146,"context_line":"            raise ValueError(err % uuid)"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"        with self.lock:"},{"line_number":149,"context_line":"            p \u003d _Provider(name, uuid, generation)"},{"line_number":150,"context_line":"            self.roots.append(p)"},{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_58b4e67f","line":149,"range":{"start_line":144,"start_character":0,"end_line":149,"end_character":1},"updated":"2017-10-02 16:03:31.000000000","message":"-1.  This opens the timing window whereby another thread can create the RP after `exists` but before `lock`.\n\nEither revert to using _find_with_lock, or split out a new `_exists_with_lock` below.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bd182fa757c9433001f549f07eaf9d7fbc6103cb","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def new_root(self, name, uuid, generation):"},{"line_number":143,"context_line":"        \"\"\"Adds a new root provider to the tree.\"\"\""},{"line_number":144,"context_line":"        if self.exists(uuid):"},{"line_number":145,"context_line":"            err \u003d _(\"Provider %s already exists as a root.\")"},{"line_number":146,"context_line":"            raise ValueError(err % uuid)"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"        with self.lock:"},{"line_number":149,"context_line":"            p \u003d _Provider(name, uuid, generation)"},{"line_number":150,"context_line":"            self.roots.append(p)"},{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_942b0d2f","line":149,"range":{"start_line":144,"start_character":0,"end_line":149,"end_character":1},"in_reply_to":"7f515b1d_58b4e67f","updated":"2017-10-04 18:47:18.000000000","message":"ack, will fix.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8bea74f297fcac334131972b729d6694f034f4bd","unresolved":false,"context_lines":[{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def new_root(self, name, uuid, generation):"},{"line_number":143,"context_line":"        \"\"\"Adds a new root provider to the tree.\"\"\""},{"line_number":144,"context_line":"        if self.exists(uuid):"},{"line_number":145,"context_line":"            err \u003d _(\"Provider %s already exists as a root.\")"},{"line_number":146,"context_line":"            raise ValueError(err % uuid)"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"        with self.lock:"},{"line_number":149,"context_line":"            p \u003d _Provider(name, uuid, generation)"},{"line_number":150,"context_line":"            self.roots.append(p)"},{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_ef50add7","line":149,"range":{"start_line":144,"start_character":0,"end_line":149,"end_character":1},"in_reply_to":"7f515b1d_942b0d2f","updated":"2017-10-09 17:23:02.000000000","message":"Done","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0d222c43a7fb253997ee65b6114e393a64c2bb8a","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_e2c08ae3","line":154,"updated":"2017-10-01 14:03:09.000000000","message":"I recognized that this merged a while back, but this tickled my brain: is this safe when the rp\u0027s name is an uuid?","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"966ccaec6e8c400d38c040332dbee3a869ed4489","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_6a72e87e","line":154,"in_reply_to":"7f515b1d_47f5e582","updated":"2017-10-04 20:03:09.000000000","message":"++\n\nThat\u0027ll wind up looking a lot cleaner anyway, I believe.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8bea74f297fcac334131972b729d6694f034f4bd","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_6f24bd60","line":154,"in_reply_to":"7f515b1d_47f5e582","updated":"2017-10-09 17:23:02.000000000","message":"Done","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"a5606566cb218403aff7f87f298365c83a4e31a4","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_47f5e582","line":154,"in_reply_to":"7f515b1d_673fc1b5","updated":"2017-10-04 19:34:09.000000000","message":"Sorry, for some reason I thought that for Ironic nodes, the hypervisor_hostname \u003d\u003d the compute node UUID so that\u0027s why it wouldn\u0027t matter for Ironic nodes... but I was totally incorrect on that :)\n\nI get your point. I will change the implementation here to do a search of either name or uuid attribute matching the supplied search string, regardless of whether the search string is a UUID-like thing or not.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"3e9fc549856dccc5471fb4f10b959d48caed02b2","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_673fc1b5","line":154,"in_reply_to":"7f515b1d_9412ed08","updated":"2017-10-04 19:12:02.000000000","message":"Huh? If I do a remove and pass what I think is a name, but that name is a uuid, find_by_uuid will be called and will not find the rp because it will be look by uuid.  The uuid of the rp is something else; since the name is a uuid, we will never getattr(\u0027name\u0027)","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bd182fa757c9433001f549f07eaf9d7fbc6103cb","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_9412ed08","line":154,"in_reply_to":"7f515b1d_e2c08ae3","updated":"2017-10-04 18:47:18.000000000","message":"Does it matter? The virt driver will be looking up resource providers by name most likely. If it passes the ironic node UUID as the name, that\u0027s perfectly fine isn\u0027t it? It will still find the provider...","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e5ea8b85b920682ee88998121839b72008fc8929","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            return p"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _find_with_lock(self, name_or_uuid):"},{"line_number":154,"context_line":"        if uuidutils.is_uuid_like(name_or_uuid):"},{"line_number":155,"context_line":"            getter \u003d \u0027find_by_uuid\u0027"},{"line_number":156,"context_line":"        else:"},{"line_number":157,"context_line":"            getter \u003d \u0027find_by_name\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_3d711c77","line":154,"in_reply_to":"7f515b1d_e2c08ae3","updated":"2017-10-02 14:35:47.000000000","message":"oo, excellent point.  Like for ironic.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f9da527d9a7bed3fdb7ea1489db7d3c621bdac64","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        \"\"\"Given either a name or a UUID, return True if the tree contains the"},{"line_number":177,"context_line":"        child provider, False otherwise."},{"line_number":178,"context_line":"        \"\"\""},{"line_number":179,"context_line":"        try:"},{"line_number":180,"context_line":"            with self.lock:"},{"line_number":181,"context_line":"                self._find_with_lock(name_or_uuid)"},{"line_number":182,"context_line":"                return True"},{"line_number":183,"context_line":"        except ValueError:"},{"line_number":184,"context_line":"            return False"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    def new_child(self, name, parent_uuid, uuid\u003dNone, generation\u003dNone):"},{"line_number":187,"context_line":"        \"\"\"Creates a new child provider with the given name and uuid under the"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_b8519a38","line":184,"range":{"start_line":179,"start_character":0,"end_line":184,"end_character":24},"updated":"2017-10-02 16:03:31.000000000","message":"Why not:\n\n try:\n     self.find(...)\n     return True\n except ValueError:\n     return False\n\nand let `find` do the locking?\n\nThat said, I\u0027m not sure why we need a separate `exists` method at all.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8bea74f297fcac334131972b729d6694f034f4bd","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        \"\"\"Given either a name or a UUID, return True if the tree contains the"},{"line_number":177,"context_line":"        child provider, False otherwise."},{"line_number":178,"context_line":"        \"\"\""},{"line_number":179,"context_line":"        try:"},{"line_number":180,"context_line":"            with self.lock:"},{"line_number":181,"context_line":"                self._find_with_lock(name_or_uuid)"},{"line_number":182,"context_line":"                return True"},{"line_number":183,"context_line":"        except ValueError:"},{"line_number":184,"context_line":"            return False"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    def new_child(self, name, parent_uuid, uuid\u003dNone, generation\u003dNone):"},{"line_number":187,"context_line":"        \"\"\"Creates a new child provider with the given name and uuid under the"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_ef730d4d","line":184,"range":{"start_line":179,"start_character":0,"end_line":184,"end_character":24},"in_reply_to":"7f515b1d_b8519a38","updated":"2017-10-09 17:23:02.000000000","message":"Done","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bd182fa757c9433001f549f07eaf9d7fbc6103cb","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        \"\"\"Given either a name or a UUID, return True if the tree contains the"},{"line_number":177,"context_line":"        child provider, False otherwise."},{"line_number":178,"context_line":"        \"\"\""},{"line_number":179,"context_line":"        try:"},{"line_number":180,"context_line":"            with self.lock:"},{"line_number":181,"context_line":"                self._find_with_lock(name_or_uuid)"},{"line_number":182,"context_line":"                return True"},{"line_number":183,"context_line":"        except ValueError:"},{"line_number":184,"context_line":"            return False"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    def new_child(self, name, parent_uuid, uuid\u003dNone, generation\u003dNone):"},{"line_number":187,"context_line":"        \"\"\"Creates a new child provider with the given name and uuid under the"}],"source_content_type":"text/x-python","patch_set":8,"id":"7f515b1d_d43185a4","line":184,"range":{"start_line":179,"start_character":0,"end_line":184,"end_character":24},"in_reply_to":"7f515b1d_b8519a38","updated":"2017-10-04 18:47:18.000000000","message":"ack, will fix.","commit_id":"2ad991a57640f848653992e9e2210b24b9fbc9f0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8a2912342c103afeab1d8caf2dca21e9e97bde9a","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        # dict of inventory records, keyed by resource class"},{"line_number":49,"context_line":"        self.inventory \u003d {}"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def find(self, search):"},{"line_number":52,"context_line":"        if self.name \u003d\u003d search or self.uuid \u003d\u003d search:"},{"line_number":53,"context_line":"            return self"},{"line_number":54,"context_line":"        if search in self.children:"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f4e5783_90832705","line":51,"updated":"2017-10-10 17:25:26.000000000","message":"oh, way nicer","commit_id":"33340f5064cbc000004345d20ec78b714feb0d65"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"a9e2d69165487612f17e58fcf38dfe895b0e87e9","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        self.inventory \u003d {}"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def find(self, search):"},{"line_number":52,"context_line":"        if self.name \u003d\u003d search or self.uuid \u003d\u003d search:"},{"line_number":53,"context_line":"            return self"},{"line_number":54,"context_line":"        if search in self.children:"},{"line_number":55,"context_line":"            return self.children[search]"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_5e61d4d2","line":52,"updated":"2017-10-13 17:06:24.000000000","message":"nice","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"a9e2d69165487612f17e58fcf38dfe895b0e87e9","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                          information."},{"line_number":204,"context_line":"        \"\"\""},{"line_number":205,"context_line":"        with self.lock:"},{"line_number":206,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":207,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def update_inventory(self, name_or_uuid, inventory, generation):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_5eb67440","line":206,"updated":"2017-10-13 17:06:24.000000000","message":"what\u0027s a p?","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"216d457fe5a8900e722e36287ef3844e3be174c7","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                          information."},{"line_number":204,"context_line":"        \"\"\""},{"line_number":205,"context_line":"        with self.lock:"},{"line_number":206,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":207,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def update_inventory(self, name_or_uuid, inventory, generation):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_fd0defe7","line":206,"in_reply_to":"5f4e5783_5eb67440","updated":"2017-10-16 22:39:53.000000000","message":"A provider?","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"511e8c5bd419e5da1942e84fdc685f50c5b45ad8","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                          information."},{"line_number":204,"context_line":"        \"\"\""},{"line_number":205,"context_line":"        with self.lock:"},{"line_number":206,"context_line":"            p \u003d self._find_with_lock(name_or_uuid)"},{"line_number":207,"context_line":"            return p.has_inventory_changed(inventory)"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def update_inventory(self, name_or_uuid, inventory, generation):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_ab85df08","line":206,"in_reply_to":"5f4e5783_fd0defe7","updated":"2017-10-17 12:57:54.000000000","message":"Done","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"efdacd0471ae2f93e204c23b2417b84b42b1b853","unresolved":false,"context_lines":[{"line_number":216,"context_line":"        :note: The provider\u0027s generation is always set to the supplied"},{"line_number":217,"context_line":"               generation, even if there were no changes to the inventory."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":220,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"},{"line_number":221,"context_line":"                             update inventory for."},{"line_number":222,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_a6e3dfa3","line":219,"range":{"start_line":219,"start_character":47,"end_line":219,"end_character":51},"updated":"2017-10-17 07:58:36.000000000","message":"nit. uuid or name?","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e594c5d8f5dc0fa97372e017a501217442121236","unresolved":false,"context_lines":[{"line_number":216,"context_line":"        :note: The provider\u0027s generation is always set to the supplied"},{"line_number":217,"context_line":"               generation, even if there were no changes to the inventory."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":220,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"},{"line_number":221,"context_line":"                             update inventory for."},{"line_number":222,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_8bdfc367","line":219,"range":{"start_line":219,"start_character":47,"end_line":219,"end_character":51},"in_reply_to":"5f4e5783_a6e3dfa3","updated":"2017-10-17 12:48:38.000000000","message":"Done","commit_id":"ac11c40f2f33d127745aa27f827f1a5186e27acb"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c3bb5d4a2b63ef6816065a6421321da43cc75dc1","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        \"\"\"Returns True if the supplied inventory is different for the provider"},{"line_number":197,"context_line":"        with the supplied name or UUID."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":200,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"},{"line_number":201,"context_line":"                             update inventory for."},{"line_number":202,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f4e5783_0b63d3b3","line":199,"range":{"start_line":199,"start_character":47,"end_line":199,"end_character":51},"updated":"2017-10-17 12:50:04.000000000","message":"ok, sorry, I\u0027m lazy, I just pointed out one of that place, there are more :)","commit_id":"3121c159e65e107a6b3f3dda4890420f2bc61569"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"511e8c5bd419e5da1942e84fdc685f50c5b45ad8","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        \"\"\"Returns True if the supplied inventory is different for the provider"},{"line_number":197,"context_line":"        with the supplied name or UUID."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"        :raises: ValueError if a provider with uuid was not found in the tree."},{"line_number":200,"context_line":"        :param name_or_uuid: Either name or UUID of the resource provider to"},{"line_number":201,"context_line":"                             update inventory for."},{"line_number":202,"context_line":"        :param inventory: dict, keyed by resource class, of inventory"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f4e5783_0b92b34c","line":199,"range":{"start_line":199,"start_character":47,"end_line":199,"end_character":51},"in_reply_to":"5f4e5783_0b63d3b3","updated":"2017-10-17 12:57:54.000000000","message":"And *I* was lazy for not looking.\n\nDone.","commit_id":"3121c159e65e107a6b3f3dda4890420f2bc61569"}]}
