)]}'
{"nova/tests/unit/virt/ironic/test_driver.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"00e14618c47c4c0e786351d46ed64db004ec8d1f","unresolved":false,"context_lines":[{"line_number":962,"context_line":"        mock_nfc.assert_called_once_with(node.uuid)"},{"line_number":963,"context_line":"        self.assertEqual([], result)"},{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    @mock.patch.object(ironic_driver.IronicDriver, \u0027_node_from_cache\u0027)"},{"line_number":966,"context_line":"    def test_get_traits_with_no_traits_attr(self, mock_nfc):"},{"line_number":967,"context_line":"        \"\"\"Ensure that when the node has no traits attribute, we return no"},{"line_number":968,"context_line":"        traits.  This models the use of an ironic client library without"},{"line_number":969,"context_line":"        support for node traits."},{"line_number":970,"context_line":"        \"\"\""},{"line_number":971,"context_line":"        node \u003d type(\u0027node\u0027, (object,),"},{"line_number":972,"context_line":"                    {\u0027uuid\u0027: \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027})"},{"line_number":973,"context_line":"        mock_nfc.return_value \u003d node"},{"line_number":974,"context_line":"        result \u003d self.driver.get_traits(node.uuid)"},{"line_number":975,"context_line":""},{"line_number":976,"context_line":"        mock_nfc.assert_called_once_with(node.uuid)"},{"line_number":977,"context_line":"        self.assertEqual([], result)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    @mock.patch.object(ironic_driver.IronicDriver, \u0027_node_from_cache\u0027)"},{"line_number":980,"context_line":"    def test_get_traits_with_traits(self, mock_nfc):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_99f6ca8f","line":977,"range":{"start_line":965,"start_character":4,"end_line":977,"end_character":36},"updated":"2018-01-25 20:13:03.000000000","message":"This can likely be removed. A node repr from ironicclient 1.37 should have a traits field on it right?","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"f000a50c0ce2633bdfcdb080e6c21b0f72dc5d05","unresolved":false,"context_lines":[{"line_number":962,"context_line":"        mock_nfc.assert_called_once_with(node.uuid)"},{"line_number":963,"context_line":"        self.assertEqual([], result)"},{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    @mock.patch.object(ironic_driver.IronicDriver, \u0027_node_from_cache\u0027)"},{"line_number":966,"context_line":"    def test_get_traits_with_no_traits_attr(self, mock_nfc):"},{"line_number":967,"context_line":"        \"\"\"Ensure that when the node has no traits attribute, we return no"},{"line_number":968,"context_line":"        traits.  This models the use of an ironic client library without"},{"line_number":969,"context_line":"        support for node traits."},{"line_number":970,"context_line":"        \"\"\""},{"line_number":971,"context_line":"        node \u003d type(\u0027node\u0027, (object,),"},{"line_number":972,"context_line":"                    {\u0027uuid\u0027: \u0027eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa\u0027})"},{"line_number":973,"context_line":"        mock_nfc.return_value \u003d node"},{"line_number":974,"context_line":"        result \u003d self.driver.get_traits(node.uuid)"},{"line_number":975,"context_line":""},{"line_number":976,"context_line":"        mock_nfc.assert_called_once_with(node.uuid)"},{"line_number":977,"context_line":"        self.assertEqual([], result)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    @mock.patch.object(ironic_driver.IronicDriver, \u0027_node_from_cache\u0027)"},{"line_number":980,"context_line":"    def test_get_traits_with_traits(self, mock_nfc):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_d9ee9287","line":977,"range":{"start_line":965,"start_character":4,"end_line":977,"end_character":36},"in_reply_to":"5f93b717_99f6ca8f","updated":"2018-01-25 20:21:01.000000000","message":"Done","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"}],"nova/virt/ironic/client_wrapper.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"d5025a99ad302afd4e8357f782ef621d7264cf91","unresolved":false,"context_lines":[{"line_number":32,"context_line":"IRONIC_GROUP \u003d nova.conf.ironic.ironic_group"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"# The API version required by the Ironic driver"},{"line_number":35,"context_line":"IRONIC_API_VERSION \u003d (1, 37)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class IronicClientWrapper(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_e4095c31","line":35,"updated":"2018-01-22 11:28:10.000000000","message":"Has this merged in Ironic yet? I am guess we need a depends on here?\n\nHow does this work with old ironic clients that don\u0027t support 1.37? Should we not depends-on the requirements bump here too?","commit_id":"3d47e1643a8b69a03957cb0556d9a8d92338811a"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"3c8ea5afe3dbb3e03e1bfa42c3acf9a293d44425","unresolved":false,"context_lines":[{"line_number":32,"context_line":"IRONIC_GROUP \u003d nova.conf.ironic.ironic_group"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"# The API version required by the Ironic driver"},{"line_number":35,"context_line":"IRONIC_API_VERSION \u003d (1, 37)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class IronicClientWrapper(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_b0870bb7","line":35,"in_reply_to":"7f96bb07_e4095c31","updated":"2018-01-22 15:52:43.000000000","message":"So nova doesn\u0027t directly require python-ironicclient, I guess because it\u0027s a driver dependency, rather than core. There isn\u0027t a requirements change to depend on yet.\n\n1.35 is already a Queens microversion, so I guess a Depends-On on the client change should be enough?","commit_id":"3d47e1643a8b69a03957cb0556d9a8d92338811a"}],"nova/virt/ironic/driver.py":[{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"9f1ed0bb5d084fd25bbd3edeb6ad4910883ec325","unresolved":false,"context_lines":[{"line_number":826,"context_line":"        # on the traits."},{"line_number":827,"context_line":"        if not hasattr(node, \u0027traits\u0027):"},{"line_number":828,"context_line":"            return set()"},{"line_number":829,"context_line":"        return set(node.traits)"},{"line_number":830,"context_line":""},{"line_number":831,"context_line":"    def get_available_resource(self, nodename):"},{"line_number":832,"context_line":"        \"\"\"Retrieve resource information."}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_af5de147","line":829,"updated":"2018-01-17 17:22:57.000000000","message":"Don\u0027t return set()s, as they don\u0027t serialise.","commit_id":"7aa12dd3638662f4f7a1db40fd0b5eb0b77797f9"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4fd9df5846c129f63e51ec4658fa2d6e20598e05","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_d9af7292","line":79,"updated":"2018-01-25 20:08:03.000000000","message":"I think we need to add \u0027traits\u0027 here.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5e5db51b43ab69b88f8a4dfbacf36207f71faae4","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_6d75e5ca","line":79,"in_reply_to":"5f93b717_0446b850","updated":"2018-01-30 01:24:32.000000000","message":"Mark, thx for digging into this! What\u0027s the best way to keep track of this list of things-to-do?","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"7a2570e4301e119d772cd090118b039ad352da89","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_9e845960","line":79,"in_reply_to":"5f93b717_189861be","updated":"2018-01-26 13:43:14.000000000","message":"I was feeling pretty bad about this, because it implies that this code completely fails to do what is intended.\n\nI looked into how the unit tests could pick up on it, and changed the utils.get_test_node() function to return only the fields in _NODE_FIELDS. Turns out there are quite a few failures when this is done, as resource_class is not in _NODE_FIELDS, and is used in various places. Also, instance_info is used in _parse_node_instance_info (although this is no longer in use and should be removed).\n\nTo be sure, I dumped a node from the cache to logs [1] on a live system, and verified that it does include all fields.\n\nSo I think we have a few things to do here, not of which are critical.\n\n* Add resource_class to _NODE_FIELDS.\n* Fix the field filtering to reduce memory footprint of cached nodes.\n* Improve unit tests to use representative filtered node objects.\n* Remove _parse_node_instance_info and associated tests.\n\n[1] http://paste.openstack.org/show/653579/","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"f000a50c0ce2633bdfcdb080e6c21b0f72dc5d05","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_b9b70687","line":79,"in_reply_to":"5f93b717_19e2bad6","updated":"2018-01-25 20:21:01.000000000","message":"Done","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"f1ac408f937c885087122228f630414b52b6a1aa","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_acf0c6fe","line":79,"in_reply_to":"5f93b717_6d75e5ca","updated":"2018-01-30 09:49:43.000000000","message":"Good point. \"Mark\u0027s head\" is probably not the right answer. I\u0027ll raise a bug and list them there, since the missing resource_class is definitely a bug.\n\nI\u0027ve got code to do most of these, but was waiting for Zuul to calm down before proposing.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"2b24616165afa30121fa1c1ea63ba6db7947c068","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_0446b850","line":79,"in_reply_to":"5f93b717_9e845960","updated":"2018-01-26 14:56:54.000000000","message":"After some investigation, the reason for this working most of the time is that nodes typically enter the cache via driver._refresh_cache(), which does a detailed list of the ironic nodes. That method gets called by get_available_resources(), which is in turn called by the compute manager\u0027s periodic resource sync, update_available_resource().\n\nSo add to the above list:\n\n* Filter the node list in _refresh_cache using _NODE_FIELDS.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"b2497627bfbe491e82410e5927887d267262332e","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_efd48022","line":79,"in_reply_to":"5f93b717_acf0c6fe","updated":"2018-01-30 10:38:11.000000000","message":"Bug raised here: https://bugs.launchpad.net/nova/+bug/1746209","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"93ab4a5cd1226a3f4e922b700789d698cbe2e10d","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_189861be","line":79,"in_reply_to":"5f93b717_b9b70687","updated":"2018-01-26 11:50:16.000000000","message":"Oh man, that was quite an oversight.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"e8f877341c83f943fab1d2e9ae2d00d5f42a7890","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_19e2bad6","line":79,"in_reply_to":"5f93b717_d9af7292","updated":"2018-01-25 20:11:14.000000000","message":"+1","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b23f4e1bf5c4625556664c361fda6350dc335a65","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"_NODE_FIELDS \u003d (\u0027uuid\u0027, \u0027power_state\u0027, \u0027target_power_state\u0027, \u0027provision_state\u0027,"},{"line_number":78,"context_line":"                \u0027target_provision_state\u0027, \u0027last_error\u0027, \u0027maintenance\u0027,"},{"line_number":79,"context_line":"                \u0027properties\u0027, \u0027instance_uuid\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"# Console state checking interval in seconds"},{"line_number":82,"context_line":"_CONSOLE_STATE_CHECKING_INTERVAL \u003d 1"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_5b02160d","line":79,"in_reply_to":"5f93b717_efd48022","updated":"2018-01-30 14:07:36.000000000","message":"Thx Mark! You following up and doing it was a good enough answer for me :)","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4fd9df5846c129f63e51ec4658fa2d6e20598e05","unresolved":false,"context_lines":[{"line_number":816,"context_line":"    def get_traits(self, nodename):"},{"line_number":817,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        :param nodename: the name of the node."},{"line_number":820,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":821,"context_line":"        \"\"\""},{"line_number":822,"context_line":"        node \u003d self._node_from_cache(nodename)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_5918421c","line":819,"updated":"2018-01-25 20:08:03.000000000","message":"nit for Ed Leafe (I think) because there was confusion as to what this was. Some other places have:\n\nThe UUID of the node. Parameter is called nodename even though it is a UUID to keep method signature the same as inherited class.\n\nIt\u0027s probably sufficient to just say the \u0027UUID of the node\u0027 ?","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"e8f877341c83f943fab1d2e9ae2d00d5f42a7890","unresolved":false,"context_lines":[{"line_number":816,"context_line":"    def get_traits(self, nodename):"},{"line_number":817,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        :param nodename: the name of the node."},{"line_number":820,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":821,"context_line":"        \"\"\""},{"line_number":822,"context_line":"        node \u003d self._node_from_cache(nodename)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_79d09ef8","line":819,"in_reply_to":"5f93b717_5918421c","updated":"2018-01-25 20:11:14.000000000","message":"+1, it will always be a UUID. Probably just a copy/paste thing.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"00e14618c47c4c0e786351d46ed64db004ec8d1f","unresolved":false,"context_lines":[{"line_number":816,"context_line":"    def get_traits(self, nodename):"},{"line_number":817,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        :param nodename: the name of the node."},{"line_number":820,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":821,"context_line":"        \"\"\""},{"line_number":822,"context_line":"        node \u003d self._node_from_cache(nodename)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_d9ebf2ad","line":819,"in_reply_to":"5f93b717_5918421c","updated":"2018-01-25 20:13:03.000000000","message":"The docstring is just being copied from the parent class:\n\nhttps://review.openstack.org/#/c/532290/8/nova/virt/driver.py@816\n\nI\u0027d be fine with making this ironic-specific though since yes it\u0027s the uuid of the node.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"f000a50c0ce2633bdfcdb080e6c21b0f72dc5d05","unresolved":false,"context_lines":[{"line_number":816,"context_line":"    def get_traits(self, nodename):"},{"line_number":817,"context_line":"        \"\"\"Get the traits for a given node."},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        :param nodename: the name of the node."},{"line_number":820,"context_line":"        :returns: an iterable of traits for the supplied node."},{"line_number":821,"context_line":"        \"\"\""},{"line_number":822,"context_line":"        node \u003d self._node_from_cache(nodename)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_19c39aef","line":819,"in_reply_to":"5f93b717_d9ebf2ad","updated":"2018-01-25 20:21:01.000000000","message":"Done","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"ca7f59f6f894073f139f2af932f201a500ca0b3f","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # attribute when we depend on an ironic client version with support for"},{"line_number":825,"context_line":"        # traits."},{"line_number":826,"context_line":"        if not hasattr(node, \u0027traits\u0027):"},{"line_number":827,"context_line":"            return []"},{"line_number":828,"context_line":"        return list(node.traits)"},{"line_number":829,"context_line":""},{"line_number":830,"context_line":"    def get_available_resource(self, nodename):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_f9d26e34","line":827,"updated":"2018-01-25 20:05:03.000000000","message":"Need to drop this before merging, but after the client release and g-r update.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"f000a50c0ce2633bdfcdb080e6c21b0f72dc5d05","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # attribute when we depend on an ironic client version with support for"},{"line_number":825,"context_line":"        # traits."},{"line_number":826,"context_line":"        if not hasattr(node, \u0027traits\u0027):"},{"line_number":827,"context_line":"            return []"},{"line_number":828,"context_line":"        return list(node.traits)"},{"line_number":829,"context_line":""},{"line_number":830,"context_line":"    def get_available_resource(self, nodename):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_f9bd8e68","line":827,"in_reply_to":"5f93b717_f9134eb7","updated":"2018-01-25 20:21:01.000000000","message":"Done","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"d643b08143c597eb02a09433a2bb641f4d474b8b","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # attribute when we depend on an ironic client version with support for"},{"line_number":825,"context_line":"        # traits."},{"line_number":826,"context_line":"        if not hasattr(node, \u0027traits\u0027):"},{"line_number":827,"context_line":"            return []"},{"line_number":828,"context_line":"        return list(node.traits)"},{"line_number":829,"context_line":""},{"line_number":830,"context_line":"    def get_available_resource(self, nodename):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f93b717_f9134eb7","line":827,"in_reply_to":"5f93b717_f9d26e34","updated":"2018-01-25 20:14:04.000000000","message":"I was thinking that we could do this later, after this has merged and everything is good, but as Jim mentioned -- it masked the problem I noted above.","commit_id":"ea55dd2d1107562ae135ae0bc5fb908de68af0fc"}]}
