)]}'
{"nova/compute/resource_tracker.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fbee8d4c3006b3993c7d34a3a649193a8455f5f5","unresolved":false,"context_lines":[{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"},{"line_number":889,"context_line":"        else:"},{"line_number":890,"context_line":"            self.scheduler_client.set_traits_for_provider("},{"line_number":891,"context_line":"                compute_node.uuid,"},{"line_number":892,"context_line":"                compute_node.hypervisor_hostname,"},{"line_number":893,"context_line":"                traits_data)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f91af0f_2290fe94","line":890,"range":{"start_line":890,"start_character":34,"end_line":890,"end_character":57},"updated":"2018-01-10 15:47:29.000000000","message":"Where is this implemented?  I don\u0027t see it in master or in this series.  I ask because I was in the middle of implementing it myself when I saw this.","commit_id":"47720c987926d220f872c8088dd4497334978d3e"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"406c03fb94b8517a6ea17c75e89e07ae9caa010f","unresolved":false,"context_lines":[{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"},{"line_number":889,"context_line":"        else:"},{"line_number":890,"context_line":"            self.scheduler_client.set_traits_for_provider("},{"line_number":891,"context_line":"                compute_node.uuid,"},{"line_number":892,"context_line":"                compute_node.hypervisor_hostname,"},{"line_number":893,"context_line":"                traits_data)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7f96bb07_61bb30e5","line":890,"range":{"start_line":890,"start_character":34,"end_line":890,"end_character":57},"in_reply_to":"9f91af0f_2290fe94","updated":"2018-01-10 16:02:36.000000000","message":"I didn\u0027t push that change with the first round because it was (and is) still in progress. Here it is: https://review.openstack.org/#/c/532539/2/nova/scheduler/client/__init__.py","commit_id":"47720c987926d220f872c8088dd4497334978d3e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b78a1756deae0a9cac3818979ef59f9bb798d040","unresolved":false,"context_lines":[{"line_number":882,"context_line":"            # this code branch"},{"line_number":883,"context_line":"            self.scheduler_client.update_compute_node(compute_node)"},{"line_number":884,"context_line":""},{"line_number":885,"context_line":"        try:"},{"line_number":886,"context_line":"            traits_data \u003d self.driver.get_traits(nodename)"},{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"}],"source_content_type":"text/x-python","patch_set":3,"id":"7f96bb07_197e2719","line":885,"updated":"2018-01-12 15:27:31.000000000","message":"Hi Mark, pursuant to our conversation around generation management:\n\nCOMPUTE_RESOURCE_SEMAPHORE effectively single-threads placement writes for this compute node.  So as long as whatever we add here in Queens a) remains under that semaphore, and b) only deals with *this* compute\u0027s provider(s), we can live with incomplete generation handling in the short term.\n\nI did track this _update method and I believe all call paths happen under the semaphore, so as long as you keep your code here, we\u0027re good.","commit_id":"2ce6a43eb839ef9c58b1d9d560d5899b31b0ac9d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8e7c19955072782ed1b39838fe8be40874d94c23","unresolved":false,"context_lines":[{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"},{"line_number":889,"context_line":"        else:"},{"line_number":890,"context_line":"            self.reportclient.set_traits_for_provider("},{"line_number":891,"context_line":"                compute_node.uuid, traits)"},{"line_number":892,"context_line":""},{"line_number":893,"context_line":"        if self.pci_tracker:"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_90f9af4e","line":890,"updated":"2018-01-22 15:34:26.000000000","message":"Okay, after getting clarification [1] we need a comment here that acknowledges that we know set_traits_for_provider doesn\u0027t do anything to ensure cache consistency; but that\u0027s okay because both set_inventory_for_provider and update_compute_node above will do that via _ensure_resource_provider.\n\n[1] http://eavesdrop.openstack.org/irclogs/%23openstack-nova/%23openstack-nova.2018-01-22.log.html#t2018-01-22T15:22:46","commit_id":"fb3202fbcb1394bdb5b61f71b89bc06964890cf2"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3edaa84303181724aa59dabfe185802df0ff95fd","unresolved":false,"context_lines":[{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"},{"line_number":889,"context_line":"        else:"},{"line_number":890,"context_line":"            # NOTE(mgoddard): set_traits_for_provider does not refresh the"},{"line_number":891,"context_line":"            # provider tree in the report client, so we rely on the above call"},{"line_number":892,"context_line":"            # to set_inventory_for_provider or update_compute_node to ensure"},{"line_number":893,"context_line":"            # that the resource provider exists in the tree and has had its"},{"line_number":894,"context_line":"            # cached traits refreshed."},{"line_number":895,"context_line":"            self.reportclient.set_traits_for_provider("},{"line_number":896,"context_line":"                compute_node.uuid, traits)"},{"line_number":897,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_d9821250","line":894,"range":{"start_line":890,"start_character":12,"end_line":894,"end_character":38},"updated":"2018-01-25 20:08:33.000000000","message":"Well this is pretty gross tight-coupling...","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"e8aa6443865668e3a99680d81253c85a933fe4b9","unresolved":false,"context_lines":[{"line_number":887,"context_line":"        except NotImplementedError:"},{"line_number":888,"context_line":"            pass"},{"line_number":889,"context_line":"        else:"},{"line_number":890,"context_line":"            # NOTE(mgoddard): set_traits_for_provider does not refresh the"},{"line_number":891,"context_line":"            # provider tree in the report client, so we rely on the above call"},{"line_number":892,"context_line":"            # to set_inventory_for_provider or update_compute_node to ensure"},{"line_number":893,"context_line":"            # that the resource provider exists in the tree and has had its"},{"line_number":894,"context_line":"            # cached traits refreshed."},{"line_number":895,"context_line":"            self.reportclient.set_traits_for_provider("},{"line_number":896,"context_line":"                compute_node.uuid, traits)"},{"line_number":897,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_b5a4d8ba","line":894,"range":{"start_line":890,"start_character":12,"end_line":894,"end_character":38},"in_reply_to":"5f93b717_d9821250","updated":"2018-01-26 11:24:20.000000000","message":"Agreed. We should be able to switch to the update_provider_tree approach eventually.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"3e191e76d235d15dcda90068977da584405d56ff","unresolved":false,"context_lines":[{"line_number":893,"context_line":"            # that the resource provider exists in the tree and has had its"},{"line_number":894,"context_line":"            # cached traits refreshed."},{"line_number":895,"context_line":"            self.reportclient.set_traits_for_provider("},{"line_number":896,"context_line":"                compute_node.uuid, traits)"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":"        if self.pci_tracker:"},{"line_number":899,"context_line":"            self.pci_tracker.save(context)"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_79a2de9c","line":896,"updated":"2018-01-25 20:09:17.000000000","message":"Was going to complain that this reports traits every cycle regardless of if they have changed, but that\u0027s not true. set_traits_for_provider() has have-they-changed protection.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"}],"nova/tests/unit/compute/test_resource_tracker.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3edaa84303181724aa59dabfe185802df0ff95fd","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"        self.assertFalse(ucn_mock.called)"},{"line_number":1293,"context_line":"        self.driver_mock.get_traits.assert_called_once_with(_NODENAME)"},{"line_number":1294,"context_line":""},{"line_number":1295,"context_line":"    def test_existing_node_get_traits_implemented(self):"},{"line_number":1296,"context_line":"        \"\"\"The get_traits() virt driver method is only implemented for some"},{"line_number":1297,"context_line":"        virt drivers. This method returns traits information for a"},{"line_number":1298,"context_line":"        node/provider, and if this method doesn\u0027t raise a NotImplementedError,"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_797dfe1a","line":1295,"range":{"start_line":1295,"start_character":8,"end_line":1295,"end_character":49},"updated":"2018-01-25 20:08:33.000000000","message":"The unit test is OK for now.\n\nWhat I\u0027d like to see at some point is a functional test where we have a fake driver that actually returns at least one trait or two (one standard, one custom that gets created), and we assert that once we start a compute service with that driver, the RT passes the trait up through to placement and it gets put on the compute node resource provider. Should be pretty simple and a nice way to make sure things are talking to each other properly end-to-end.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"e8aa6443865668e3a99680d81253c85a933fe4b9","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"        self.assertFalse(ucn_mock.called)"},{"line_number":1293,"context_line":"        self.driver_mock.get_traits.assert_called_once_with(_NODENAME)"},{"line_number":1294,"context_line":""},{"line_number":1295,"context_line":"    def test_existing_node_get_traits_implemented(self):"},{"line_number":1296,"context_line":"        \"\"\"The get_traits() virt driver method is only implemented for some"},{"line_number":1297,"context_line":"        virt drivers. This method returns traits information for a"},{"line_number":1298,"context_line":"        node/provider, and if this method doesn\u0027t raise a NotImplementedError,"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_5599d46b","line":1295,"range":{"start_line":1295,"start_character":8,"end_line":1295,"end_character":49},"in_reply_to":"5f93b717_797dfe1a","updated":"2018-01-26 11:24:20.000000000","message":"Just say the word, and jroll makes it happen: https://review.openstack.org/#/c/538047","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8fdc5c185e41b76c2e83c1a211d25daeb1c61eed","unresolved":false,"context_lines":[{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"        # Emulate a driver that has implemented the new get_traits() virt"},{"line_number":1307,"context_line":"        # driver method"},{"line_number":1308,"context_line":"        self.driver_mock.get_traits.side_effect \u003d [mock.sentinel.traits]"},{"line_number":1309,"context_line":""},{"line_number":1310,"context_line":"        orig_compute \u003d _COMPUTE_NODE_FIXTURES[0].obj_clone()"},{"line_number":1311,"context_line":"        self.rt.compute_nodes[_NODENAME] \u003d orig_compute"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_d9b692da","line":1308,"range":{"start_line":1308,"start_character":36,"end_line":1308,"end_character":72},"updated":"2018-01-25 20:12:24.000000000","message":"This is weird, made me think get_traits() was returning a list containing mock.sentinel.traits and then the assertion below was asserting the call with just mock.sentinel.traits (i.e. the listitude got stripped).  But upon closer inspection, I believe the use of side_effect means the method will return mock.sentinel.traits (not [mock.sentinel.traits]) the first time and then error after that.  Which seems like overkill considering assert_called_once_with() is already making sure we only called it once.  So it would be less confusing to say\n\n self.driver_mock.get_traits.return_value \u003d mock.sentinel.traits\n\nBut, you know, meh.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"e8aa6443865668e3a99680d81253c85a933fe4b9","unresolved":false,"context_lines":[{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"        # Emulate a driver that has implemented the new get_traits() virt"},{"line_number":1307,"context_line":"        # driver method"},{"line_number":1308,"context_line":"        self.driver_mock.get_traits.side_effect \u003d [mock.sentinel.traits]"},{"line_number":1309,"context_line":""},{"line_number":1310,"context_line":"        orig_compute \u003d _COMPUTE_NODE_FIXTURES[0].obj_clone()"},{"line_number":1311,"context_line":"        self.rt.compute_nodes[_NODENAME] \u003d orig_compute"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_5500f467","line":1308,"range":{"start_line":1308,"start_character":36,"end_line":1308,"end_character":72},"in_reply_to":"5f93b717_8ff6788f","updated":"2018-01-26 11:24:20.000000000","message":"That\u0027s correct. The same approach is taken in test_existing_node_get_inventory_implemented.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fe8e37bf67c13981b34a982b8f0e204e67caf576","unresolved":false,"context_lines":[{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"        # Emulate a driver that has implemented the new get_traits() virt"},{"line_number":1307,"context_line":"        # driver method"},{"line_number":1308,"context_line":"        self.driver_mock.get_traits.side_effect \u003d [mock.sentinel.traits]"},{"line_number":1309,"context_line":""},{"line_number":1310,"context_line":"        orig_compute \u003d _COMPUTE_NODE_FIXTURES[0].obj_clone()"},{"line_number":1311,"context_line":"        self.rt.compute_nodes[_NODENAME] \u003d orig_compute"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_8ff6788f","line":1308,"range":{"start_line":1308,"start_character":36,"end_line":1308,"end_character":72},"in_reply_to":"5f93b717_d9b692da","updated":"2018-01-25 21:30:03.000000000","message":"[Later] Oh, because _setup_rt sets the side_effect, which would cause the return_value to be ignored, so it would actually have to be\n\n self.driver_mock.get_traits.side_effect \u003d None\n self.driver_mock.get_traits.return_value \u003d mock.sentinel.traits\n\n...which ain\u0027t less confusing enough to be worth it.\n\n/me crawls back into his hole","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"}],"nova/virt/driver.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8fdc5c185e41b76c2e83c1a211d25daeb1c61eed","unresolved":false,"context_lines":[{"line_number":811,"context_line":"    def get_traits(self, nodename):"},{"line_number":812,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":813,"context_line":""},{"line_number":814,"context_line":"        Returns an iterable of traits for the supplied node."},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        :param nodename: the name of the node."},{"line_number":817,"context_line":"        :returns: an iterable of traits for the supplied node."}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_b9e626e8","line":814,"updated":"2018-01-25 20:12:24.000000000","message":"Redundant.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"e8aa6443865668e3a99680d81253c85a933fe4b9","unresolved":false,"context_lines":[{"line_number":811,"context_line":"    def get_traits(self, nodename):"},{"line_number":812,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":813,"context_line":""},{"line_number":814,"context_line":"        Returns an iterable of traits for the supplied node."},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        :param nodename: the name of the node."},{"line_number":817,"context_line":"        :returns: an iterable of traits for the supplied node."}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_f58d80d3","line":814,"in_reply_to":"5f93b717_b9e626e8","updated":"2018-01-26 11:24:20.000000000","message":"Will follow up.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8fdc5c185e41b76c2e83c1a211d25daeb1c61eed","unresolved":false,"context_lines":[{"line_number":814,"context_line":"        Returns an iterable of traits for the supplied node."},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        :param nodename: the name of the node."},{"line_number":817,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":818,"context_line":"        \"\"\""},{"line_number":819,"context_line":"        raise NotImplementedError()"},{"line_number":820,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_b9ff0666","line":817,"range":{"start_line":817,"start_character":33,"end_line":817,"end_character":39},"updated":"2018-01-25 20:12:24.000000000","message":"string trait names\n\nWould also be a good idea to mention that custom traits need not be pre-created - that\u0027s handled by the caller.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"e8aa6443865668e3a99680d81253c85a933fe4b9","unresolved":false,"context_lines":[{"line_number":814,"context_line":"        Returns an iterable of traits for the supplied node."},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        :param nodename: the name of the node."},{"line_number":817,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":818,"context_line":"        \"\"\""},{"line_number":819,"context_line":"        raise NotImplementedError()"},{"line_number":820,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"5f93b717_95be7c63","line":817,"range":{"start_line":817,"start_character":33,"end_line":817,"end_character":39},"in_reply_to":"5f93b717_b9ff0666","updated":"2018-01-26 11:24:20.000000000","message":"Will follow up.","commit_id":"a0bf6d9d8cfeee7a3b468eeaf8da1818e4ba8613"}]}
