)]}'
{"ironic/conductor/manager.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e74cd0be75ab1a475b5f75eb3b9bfbf4e3e38324","unresolved":false,"context_lines":[{"line_number":388,"context_line":""},{"line_number":389,"context_line":"            if driver_method not in task.driver.vendor.vendor_routes:"},{"line_number":390,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":391,"context_line":"                    _(\u0027No handler for method %s\u0027) % driver_method)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"            task.driver.vendor.validate(task, method\u003ddriver_method,"},{"line_number":394,"context_line":"                                        **info)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9aa7fdbe_168f83cd","line":391,"updated":"2014-10-22 08:44:10.000000000","message":"This duplicates code in the base class and is encapsulation violation that prevents you from overriding base implementation in utils.py.","commit_id":"71059ad0bbdb55c431641bd343c8f69b87ffb88f"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e74cd0be75ab1a475b5f75eb3b9bfbf4e3e38324","unresolved":false,"context_lines":[{"line_number":432,"context_line":""},{"line_number":433,"context_line":"        if driver_method not in driver.vendor.driver_routes:"},{"line_number":434,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":435,"context_line":"                _(\u0027No handler for method %s\u0027) % driver_method)"},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"        return driver.vendor.driver_vendor_passthru(context,"},{"line_number":438,"context_line":"                                                    method\u003ddriver_method,"}],"source_content_type":"text/x-python","patch_set":6,"id":"9aa7fdbe_36bd6769","line":435,"updated":"2014-10-22 08:44:10.000000000","message":"ditto","commit_id":"71059ad0bbdb55c431641bd343c8f69b87ffb88f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":352,"context_line":"                             task, new_state)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"    def _vendor_passthru(self, task_or_context, method, routes_map\u003dNone,"},{"line_number":355,"context_line":"                         **kwargs):"},{"line_number":356,"context_line":"        \"\"\"Receive requests for vendor-specific actions."},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"        :param task_or_context: a task object or an admin context."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_7e940fe2","line":355,"updated":"2014-10-22 20:48:18.000000000","message":"I\u0027m not sure I like this being in the ConductorManager. It seems like it belongs more with the driver code. Do you see an advantage for this being here?","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":352,"context_line":"                             task, new_state)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"    def _vendor_passthru(self, task_or_context, method, routes_map\u003dNone,"},{"line_number":355,"context_line":"                         **kwargs):"},{"line_number":356,"context_line":"        \"\"\"Receive requests for vendor-specific actions."},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"        :param task_or_context: a task object or an admin context."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_c5e43ee3","line":355,"in_reply_to":"9aa7fdbe_7e940fe2","updated":"2014-10-23 09:47:27.000000000","message":"Right in the VendorInterface? The plan was to make the function invoking the vendor methods generic so that vendors don\u0027t need to implement their own every time they want to expose a new vendor method and also having a generic one we would take care of logging erros and converting non-ironic exceptions to Ironic exceptions. I could add a new method in the VendorInterface to do that, but I just didn\u0027t cause I don\u0027t see reason why someone would need to overwrite this method anymore, so I just think that having it in the conductor is fine since it always will be called from the conductor.\n\nLemme know if that makes sense","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":432,"context_line":"                LOG.warning(_LW(\"Drivers implementing their own version \""},{"line_number":433,"context_line":"                                \"of vendor_passthru() has been deprecated. \""},{"line_number":434,"context_line":"                                \"Please update the code to use the new \""},{"line_number":435,"context_line":"                                \"vendor mechanism\"))"},{"line_number":436,"context_line":"                task.driver.vendor.validate(task, method\u003ddriver_method,"},{"line_number":437,"context_line":"                                            **info)"},{"line_number":438,"context_line":"                task.spawn_after(self._spawn_worker,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_3eb1a78f","line":435,"updated":"2014-10-22 20:48:18.000000000","message":"Maybe be more specific as to what the \u0027new vendor mechanism\u0027 might be, eg \u0027use VendorInterface.vendor_routes() instead of the deprecated VendorInterface.vendor_passthru()\u0027.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":432,"context_line":"                LOG.warning(_LW(\"Drivers implementing their own version \""},{"line_number":433,"context_line":"                                \"of vendor_passthru() has been deprecated. \""},{"line_number":434,"context_line":"                                \"Please update the code to use the new \""},{"line_number":435,"context_line":"                                \"vendor mechanism\"))"},{"line_number":436,"context_line":"                task.driver.vendor.validate(task, method\u003ddriver_method,"},{"line_number":437,"context_line":"                                            **info)"},{"line_number":438,"context_line":"                task.spawn_after(self._spawn_worker,"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_e2e698af","line":435,"in_reply_to":"9aa7fdbe_3eb1a78f","updated":"2014-10-23 09:47:27.000000000","message":"+1","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":440,"context_line":"                                 method\u003ddriver_method, **info)"},{"line_number":441,"context_line":"                return"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":444,"context_line":"            if driver_method not in vendor_routes:"},{"line_number":445,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":446,"context_line":"                    _(\u0027No handler for method %s\u0027) % driver_method)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_be64b722","line":443,"updated":"2014-10-22 20:48:18.000000000","message":"Would it be better to not expose vendor_routes (and driver_routes) outside of the drivers? And instead, have VendorInterface methods that can be called instead, eg VendorInterface.has_driver_method(method)","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":440,"context_line":"                                 method\u003ddriver_method, **info)"},{"line_number":441,"context_line":"                return"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":444,"context_line":"            if driver_method not in vendor_routes:"},{"line_number":445,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":446,"context_line":"                    _(\u0027No handler for method %s\u0027) % driver_method)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_c2f51458","line":443,"in_reply_to":"9aa7fdbe_43212bfa","updated":"2014-10-23 09:47:27.000000000","message":"+1 yeah I\u0027m having a hard time with trying to keep the backwards compability here. About the spec yes I will put one up about this changes.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0b8252662293e18117439558b7937af00f081f60","unresolved":false,"context_lines":[{"line_number":440,"context_line":"                                 method\u003ddriver_method, **info)"},{"line_number":441,"context_line":"                return"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":444,"context_line":"            if driver_method not in vendor_routes:"},{"line_number":445,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":446,"context_line":"                    _(\u0027No handler for method %s\u0027) % driver_method)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_43212bfa","line":443,"in_reply_to":"9aa7fdbe_be64b722","updated":"2014-10-23 08:15:49.000000000","message":"heh, we had a heated discussion on this yesterday (and it does deserve a spec). the problem with encapsulating everything in VendorInterface (while 100% correct in theory) is in backward compatibility. So your has_driver_method(method) should be able to deal with both new driver (via vendor_routes) and old ones (via vendor_passthru, but how?). Or include hacks like on #431. The same goes for determining if call is sync or async (see next patch).","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":495,"context_line":"            LOG.warning(_LW(\"Drivers implementing their own version \""},{"line_number":496,"context_line":"                            \"of driver_vendor_passthru() has been \""},{"line_number":497,"context_line":"                            \"deprecated. Please update the code to use \""},{"line_number":498,"context_line":"                            \"the new vendor mechanism\"))"},{"line_number":499,"context_line":"            return driver.vendor.driver_vendor_passthru("},{"line_number":500,"context_line":"                            context, method\u003ddriver_method, **info)"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_fe6e3f00","line":498,"updated":"2014-10-22 20:48:18.000000000","message":"Maybe be more specific as to what the \u0027new vendor mechanism\u0027 might be, eg \u0027use VendorInterface.driver_routes() instead of the deprecated VendorInterface.driver_vendor_passthru()\u0027.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":495,"context_line":"            LOG.warning(_LW(\"Drivers implementing their own version \""},{"line_number":496,"context_line":"                            \"of driver_vendor_passthru() has been \""},{"line_number":497,"context_line":"                            \"deprecated. Please update the code to use \""},{"line_number":498,"context_line":"                            \"the new vendor mechanism\"))"},{"line_number":499,"context_line":"            return driver.vendor.driver_vendor_passthru("},{"line_number":500,"context_line":"                            context, method\u003ddriver_method, **info)"},{"line_number":501,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_02a39c4f","line":498,"in_reply_to":"9aa7fdbe_fe6e3f00","updated":"2014-10-23 09:47:27.000000000","message":"+1","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"cf961d3be4db740cef40d4d80170b68e9f6982fd","unresolved":false,"context_lines":[{"line_number":505,"context_line":"                _(\u0027No handler for method %s\u0027) % driver_method)"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        return self._vendor_passthru(context, driver_method,"},{"line_number":508,"context_line":"                                     driver_routes, **info)"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"    def _provisioning_error_handler(self, e, node, provision_state,"},{"line_number":511,"context_line":"                                    target_provision_state):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_bca82878","line":508,"updated":"2014-10-23 15:34:32.000000000","message":"What do you think about having a VendorPassthru method that returns the dict associated with the driver_method (or raises InvalidParameterValue). Then the dict could be used/passed around to _vendor_passthru. That way, it doesn\u0027t need to know about driver_routes or vendor_routes dictionaries.\n\n[Or maybe the code will evolve that way anyway.]","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0712b40f64767da3fb4f940997ae243aa20f6e40","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        except KeyError:"},{"line_number":470,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":471,"context_line":"                _(\u0027No handler for method %s\u0027) % driver_method)"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"        return vendor_func(context, **info)"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"    def _provisioning_error_handler(self, e, node, provision_state,"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_e2bfebfa","line":472,"updated":"2014-10-29 12:05:01.000000000","message":"why no validate here?","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4770fc4d2d1e70a1100f06abd919654de6648011","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        except KeyError:"},{"line_number":470,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":471,"context_line":"                _(\u0027No handler for method %s\u0027) % driver_method)"},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"        return vendor_func(context, **info)"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"    def _provisioning_error_handler(self, e, node, provision_state,"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_434a6f56","line":472,"in_reply_to":"9aa7fdbe_e2bfebfa","updated":"2014-10-29 18:31:14.000000000","message":"It never had a validate and I suspect it\u0027s because we don\u0027t have a task object to pass to the validate method :/ which is what it\u0027s expecting.\n\nI would consider it a bug, but I don\u0027t think it worth fixing in this patch here.","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"}],"ironic/drivers/base.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"1c4da75798d1da6f61f0be7c4e7ce58d40e412fe","unresolved":false,"context_lines":[{"line_number":393,"context_line":"                 the supported interfaces."},{"line_number":394,"context_line":"        :raises: InvalidParameterValue if kwargs does not contain \u0027method\u0027."},{"line_number":395,"context_line":"        :raises: MissingParameterValue when a required parameter is missing"},{"line_number":396,"context_line":"        \"\"\""},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"    @abc.abstractproperty"},{"line_number":399,"context_line":"    def vendor_routes(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"baa201ad_94012fb1","line":396,"updated":"2014-10-17 14:16:19.000000000","message":"I expected the default implementation here, taking function from vendor_routes","commit_id":"206a57c8496fb4a913ddd4a942dc3de05574ff77"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"1c4da75798d1da6f61f0be7c4e7ce58d40e412fe","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        \"\"\""},{"line_number":419,"context_line":"        raise exception.UnsupportedDriverExtension("},{"line_number":420,"context_line":"            _(\u0027Vendor interface does not support driver vendor_passthru \u0027"},{"line_number":421,"context_line":"              \u0027method: %s\u0027) % method)"},{"line_number":422,"context_line":""},{"line_number":423,"context_line":"    @property"},{"line_number":424,"context_line":"    def driver_routes(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"baa201ad_74f68bd8","line":421,"updated":"2014-10-17 14:16:19.000000000","message":"I expected the default implementation here, taking function from driver_routes","commit_id":"206a57c8496fb4a913ddd4a942dc3de05574ff77"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4bab90978cc9b80707a6f4dbc8440b7a94160cce","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        \"\"\""},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    @abc.abstractmethod"},{"line_number":386,"context_line":"    def vendor_passthru(self, task, **kwargs):"},{"line_number":387,"context_line":"        \"\"\"Receive requests for vendor-specific actions."},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        :param task: a task from TaskManager."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_279025ec","side":"PARENT","line":386,"updated":"2014-10-20 02:45:37.000000000","message":"Why remove abstractmethod here?","commit_id":"504ca9f04f886e1247a7f9e03a420b6bab22fb51"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        \"\"\""},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    @abc.abstractmethod"},{"line_number":386,"context_line":"    def vendor_passthru(self, task, **kwargs):"},{"line_number":387,"context_line":"        \"\"\"Receive requests for vendor-specific actions."},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        :param task: a task from TaskManager."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_0a86c1b9","side":"PARENT","line":386,"in_reply_to":"9aa7fdbe_07931ca4","updated":"2014-10-20 10:08:03.000000000","message":"yeah as @Dmitry said, it now has a default implementation so it should not be implemented in the classes inheriting  from BaseDriver","commit_id":"504ca9f04f886e1247a7f9e03a420b6bab22fb51"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        \"\"\""},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"    @abc.abstractmethod"},{"line_number":386,"context_line":"    def vendor_passthru(self, task, **kwargs):"},{"line_number":387,"context_line":"        \"\"\"Receive requests for vendor-specific actions."},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        :param task: a task from TaskManager."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_07931ca4","side":"PARENT","line":386,"in_reply_to":"9aa7fdbe_279025ec","updated":"2014-10-20 08:34:27.000000000","message":"because it has a default implementation now","commit_id":"504ca9f04f886e1247a7f9e03a420b6bab22fb51"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":398,"context_line":"        :raises: MissingParameterValue when a required parameter is missing"},{"line_number":399,"context_line":"        \"\"\""},{"line_number":400,"context_line":"        method \u003d kwargs[\u0027method\u0027]"},{"line_number":401,"context_line":"        func \u003d self.vendor_routes[method]"},{"line_number":402,"context_line":"        try:"},{"line_number":403,"context_line":"            return func(task, **kwargs)"},{"line_number":404,"context_line":"        except exception.IronicException as e:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_27e74042","line":401,"updated":"2014-10-20 08:34:27.000000000","message":"KeyError should be handled here","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":398,"context_line":"        :raises: MissingParameterValue when a required parameter is missing"},{"line_number":399,"context_line":"        \"\"\""},{"line_number":400,"context_line":"        method \u003d kwargs[\u0027method\u0027]"},{"line_number":401,"context_line":"        func \u003d self.vendor_routes[method]"},{"line_number":402,"context_line":"        try:"},{"line_number":403,"context_line":"            return func(task, **kwargs)"},{"line_number":404,"context_line":"        except exception.IronicException as e:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_2afc653e","line":401,"in_reply_to":"9aa7fdbe_27e74042","updated":"2014-10-20 10:08:03.000000000","message":"Right I can handle it here, but the idea was that the conductor will test whether the method exist or not before calling it[1], so I don\u0027t see how it\u0027s going to be raised.\n\n[1] https://review.openstack.org/#/c/129261/4/ironic/conductor/manager.py","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"4bab90978cc9b80707a6f4dbc8440b7a94160cce","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            LOG.exception(_LE(\u0027vendor_passthru failed with method %s\u0027), method)"},{"line_number":410,"context_line":"            raise exception.VendorPassthruException(message\u003de)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"    @abc.abstractproperty"},{"line_number":413,"context_line":"    def vendor_routes(self):"},{"line_number":414,"context_line":"        \"\"\"Return the supported methods of the node vendor interface."},{"line_number":415,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_47bc496d","line":412,"updated":"2014-10-20 02:45:37.000000000","message":"Making this an abstract property means that all driver classe inheriting from this base class must be updated to implement this method, or they will fail to load when this patch is applied.\n\nThus, this change is immediately braeking backwards cmopatibility.","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            LOG.exception(_LE(\u0027vendor_passthru failed with method %s\u0027), method)"},{"line_number":410,"context_line":"            raise exception.VendorPassthruException(message\u003de)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"    @abc.abstractproperty"},{"line_number":413,"context_line":"    def vendor_routes(self):"},{"line_number":414,"context_line":"        \"\"\"Return the supported methods of the node vendor interface."},{"line_number":415,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_87ee2c21","line":412,"in_reply_to":"9aa7fdbe_47bc496d","updated":"2014-10-20 08:34:27.000000000","message":"I think it should just return {} and let vendor_passthru default implementation fail with UnsupportedVendorExtension (or how is it called?)","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            LOG.exception(_LE(\u0027vendor_passthru failed with method %s\u0027), method)"},{"line_number":410,"context_line":"            raise exception.VendorPassthruException(message\u003de)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":"    @abc.abstractproperty"},{"line_number":413,"context_line":"    def vendor_routes(self):"},{"line_number":414,"context_line":"        \"\"\"Return the supported methods of the node vendor interface."},{"line_number":415,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_6ac74d13","line":412,"in_reply_to":"9aa7fdbe_87ee2c21","updated":"2014-10-20 10:08:03.000000000","message":"+1 to remove the abstract decorator\n\n@Dmitry yeah I will make it return {}, the conductor already returns UnsupportedDriverExtension if the vendor interface is not present[1], I think that just returning an empty dict here is enough because it will raise InvalidParameterValue for all methods telling that the method is not handled by the vendor interface, which is fair enough IMO since none methods are supported.\n\n[1] https://github.com/openstack/ironic/blob/master/ironic/conductor/manager.py#L383-L387","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":430,"context_line":"        :param method: an arbitrary string describing the action to be taken."},{"line_number":431,"context_line":"        :param kwargs: arbitrary parameters to the passthru method."},{"line_number":432,"context_line":"        \"\"\""},{"line_number":433,"context_line":"        func \u003d self.driver_routes[method]"},{"line_number":434,"context_line":"        try:"},{"line_number":435,"context_line":"            return func(context, **kwargs)"},{"line_number":436,"context_line":"        except exception.IronicException as e:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_47e4443b","line":433,"updated":"2014-10-20 08:34:27.000000000","message":"KeyError should be handled here","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":430,"context_line":"        :param method: an arbitrary string describing the action to be taken."},{"line_number":431,"context_line":"        :param kwargs: arbitrary parameters to the passthru method."},{"line_number":432,"context_line":"        \"\"\""},{"line_number":433,"context_line":"        func \u003d self.driver_routes[method]"},{"line_number":434,"context_line":"        try:"},{"line_number":435,"context_line":"            return func(context, **kwargs)"},{"line_number":436,"context_line":"        except exception.IronicException as e:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_6a958de3","line":433,"in_reply_to":"9aa7fdbe_47e4443b","updated":"2014-10-20 10:08:03.000000000","message":"ditto L401","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e74cd0be75ab1a475b5f75eb3b9bfbf4e3e38324","unresolved":false,"context_lines":[{"line_number":404,"context_line":"            return func(task, **kwargs)"},{"line_number":405,"context_line":"        except KeyError:"},{"line_number":406,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":407,"context_line":"                _(\u0027No handler for method %s\u0027) % method)"},{"line_number":408,"context_line":"        except exception.IronicException as e:"},{"line_number":409,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":410,"context_line":"                LOG.exception(_LE(\u0027vendor_passthru failed with method %s\u0027),"}],"source_content_type":"text/x-python","patch_set":6,"id":"9aa7fdbe_36ef2789","line":407,"updated":"2014-10-22 08:44:10.000000000","message":"I don\u0027t like it handling any KeyError from vendor function, better:\n\n try:\n    func \u003d self.vendor_routes[method]\n except KeyError:\n    ...\n \n try:\n   ....","commit_id":"71059ad0bbdb55c431641bd343c8f69b87ffb88f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    Additional vendor- or driver-specific capabilities should be"},{"line_number":354,"context_line":"    implemented as private methods and added to the vendor_routes()"},{"line_number":355,"context_line":"    or driver_routes() maps."},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    driver calls are a blocking calls - methods implemented here should"},{"line_number":358,"context_line":"    be short-lived."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_9e7d33b4","line":355,"updated":"2014-10-22 20:48:18.000000000","message":"I don\u0027t know if this is clearer: \u0027... added to the dictionary returned by vendor_routes() or driver_routes()\u0027.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    Additional vendor- or driver-specific capabilities should be"},{"line_number":354,"context_line":"    implemented as private methods and added to the vendor_routes()"},{"line_number":355,"context_line":"    or driver_routes() maps."},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    driver calls are a blocking calls - methods implemented here should"},{"line_number":358,"context_line":"    be short-lived."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_c5da7e4b","line":355,"in_reply_to":"9aa7fdbe_9e7d33b4","updated":"2014-10-23 09:47:27.000000000","message":"+1","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":354,"context_line":"    implemented as private methods and added to the vendor_routes()"},{"line_number":355,"context_line":"    or driver_routes() maps."},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    driver calls are a blocking calls - methods implemented here should"},{"line_number":358,"context_line":"    be short-lived."},{"line_number":359,"context_line":"    \"\"\""},{"line_number":360,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_fe455f70","line":357,"updated":"2014-10-22 20:48:18.000000000","message":"nit: \u0027a blocking calls\u0027 -\u003e \u0027blocking calls\u0027","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":354,"context_line":"    implemented as private methods and added to the vendor_routes()"},{"line_number":355,"context_line":"    or driver_routes() maps."},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    driver calls are a blocking calls - methods implemented here should"},{"line_number":358,"context_line":"    be short-lived."},{"line_number":359,"context_line":"    \"\"\""},{"line_number":360,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_45e68e16","line":357,"in_reply_to":"9aa7fdbe_fe455f70","updated":"2014-10-23 09:47:27.000000000","message":"+1","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        :returns: dictionary of \u003cmethod name\u003e:\u003cmethod reference\u003e entries."},{"line_number":395,"context_line":"        \"\"\""},{"line_number":396,"context_line":"        return {}"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_c903870b","line":396,"updated":"2014-10-22 20:48:18.000000000","message":"I might need to think about this more; I think I\u0027m missing something. When I look at the code changes from here and in the driver modules, is there anything that needs to distinguish between vendor_routes and driver_routes? Ie, why not have one map for all of them?","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"cf961d3be4db740cef40d4d80170b68e9f6982fd","unresolved":false,"context_lines":[{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        :returns: dictionary of \u003cmethod name\u003e:\u003cmethod reference\u003e entries."},{"line_number":395,"context_line":"        \"\"\""},{"line_number":396,"context_line":"        return {}"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_3c7278ad","line":396,"in_reply_to":"9aa7fdbe_0355634f","updated":"2014-10-23 15:34:32.000000000","message":"True. @Lucas, maybe we should add something to the docstring to make it clear what the differences are between vendor_routes and driver_routes.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"ab68ce0b84b051fb5577cdf4b693d576e5ba4905","unresolved":false,"context_lines":[{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        :returns: dictionary of \u003cmethod name\u003e:\u003cmethod reference\u003e entries."},{"line_number":395,"context_line":"        \"\"\""},{"line_number":396,"context_line":"        return {}"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_b7a5a348","line":396,"in_reply_to":"9aa7fdbe_3c7278ad","updated":"2014-10-23 16:05:36.000000000","message":"will do","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0b8252662293e18117439558b7937af00f081f60","unresolved":false,"context_lines":[{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        :returns: dictionary of \u003cmethod name\u003e:\u003cmethod reference\u003e entries."},{"line_number":395,"context_line":"        \"\"\""},{"line_number":396,"context_line":"        return {}"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_0355634f","line":396,"in_reply_to":"9aa7fdbe_c903870b","updated":"2014-10-23 08:15:49.000000000","message":"at least we want to prevent user from calling driver_vendor_passthru as vendor_passthru and getting strange error due to wrong arguments (node vs context IIRC)","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0712b40f64767da3fb4f940997ae243aa20f6e40","unresolved":false,"context_lines":[{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"def register_driver_passthru(method):"},{"line_number":400,"context_line":"    return _register_passthru(method, driver_passthru\u003dTrue)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_42dc3719","line":400,"updated":"2014-10-29 12:05:01.000000000","message":"As in previous patch, I would prefer these to be called \"passthru\" and \"driver_passthru\", but anyway they don\u0027t register anything","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4770fc4d2d1e70a1100f06abd919654de6648011","unresolved":false,"context_lines":[{"line_number":397,"context_line":""},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"def register_driver_passthru(method):"},{"line_number":400,"context_line":"    return _register_passthru(method, driver_passthru\u003dTrue)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"@six.add_metaclass(abc.ABCMeta)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_837377b3","line":400,"in_reply_to":"9aa7fdbe_42dc3719","updated":"2014-10-29 18:31:14.000000000","message":"Done","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0712b40f64767da3fb4f940997ae243aa20f6e40","unresolved":false,"context_lines":[{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    Additional vendor- or driver-specific capabilities should be implemented as"},{"line_number":408,"context_line":"    private methods and invoked from vendor_passthru() or"},{"line_number":409,"context_line":"    driver_vendor_passthru()."},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"    driver_vendor_passthru() is a blocking call - methods implemented here"},{"line_number":412,"context_line":"    should be short-lived."}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_a2eb23af","line":409,"updated":"2014-10-29 12:05:01.000000000","message":"docstring should be updated","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4770fc4d2d1e70a1100f06abd919654de6648011","unresolved":false,"context_lines":[{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    Additional vendor- or driver-specific capabilities should be implemented as"},{"line_number":408,"context_line":"    private methods and invoked from vendor_passthru() or"},{"line_number":409,"context_line":"    driver_vendor_passthru()."},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"    driver_vendor_passthru() is a blocking call - methods implemented here"},{"line_number":412,"context_line":"    should be short-lived."}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_a3787b90","line":409,"in_reply_to":"9aa7fdbe_a2eb23af","updated":"2014-10-29 18:31:14.000000000","message":"Done","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        # in the following patches this is going to have more metadata"},{"line_number":378,"context_line":"        # about the vendor method. For e.g the supported HTTP methods and"},{"line_number":379,"context_line":"        # whether it should run asynchrounously or not."},{"line_number":380,"context_line":"        metadata \u003d (api_method, {})"},{"line_number":381,"context_line":"        if not driver_passthru:"},{"line_number":382,"context_line":"            func._vendor_metadata \u003d metadata"},{"line_number":383,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_7f046d15","line":380,"updated":"2014-10-30 13:28:32.000000000","message":"what about making it a namedtuple instead of rather vague data structure?","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        # in the following patches this is going to have more metadata"},{"line_number":378,"context_line":"        # about the vendor method. For e.g the supported HTTP methods and"},{"line_number":379,"context_line":"        # whether it should run asynchrounously or not."},{"line_number":380,"context_line":"        metadata \u003d (api_method, {})"},{"line_number":381,"context_line":"        if not driver_passthru:"},{"line_number":382,"context_line":"            func._vendor_metadata \u003d metadata"},{"line_number":383,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_f01c0a16","line":380,"in_reply_to":"7a8c0949_7f046d15","updated":"2014-10-30 15:00:29.000000000","message":"Good idea! Thanks","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        else:"},{"line_number":384,"context_line":"            func._driver_metadata \u003d metadata"},{"line_number":385,"context_line":""},{"line_number":386,"context_line":"        passthru_logmessage \u003d _LE(\u0027vendor_passthru failed with method %s\u0027)"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        @functools.wraps(func)"},{"line_number":389,"context_line":"        def passthru_handler(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_bf0ed532","line":386,"updated":"2014-10-30 13:28:32.000000000","message":"this can be a top-level constant","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":383,"context_line":"        else:"},{"line_number":384,"context_line":"            func._driver_metadata \u003d metadata"},{"line_number":385,"context_line":""},{"line_number":386,"context_line":"        passthru_logmessage \u003d _LE(\u0027vendor_passthru failed with method %s\u0027)"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        @functools.wraps(func)"},{"line_number":389,"context_line":"        def passthru_handler(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_d0cd4e88","line":386,"in_reply_to":"7a8c0949_bf0ed532","updated":"2014-10-30 15:00:29.000000000","message":"I suspect this should be fixed on the previous patch of this series? Since it\u0027s introduced there","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"03edcf02eb9a0f13f7e6bb5db597606964e821b0","unresolved":false,"context_lines":[{"line_number":444,"context_line":""},{"line_number":445,"context_line":"            if dmeta is not None:"},{"line_number":446,"context_line":"                dmeta.metadata[\u0027func\u0027] \u003d ref"},{"line_number":447,"context_line":"                self.driver_routes.update({dmeta.method: dmeta.metadata})"},{"line_number":448,"context_line":""},{"line_number":449,"context_line":"    @abc.abstractmethod"},{"line_number":450,"context_line":"    def get_properties(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a8c0949_a3ff7e33","line":447,"updated":"2014-10-31 18:10:00.000000000","message":"Could we move this logic into __new__ so that those extending VendorInterface don\u0027t have to remember to call super anytime they want to add some init code? \n\ndef __new__(cls, *args, **kwargs):\n    if not (hasattr(cls, \"vendor_routes\") and hasattr(cls \"driver_routes\")): \n        cls.vendor_routes \u003d {}\n        cls.driver_routes \u003d {}\n\n        for name, ref in inspect.getmembers(cls, predicate\u003dinspect.ismethod):\n            etc...\n\n    return super(VendorInterface, cls).__new__(cls, *args, **kwargs)\n\nThis way can also build in some performance improvements because its setting class variables, so we can check if they have been set already and not rebuild the lists every time.","commit_id":"9834e48514866c9ef140ca0b6fb1e3172db5a060"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5be627297f443a36e0dfa6373ff72fec456f13f7","unresolved":false,"context_lines":[{"line_number":444,"context_line":""},{"line_number":445,"context_line":"            if dmeta is not None:"},{"line_number":446,"context_line":"                dmeta.metadata[\u0027func\u0027] \u003d ref"},{"line_number":447,"context_line":"                self.driver_routes.update({dmeta.method: dmeta.metadata})"},{"line_number":448,"context_line":""},{"line_number":449,"context_line":"    @abc.abstractmethod"},{"line_number":450,"context_line":"    def get_properties(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a8c0949_c6b9f82f","line":447,"in_reply_to":"7a8c0949_a3ff7e33","updated":"2014-10-31 18:23:46.000000000","message":"It\u0027s a good suggestion but I would have to instantiate the class before, for e.g:\n\n def __new__(cls, *args, **kwargs):\n     inst \u003d super(VendorInterface, cls).__new__(cls, *args, **kwargs)\n\n     inst.vendor_routes \u003d {}\n     inst.driver_routes \u003d {}\n\n     for name, ref in inspect.getmembers(inst, predicate\u003dinspect.ismethod):\n         vmeta \u003d getattr(ref, \u0027_vendor_metadata\u0027, None)\n         dmeta \u003d getattr(ref, \u0027_driver_metadata\u0027, None)\n\n         if vmeta is not None:\n             vmeta.metadata[\u0027func\u0027] \u003d ref\n             inst.vendor_routes.update({vmeta.method: vmeta.metadata})\n\n         if dmeta is not None:\n             dmeta.metadata[\u0027func\u0027] \u003d ref\n             inst.driver_routes.update({dmeta.method: dmeta.metadata})\n\n     return inst\n\n\nThe reason is because metadata[\u0027func\u0027] should have a reference to a method from an instance and not a method definition, otherwise when I\u0027m calling it from the ConductorManager I would have to pass an instance as the first parameter to \u0027self\u0027, and things can get nasty when you work with the VendorMixIn.\n\nI will test doing that, and yeah if that works I think it\u0027s a good idea.","commit_id":"9834e48514866c9ef140ca0b6fb1e3172db5a060"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":373,"context_line":"    reraised, it won\u0027t be handled if it is an async. call."},{"line_number":374,"context_line":""},{"line_number":375,"context_line":"    :param method: an arbitrary string describing the action to be taken."},{"line_number":376,"context_line":"    :param driver_vendor_passthru: Boolean value. Whether this is a driver"},{"line_number":377,"context_line":"                                   vendor passthru or a node vendor passthru"},{"line_number":378,"context_line":"                                   method."},{"line_number":379,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_d22439b1","line":376,"updated":"2014-11-04 17:58:59.000000000","message":"Documented parameter name does not match actual parameter.","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":373,"context_line":"    reraised, it won\u0027t be handled if it is an async. call."},{"line_number":374,"context_line":""},{"line_number":375,"context_line":"    :param method: an arbitrary string describing the action to be taken."},{"line_number":376,"context_line":"    :param driver_vendor_passthru: Boolean value. Whether this is a driver"},{"line_number":377,"context_line":"                                   vendor passthru or a node vendor passthru"},{"line_number":378,"context_line":"                                   method."},{"line_number":379,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_dbfe5638","line":376,"in_reply_to":"7a8c0949_d22439b1","updated":"2014-11-10 10:18:45.000000000","message":"Done","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":388,"context_line":"        # about the vendor method. For e.g the supported HTTP methods and"},{"line_number":389,"context_line":"        # whether it should run asynchrounously or not."},{"line_number":390,"context_line":"        metadata \u003d VendorMetadata(api_method, {})"},{"line_number":391,"context_line":"        if not driver_passthru:"},{"line_number":392,"context_line":"            func._vendor_metadata \u003d metadata"},{"line_number":393,"context_line":"        else:"},{"line_number":394,"context_line":"            func._driver_metadata \u003d metadata"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_32357dda","line":391,"updated":"2014-11-04 17:58:59.000000000","message":"Just a nit, but why the \u0027not\u0027 here? I\u0027d find this easier to read if we removed the \u0027not\u0027 and reversed the logic.","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":388,"context_line":"        # about the vendor method. For e.g the supported HTTP methods and"},{"line_number":389,"context_line":"        # whether it should run asynchrounously or not."},{"line_number":390,"context_line":"        metadata \u003d VendorMetadata(api_method, {})"},{"line_number":391,"context_line":"        if not driver_passthru:"},{"line_number":392,"context_line":"            func._vendor_metadata \u003d metadata"},{"line_number":393,"context_line":"        else:"},{"line_number":394,"context_line":"            func._driver_metadata \u003d metadata"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_9bedae8e","line":391,"in_reply_to":"7a8c0949_32357dda","updated":"2014-11-10 10:18:45.000000000","message":"I don\u0027t know the reason why I added \u0027not\u0027 here, maybe looked easier to me to read when I was coding. I will revert the logic","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":427,"context_line":"    use the @passthru or @driver_passthru decorators."},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    Methods decorated with @driver_passthru should be short-lived because"},{"line_number":430,"context_line":"    it is a blocking call."},{"line_number":431,"context_line":"    \"\"\""},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"    def __new__(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_3291fd99","line":430,"updated":"2014-11-04 17:58:59.000000000","message":"Hmm. Would it be more clear if we renamed these decorators @async_passthru and @sync_passthru?","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"3aac15e67b6f4a6ba810dfb48bfa591331ecb42a","unresolved":false,"context_lines":[{"line_number":427,"context_line":"    use the @passthru or @driver_passthru decorators."},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    Methods decorated with @driver_passthru should be short-lived because"},{"line_number":430,"context_line":"    it is a blocking call."},{"line_number":431,"context_line":"    \"\"\""},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"    def __new__(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_52ba090b","line":430,"in_reply_to":"7a8c0949_3291fd99","updated":"2014-11-04 18:10:05.000000000","message":"Ignore that question. I should have looked ahead to the next review where the synchronous nature is indicated separately.  :)","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"}],"ironic/drivers/modules/agent.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"1c4da75798d1da6f61f0be7c4e7ce58d40e412fe","unresolved":false,"context_lines":[{"line_number":365,"context_line":"        if method not in self.driver_routes:"},{"line_number":366,"context_line":"            raise exception.InvalidParameterValue(_(\u0027No handler for method %s\u0027)"},{"line_number":367,"context_line":"                                                  % method)"},{"line_number":368,"context_line":"        func \u003d self.driver_routes[method]"},{"line_number":369,"context_line":"        return func(task, **kwargs)"},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"    def vendor_passthru(self, task, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"baa201ad_14dc5f45","line":368,"updated":"2014-10-17 14:16:19.000000000","message":"this should be gone","commit_id":"206a57c8496fb4a913ddd4a942dc3de05574ff77"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"1c4da75798d1da6f61f0be7c4e7ce58d40e412fe","unresolved":false,"context_lines":[{"line_number":391,"context_line":"            # catch-all in case something bubbles up here"},{"line_number":392,"context_line":"            # log this because even though the exception is being"},{"line_number":393,"context_line":"            # reraised, it won\u0027t be handled if it is an async. call."},{"line_number":394,"context_line":"            LOG.exception(_LE(\u0027vendor_passthru failed with method %s\u0027), method)"},{"line_number":395,"context_line":"            raise exception.VendorPassthruException(message\u003de)"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    def _heartbeat(self, task, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"baa201ad_74e4cb0c","line":394,"updated":"2014-10-17 14:16:19.000000000","message":"and all this","commit_id":"206a57c8496fb4a913ddd4a942dc3de05574ff77"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"cf961d3be4db740cef40d4d80170b68e9f6982fd","unresolved":false,"context_lines":[{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @property"},{"line_number":334,"context_line":"    def vendor_routes(self):"},{"line_number":335,"context_line":"        return {\u0027heartbeat\u0027: self._heartbeat}"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    @property"},{"line_number":338,"context_line":"    def driver_routes(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_3c9d185a","line":335,"updated":"2014-10-23 15:34:32.000000000","message":"I suppose in a different patch, you\u0027re going to change this value to be a dictionary. I\u0027m actually fine if you put in that plumbing now given that there\u0027s a spec ;)","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"ab68ce0b84b051fb5577cdf4b693d576e5ba4905","unresolved":false,"context_lines":[{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @property"},{"line_number":334,"context_line":"    def vendor_routes(self):"},{"line_number":335,"context_line":"        return {\u0027heartbeat\u0027: self._heartbeat}"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    @property"},{"line_number":338,"context_line":"    def driver_routes(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_972dffaa","line":335,"in_reply_to":"9aa7fdbe_3c9d185a","updated":"2014-10-23 16:05:36.000000000","message":"Yeah I think that now that we have a spec it makes sense to do it. I will the spec to get more reviews and/or be approved to make changes to this patch (saving some time/effort).","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":436,"context_line":"        node.save()"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"    @base.driver_passthru(method\u003d\u0027lookup\u0027)"},{"line_number":439,"context_line":"    def _lookup(self, context, **kwargs):"},{"line_number":440,"context_line":"        \"\"\"Find a matching node for the agent."},{"line_number":441,"context_line":""},{"line_number":442,"context_line":"        Method to be called the first time a ramdisk agent checks in. This"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_7f2b8d82","line":439,"updated":"2014-10-30 13:28:32.000000000","message":"I\u0027d prefer renaming to lookup","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":436,"context_line":"        node.save()"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"    @base.driver_passthru(method\u003d\u0027lookup\u0027)"},{"line_number":439,"context_line":"    def _lookup(self, context, **kwargs):"},{"line_number":440,"context_line":"        \"\"\"Find a matching node for the agent."},{"line_number":441,"context_line":""},{"line_number":442,"context_line":"        Method to be called the first time a ramdisk agent checks in. This"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_90abc688","line":439,"in_reply_to":"7a8c0949_7f2b8d82","updated":"2014-10-30 15:00:29.000000000","message":"right will do","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"}],"ironic/drivers/modules/fake.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        _raise_unsupported_error(method)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def _private_method(self, task, **kwargs):"},{"line_number":116,"context_line":"        bar \u003d kwargs.get(\u0027bar\u0027)"},{"line_number":117,"context_line":"        return True if bar \u003d\u003d \u0027baz\u0027 else False"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_a7ca509f","line":116,"updated":"2014-10-20 08:34:27.000000000","message":"this change is not needed, Python is smart enough IIRC","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        _raise_unsupported_error(method)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def _private_method(self, task, **kwargs):"},{"line_number":116,"context_line":"        bar \u003d kwargs.get(\u0027bar\u0027)"},{"line_number":117,"context_line":"        return True if bar \u003d\u003d \u0027baz\u0027 else False"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_aa6db506","line":116,"in_reply_to":"9aa7fdbe_a7ca509f","updated":"2014-10-20 10:08:03.000000000","message":"+1 yeah I wasn\u0027t sure, but it seems to work indeed","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        _raise_unsupported_error(method)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def _private_method(self, task, **kwargs):"},{"line_number":142,"context_line":"        bar \u003d kwargs.get(\u0027bar\u0027)"},{"line_number":143,"context_line":"        return True if bar \u003d\u003d \u0027kazoo\u0027 else False"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_e7c37888","line":142,"updated":"2014-10-20 08:34:27.000000000","message":"ditto","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        _raise_unsupported_error(method)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def _private_method(self, task, **kwargs):"},{"line_number":142,"context_line":"        bar \u003d kwargs.get(\u0027bar\u0027)"},{"line_number":143,"context_line":"        return True if bar \u003d\u003d \u0027kazoo\u0027 else False"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_ea76ddd7","line":142,"in_reply_to":"9aa7fdbe_e7c37888","updated":"2014-10-20 10:08:03.000000000","message":"+1 yeah I wasn\u0027t sure, but it seems to work indeed","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"}],"ironic/drivers/modules/ipmitool.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":809,"context_line":"        :raises:  InvalidParameterValue when an invalid value is specified."},{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        \"\"\""},{"line_number":812,"context_line":"        raw_bytes \u003d kwargs.get(\u0027raw_bytes\u0027)"},{"line_number":813,"context_line":"        node_uuid \u003d task.node.uuid"},{"line_number":814,"context_line":"        LOG.debug(\u0027Sending node %(node)s raw bytes %(bytes)s\u0027,"},{"line_number":815,"context_line":"                  {\u0027bytes\u0027: raw_bytes, \u0027node\u0027: node_uuid})"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_c7467423","line":812,"updated":"2014-10-20 08:34:27.000000000","message":"again, I doubt this change is needed. Python should be smart enough to unpack **kwargs into the correct argument","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":809,"context_line":"        :raises:  InvalidParameterValue when an invalid value is specified."},{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        \"\"\""},{"line_number":812,"context_line":"        raw_bytes \u003d kwargs.get(\u0027raw_bytes\u0027)"},{"line_number":813,"context_line":"        node_uuid \u003d task.node.uuid"},{"line_number":814,"context_line":"        LOG.debug(\u0027Sending node %(node)s raw bytes %(bytes)s\u0027,"},{"line_number":815,"context_line":"                  {\u0027bytes\u0027: raw_bytes, \u0027node\u0027: node_uuid})"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_aa44d574","line":812,"in_reply_to":"9aa7fdbe_c7467423","updated":"2014-10-20 10:08:03.000000000","message":"+1","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":838,"context_line":"        :raises: InvalidParameterValue when an invalid value is specified"},{"line_number":839,"context_line":""},{"line_number":840,"context_line":"        \"\"\""},{"line_number":841,"context_line":"        warm \u003d kwargs.get(\u0027warm\u0027, True)"},{"line_number":842,"context_line":"        node_uuid \u003d task.node.uuid"},{"line_number":843,"context_line":""},{"line_number":844,"context_line":"        if warm:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_07487c2c","line":841,"updated":"2014-10-20 08:34:27.000000000","message":"ditto","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":838,"context_line":"        :raises: InvalidParameterValue when an invalid value is specified"},{"line_number":839,"context_line":""},{"line_number":840,"context_line":"        \"\"\""},{"line_number":841,"context_line":"        warm \u003d kwargs.get(\u0027warm\u0027, True)"},{"line_number":842,"context_line":"        node_uuid \u003d task.node.uuid"},{"line_number":843,"context_line":""},{"line_number":844,"context_line":"        if warm:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_8a363102","line":841,"in_reply_to":"9aa7fdbe_07487c2c","updated":"2014-10-20 10:08:03.000000000","message":"This one I would have to at least add a default value for warm, cause the way it was passed was:\n\n return self._bmc_reset(task, warm\u003dkwargs.get(\u0027warm\u0027, True))","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":827,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":828,"context_line":""},{"line_number":829,"context_line":"    @task_manager.require_exclusive_lock"},{"line_number":830,"context_line":"    def _bmc_reset(self, task, warm\u003dTrue):"},{"line_number":831,"context_line":"        \"\"\"Reset BMC with IPMI command \u0027bmc reset (warm|cold)\u0027."},{"line_number":832,"context_line":""},{"line_number":833,"context_line":"        :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_691e1b65","line":830,"updated":"2014-10-22 20:48:18.000000000","message":"I don\u0027t think default arguments (warm\u003dTrue) is going to work. (I\u0027ll put a comment in test_ipmitool.py)","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":827,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":828,"context_line":""},{"line_number":829,"context_line":"    @task_manager.require_exclusive_lock"},{"line_number":830,"context_line":"    def _bmc_reset(self, task, warm\u003dTrue):"},{"line_number":831,"context_line":"        \"\"\"Reset BMC with IPMI command \u0027bmc reset (warm|cold)\u0027."},{"line_number":832,"context_line":""},{"line_number":833,"context_line":"        :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_c2519437","line":830,"in_reply_to":"9aa7fdbe_239fc751","updated":"2014-10-23 09:47:27.000000000","message":"In [1]: def test(hello, hi\u003dTrue):\n    ...:     print hello, hi\n    ...:     \n In [2]: kwargs \u003d {\u0027hi\u0027: False}\n In [3]: test(\"aaaa\", **kwargs)\n aaaa False\n\nBut maybe it just looks a bit complicated, I can change to **kwargs that argument to make it simpler to make it more understandable.","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0b8252662293e18117439558b7937af00f081f60","unresolved":false,"context_lines":[{"line_number":827,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":828,"context_line":""},{"line_number":829,"context_line":"    @task_manager.require_exclusive_lock"},{"line_number":830,"context_line":"    def _bmc_reset(self, task, warm\u003dTrue):"},{"line_number":831,"context_line":"        \"\"\"Reset BMC with IPMI command \u0027bmc reset (warm|cold)\u0027."},{"line_number":832,"context_line":""},{"line_number":833,"context_line":"        :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_239fc751","line":830,"in_reply_to":"9aa7fdbe_691e1b65","updated":"2014-10-23 08:15:49.000000000","message":"manager uses\n\n return func(task_or_context, **kwargs)\n\nso they will, why not?","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"a242dc6236db760931435215119ab3e9108b8c05","unresolved":false,"context_lines":[{"line_number":827,"context_line":"            raise exception.IPMIFailure(cmd\u003dcmd)"},{"line_number":828,"context_line":""},{"line_number":829,"context_line":"    @task_manager.require_exclusive_lock"},{"line_number":830,"context_line":"    def _bmc_reset(self, task, warm\u003dTrue):"},{"line_number":831,"context_line":"        \"\"\"Reset BMC with IPMI command \u0027bmc reset (warm|cold)\u0027."},{"line_number":832,"context_line":""},{"line_number":833,"context_line":"        :param task: a TaskManager instance."}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_689d2766","line":830,"in_reply_to":"9aa7fdbe_c2519437","updated":"2014-10-23 10:40:49.000000000","message":"-1 to using **kwargs make anything simpler or understandable...","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"}],"ironic/drivers/modules/seamicro.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0712b40f64767da3fb4f940997ae243aa20f6e40","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        if method not in self.vendor_routes:"},{"line_number":419,"context_line":"            raise exception.InvalidParameterValue(_("},{"line_number":420,"context_line":"                \"Unsupported method (%s) passed to SeaMicro driver.\")"},{"line_number":421,"context_line":"                % method)"},{"line_number":422,"context_line":"        _parse_driver_info(task.node)"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"    @base.register_passthru(\u0027set_node_vlan_id\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_221c93c1","line":421,"updated":"2014-10-29 12:05:01.000000000","message":"should be moved out of here","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4770fc4d2d1e70a1100f06abd919654de6648011","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        if method not in self.vendor_routes:"},{"line_number":419,"context_line":"            raise exception.InvalidParameterValue(_("},{"line_number":420,"context_line":"                \"Unsupported method (%s) passed to SeaMicro driver.\")"},{"line_number":421,"context_line":"                % method)"},{"line_number":422,"context_line":"        _parse_driver_info(task.node)"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"    @base.register_passthru(\u0027set_node_vlan_id\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9aa7fdbe_e3ce03b4","line":421,"in_reply_to":"9aa7fdbe_221c93c1","updated":"2014-10-29 18:31:14.000000000","message":"Done","commit_id":"859d112932dc3bd17429013dae561ac318c5f9a1"}],"ironic/drivers/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8e2f0a6f51b9ba2576f85f30b928fbf7ea989c7c","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @property"},{"line_number":74,"context_line":"    def driver_routes(self):"},{"line_number":75,"context_line":"        return self._driver_routes"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_properties(self):"},{"line_number":78,"context_line":"        \"\"\"Return the properties from all the VendorInterfaces."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_672ce84b","line":75,"updated":"2014-10-20 08:34:27.000000000","message":"If vendor_routes and driver_routes are not abstract in base class, this class could be left as it was before.","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"dd933f8b9f8ab8cc4e7f7215db172078ca9bb5e8","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @property"},{"line_number":74,"context_line":"    def driver_routes(self):"},{"line_number":75,"context_line":"        return self._driver_routes"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_properties(self):"},{"line_number":78,"context_line":"        \"\"\"Return the properties from all the VendorInterfaces."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_d5f7fa8a","line":75,"in_reply_to":"9aa7fdbe_672ce84b","updated":"2014-10-20 10:08:03.000000000","message":"How would that work? it would return an empty dict all the time and in the conductor/manager.py it would fail with InvalidParameterValue","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"86b9c21435cf76c063f8478a58371355ab1bec14","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @property"},{"line_number":74,"context_line":"    def driver_routes(self):"},{"line_number":75,"context_line":"        return self._driver_routes"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_properties(self):"},{"line_number":78,"context_line":"        \"\"\"Return the properties from all the VendorInterfaces."}],"source_content_type":"text/x-python","patch_set":4,"id":"9aa7fdbe_dbd009fa","line":75,"in_reply_to":"9aa7fdbe_d5f7fa8a","updated":"2014-10-20 11:11:33.000000000","message":"that\u0027s why I\u0027m against checking it in the conductor: it breaks encapsulation.","commit_id":"778f6090f72ce7c5d8e528abe1e4d2f2a9384098"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"e74cd0be75ab1a475b5f75eb3b9bfbf4e3e38324","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @property"},{"line_number":79,"context_line":"    def driver_routes(self):"},{"line_number":80,"context_line":"        return self._driver_routes"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def get_properties(self):"},{"line_number":83,"context_line":"        \"\"\"Return the properties from all the VendorInterfaces."}],"source_content_type":"text/x-python","patch_set":6,"id":"9aa7fdbe_9671b3e2","line":80,"updated":"2014-10-22 08:44:10.000000000","message":"Again, this change is not required. It\u0027s only here because you decided to break encapsulation in manager.py.","commit_id":"71059ad0bbdb55c431641bd343c8f69b87ffb88f"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        self.driver_routes \u003d self._build_routes(self.driver_level_mapping,"},{"line_number":43,"context_line":"                                                driver_passthru\u003dTrue)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def _build_routes(self, map_dict, driver_passthru\u003dFalse):"},{"line_number":46,"context_line":"        d \u003d {}"},{"line_number":47,"context_line":"        for method_name in map_dict:"},{"line_number":48,"context_line":"            iface \u003d map_dict[method_name]"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_d2a999e0","line":45,"updated":"2014-11-04 17:58:59.000000000","message":"Do we want a docstring here?","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        self.driver_routes \u003d self._build_routes(self.driver_level_mapping,"},{"line_number":43,"context_line":"                                                driver_passthru\u003dTrue)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def _build_routes(self, map_dict, driver_passthru\u003dFalse):"},{"line_number":46,"context_line":"        d \u003d {}"},{"line_number":47,"context_line":"        for method_name in map_dict:"},{"line_number":48,"context_line":"            iface \u003d map_dict[method_name]"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_db8576ae","line":45,"in_reply_to":"7a8c0949_d2a999e0","updated":"2014-11-10 10:18:45.000000000","message":"I will add a docstring, but these are private methods so it\u0027s not really required","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        d \u003d {}"},{"line_number":47,"context_line":"        for method_name in map_dict:"},{"line_number":48,"context_line":"            iface \u003d map_dict[method_name]"},{"line_number":49,"context_line":"            if not driver_passthru:"},{"line_number":50,"context_line":"                driver_methods \u003d iface.vendor_routes"},{"line_number":51,"context_line":"            else:"},{"line_number":52,"context_line":"                driver_methods \u003d iface.driver_routes"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_729c65c1","line":49,"updated":"2014-11-04 17:58:59.000000000","message":"Similar to another nit left elsewhere: I don\u0027t see the need for negation here. It reads easier to me if we reverse the logic.","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        d \u003d {}"},{"line_number":47,"context_line":"        for method_name in map_dict:"},{"line_number":48,"context_line":"            iface \u003d map_dict[method_name]"},{"line_number":49,"context_line":"            if not driver_passthru:"},{"line_number":50,"context_line":"                driver_methods \u003d iface.vendor_routes"},{"line_number":51,"context_line":"            else:"},{"line_number":52,"context_line":"                driver_methods \u003d iface.driver_routes"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_7b9f2204","line":49,"in_reply_to":"7a8c0949_729c65c1","updated":"2014-11-10 10:18:45.000000000","message":"Done","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":3099,"name":"David Shrewsbury","email":"dshrewsb@redhat.com","username":"dshrews"},"change_message_id":"59e0f12a8f5d8c1ed18985d1fcdfb9e5107b849f","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                pass"},{"line_number":58,"context_line":"        return d"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _get_route(self, **kwargs):"},{"line_number":61,"context_line":"        method \u003d kwargs.get(\u0027method\u0027)"},{"line_number":62,"context_line":"        if not method:"},{"line_number":63,"context_line":"            raise exception.MissingParameterValue("}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_12ab21d7","line":60,"updated":"2014-11-04 17:58:59.000000000","message":"Docstring?","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                pass"},{"line_number":58,"context_line":"        return d"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _get_route(self, **kwargs):"},{"line_number":61,"context_line":"        method \u003d kwargs.get(\u0027method\u0027)"},{"line_number":62,"context_line":"        if not method:"},{"line_number":63,"context_line":"            raise exception.MissingParameterValue("}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_fb9232f5","line":60,"in_reply_to":"7a8c0949_12ab21d7","updated":"2014-11-10 10:18:45.000000000","message":"I will add a docstring, but these are private methods so it\u0027s not really required","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"}],"ironic/tests/drivers/test_base.py":[{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"0933403eb7bd929e0120ee500ac0425ac92143c1","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @driver_base.passthru(method\u003d\u0027normalexception\u0027)"},{"line_number":36,"context_line":"    def _normalexception(self):"},{"line_number":37,"context_line":"        raise Exception(\"Fake!\")"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def validate(self, task, **kwargs):"},{"line_number":40,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a8c0949_7ec5325a","line":37,"updated":"2014-10-31 16:25:28.000000000","message":"These 3 functions could be renamed to not include the leading \u0027_\u0027 and then they wouldn\u0027t need the method\u003d parameter for the decorator.","commit_id":"b6798cc44752f9e03393ecbfad626f79ff854c8a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"89f70128f943f78860694c19d80b44eac5567c4a","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @driver_base.passthru(method\u003d\u0027normalexception\u0027)"},{"line_number":36,"context_line":"    def _normalexception(self):"},{"line_number":37,"context_line":"        raise Exception(\"Fake!\")"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def validate(self, task, **kwargs):"},{"line_number":40,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a8c0949_a3da1e76","line":37,"in_reply_to":"7a8c0949_7ec5325a","updated":"2014-10-31 17:49:18.000000000","message":"Done","commit_id":"b6798cc44752f9e03393ecbfad626f79ff854c8a"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"0933403eb7bd929e0120ee500ac0425ac92143c1","unresolved":false,"context_lines":[{"line_number":45,"context_line":"            self._noexception()"},{"line_number":46,"context_line":"        elif method \u003d\u003d \"ironicexception\":"},{"line_number":47,"context_line":"            self._ironicexception()"},{"line_number":48,"context_line":"        elif method \u003d\u003d \"normalexception\":"},{"line_number":49,"context_line":"            self._normalexception()"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"7a8c0949_7e73724d","line":48,"updated":"2014-10-31 16:25:28.000000000","message":"This function could be removed now, so that FakeVendorInterface is up to date with the new passthru system, then the tests below can call straight to the functions themselves like self.assertRaises(exception.IronicException, self.fvi.noexception)","commit_id":"b6798cc44752f9e03393ecbfad626f79ff854c8a"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"89f70128f943f78860694c19d80b44eac5567c4a","unresolved":false,"context_lines":[{"line_number":45,"context_line":"            self._noexception()"},{"line_number":46,"context_line":"        elif method \u003d\u003d \"ironicexception\":"},{"line_number":47,"context_line":"            self._ironicexception()"},{"line_number":48,"context_line":"        elif method \u003d\u003d \"normalexception\":"},{"line_number":49,"context_line":"            self._normalexception()"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"7a8c0949_c3e72a3f","line":48,"in_reply_to":"7a8c0949_7e73724d","updated":"2014-10-31 17:49:18.000000000","message":"Done","commit_id":"b6798cc44752f9e03393ecbfad626f79ff854c8a"}],"ironic/tests/drivers/test_ipmitool.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bad2316363c7e3ea1e15e01acc37ed76c56f4c17","unresolved":false,"context_lines":[{"line_number":983,"context_line":"                                  self.node[\u0027uuid\u0027]) as task:"},{"line_number":984,"context_line":"            self.driver.vendor._bmc_reset(task)"},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"        mock_exec.assert_called_once_with(self.info, \u0027bmc reset warm\u0027)"},{"line_number":987,"context_line":""},{"line_number":988,"context_line":"    @mock.patch.object(ipmi, \u0027_exec_ipmitool\u0027, autospec\u003dTrue)"},{"line_number":989,"context_line":"    def test__bmc_reset_cold(self, mock_exec):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_a94e436d","line":986,"updated":"2014-10-22 20:48:18.000000000","message":"If you look at this test, and change it, well, add this line just before #984\n    kwargs \u003d {\u0027warm\u0027: False}\nAnd change #984 to be\n    self.driver.vendor._bmc_reset(task, kwargs)\n\nYou\u0027ll see that this passes. Although _exec_ipmitool should be called with \u0027bmc reset cold\u0027, not \u0027warm\u0027 :-(","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"cf961d3be4db740cef40d4d80170b68e9f6982fd","unresolved":false,"context_lines":[{"line_number":983,"context_line":"                                  self.node[\u0027uuid\u0027]) as task:"},{"line_number":984,"context_line":"            self.driver.vendor._bmc_reset(task)"},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"        mock_exec.assert_called_once_with(self.info, \u0027bmc reset warm\u0027)"},{"line_number":987,"context_line":""},{"line_number":988,"context_line":"    @mock.patch.object(ipmi, \u0027_exec_ipmitool\u0027, autospec\u003dTrue)"},{"line_number":989,"context_line":"    def test__bmc_reset_cold(self, mock_exec):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_dc016c06","line":986,"in_reply_to":"9aa7fdbe_85b4f635","updated":"2014-10-23 15:34:32.000000000","message":"Ouch. Yup, you\u0027re right. Sorry about that!","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"df53f279cc7c6b6132b00218a609c6a058e490d1","unresolved":false,"context_lines":[{"line_number":983,"context_line":"                                  self.node[\u0027uuid\u0027]) as task:"},{"line_number":984,"context_line":"            self.driver.vendor._bmc_reset(task)"},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"        mock_exec.assert_called_once_with(self.info, \u0027bmc reset warm\u0027)"},{"line_number":987,"context_line":""},{"line_number":988,"context_line":"    @mock.patch.object(ipmi, \u0027_exec_ipmitool\u0027, autospec\u003dTrue)"},{"line_number":989,"context_line":"    def test__bmc_reset_cold(self, mock_exec):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9aa7fdbe_85b4f635","line":986,"in_reply_to":"9aa7fdbe_a94e436d","updated":"2014-10-23 09:47:27.000000000","message":"it\u0027s becase you haven\u0027t expanded the kwargs argument, when you call it like:\n\n self.driver.vendor._bmc_reset(task, kwargs)\n\nThe warm parameter will receive the dictonary, e.g warm\u003d{\u0027warm\u0027: False}, and it will pass the conditional \"if warm\"\n\nYou have to expand the argument when calling the function, e.g:\n\n self.driver.vendor._bmc_reset(task, **kwargs)\n\nand then the test fails","commit_id":"77dfa7c3b161c6709f26675b999fcea8672fe844"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1076,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1077,"context_line":"            kwargs \u003d {\u0027raw_bytes\u0027: \u00270x00 0x01\u0027}"},{"line_number":1078,"context_line":"            self.driver.vendor.send_raw(task, **kwargs)"},{"line_number":1079,"context_line":"            raw_bytes_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_vendor_passthru_validate__bmc_reset_good(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_bfaa55d2","line":1078,"updated":"2014-10-30 13:28:32.000000000","message":"self.driver.vendor.send_raw(task, raw_bytes\u003d\u00270x00 0x01\u0027)","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1076,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1077,"context_line":"            kwargs \u003d {\u0027raw_bytes\u0027: \u00270x00 0x01\u0027}"},{"line_number":1078,"context_line":"            self.driver.vendor.send_raw(task, **kwargs)"},{"line_number":1079,"context_line":"            raw_bytes_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_vendor_passthru_validate__bmc_reset_good(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_309cd269","line":1078,"in_reply_to":"7a8c0949_bfaa55d2","updated":"2014-10-30 15:00:29.000000000","message":"Done","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":1100,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1101,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1102,"context_line":"            kwargs \u003d {\u0027warm\u0027: True}"},{"line_number":1103,"context_line":"            self.driver.vendor.bmc_reset(task, **kwargs)"},{"line_number":1104,"context_line":"            bmc_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1105,"context_line":""},{"line_number":1106,"context_line":"    @mock.patch.object(ipmi.VendorPassthru, \u0027bmc_reset\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_ffabfdd3","line":1103,"updated":"2014-10-30 13:28:32.000000000","message":"ditto","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":1100,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1101,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1102,"context_line":"            kwargs \u003d {\u0027warm\u0027: True}"},{"line_number":1103,"context_line":"            self.driver.vendor.bmc_reset(task, **kwargs)"},{"line_number":1104,"context_line":"            bmc_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1105,"context_line":""},{"line_number":1106,"context_line":"    @mock.patch.object(ipmi.VendorPassthru, \u0027bmc_reset\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_f0916a53","line":1103,"in_reply_to":"7a8c0949_ffabfdd3","updated":"2014-10-30 15:00:29.000000000","message":"Done","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b3fe600af5c703affc672c010435599614e6e799","unresolved":false,"context_lines":[{"line_number":1108,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1109,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1110,"context_line":"            kwargs \u003d {\u0027warm\u0027: False}"},{"line_number":1111,"context_line":"            self.driver.vendor.bmc_reset(task, **kwargs)"},{"line_number":1112,"context_line":"            bmc_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1113,"context_line":""},{"line_number":1114,"context_line":"    def test_vendor_passthru_vendor_routes(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_1fb9a92e","line":1111,"updated":"2014-10-30 13:28:32.000000000","message":"ditto","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"0338ccca7a51854c95092bed6703e9c21b715be5","unresolved":false,"context_lines":[{"line_number":1108,"context_line":"        with task_manager.acquire(self.context, self.node[\u0027uuid\u0027],"},{"line_number":1109,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":1110,"context_line":"            kwargs \u003d {\u0027warm\u0027: False}"},{"line_number":1111,"context_line":"            self.driver.vendor.bmc_reset(task, **kwargs)"},{"line_number":1112,"context_line":"            bmc_mock.assert_called_once_with(task, **kwargs)"},{"line_number":1113,"context_line":""},{"line_number":1114,"context_line":"    def test_vendor_passthru_vendor_routes(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8c0949_109fd660","line":1111,"in_reply_to":"7a8c0949_1fb9a92e","updated":"2014-10-30 15:00:29.000000000","message":"Done","commit_id":"66a690a172560c507af0c535fae9f54fdebec038"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b24f8a0d705f1b174b2a870f4b3c426458113038","unresolved":false,"context_lines":[{"line_number":1114,"context_line":"                                  shared\u003dTrue) as task:"},{"line_number":1115,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":1116,"context_line":"            self.assertIsInstance(vendor_routes, dict)"},{"line_number":1117,"context_line":"            self.assertEqual(sorted(expected), sorted(list(vendor_routes)))"},{"line_number":1118,"context_line":""},{"line_number":1119,"context_line":"    def test_vendor_passthru_driver_routes(self):"},{"line_number":1120,"context_line":"        with task_manager.acquire(self.context, self.node.uuid,"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_566e5d30","line":1117,"updated":"2014-11-06 15:36:18.000000000","message":"list() call is redundant","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":1114,"context_line":"                                  shared\u003dTrue) as task:"},{"line_number":1115,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":1116,"context_line":"            self.assertIsInstance(vendor_routes, dict)"},{"line_number":1117,"context_line":"            self.assertEqual(sorted(expected), sorted(list(vendor_routes)))"},{"line_number":1118,"context_line":""},{"line_number":1119,"context_line":"    def test_vendor_passthru_driver_routes(self):"},{"line_number":1120,"context_line":"        with task_manager.acquire(self.context, self.node.uuid,"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_1b90deeb","line":1117,"in_reply_to":"7a8c0949_566e5d30","updated":"2014-11-10 10:18:45.000000000","message":"Done","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"}],"ironic/tests/drivers/test_seamicro.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"b24f8a0d705f1b174b2a870f4b3c426458113038","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                                  shared\u003dTrue) as task:"},{"line_number":300,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":301,"context_line":"            self.assertIsInstance(vendor_routes, dict)"},{"line_number":302,"context_line":"            self.assertEqual(sorted(expected), sorted(list(vendor_routes)))"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    def test_driver_routes(self):"},{"line_number":305,"context_line":"        with task_manager.acquire(self.context, self.node.uuid,"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a8c0949_b64a21aa","line":302,"updated":"2014-11-06 15:36:18.000000000","message":"list() call is redundant","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c5f1da972707c4bd38d29792f222a2b9036a0a8","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                                  shared\u003dTrue) as task:"},{"line_number":300,"context_line":"            vendor_routes \u003d task.driver.vendor.vendor_routes"},{"line_number":301,"context_line":"            self.assertIsInstance(vendor_routes, dict)"},{"line_number":302,"context_line":"            self.assertEqual(sorted(expected), sorted(list(vendor_routes)))"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    def test_driver_routes(self):"},{"line_number":305,"context_line":"        with task_manager.acquire(self.context, self.node.uuid,"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a890539_5bc186e3","line":302,"in_reply_to":"7a8c0949_b64a21aa","updated":"2014-11-10 10:18:45.000000000","message":"Done","commit_id":"92983a4436e25b6a8f8dd4fbefa56ce6cae59006"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"4d99f66d9aac05bb532b94bb67844dce0ff65ada","unresolved":false,"context_lines":[{"line_number":438,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":439,"context_line":"            self.assertRaises(exception.InvalidParameterValue,"},{"line_number":440,"context_line":"                              task.driver.vendor.set_node_vlan_id,"},{"line_number":441,"context_line":"                              task, **{})"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"    @mock.patch.object(seamicro, \u0027_get_server\u0027)"},{"line_number":444,"context_line":"    def test_set_node_vlan_id_fail(self, mock_get_server):"}],"source_content_type":"text/x-python","patch_set":19,"id":"5a890539_09edd8c3","line":441,"updated":"2014-11-11 12:48:50.000000000","message":"**{} is redundant","commit_id":"b5a531aa4d1e8c5e0056d7aeceda467423009e55"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"4d99f66d9aac05bb532b94bb67844dce0ff65ada","unresolved":false,"context_lines":[{"line_number":536,"context_line":"                                  shared\u003dFalse) as task:"},{"line_number":537,"context_line":"            self.assertRaises(exception.InvalidParameterValue,"},{"line_number":538,"context_line":"                              task.driver.vendor.attach_volume, task,"},{"line_number":539,"context_line":"                              **{})"},{"line_number":540,"context_line":""},{"line_number":541,"context_line":"    @mock.patch.object(seamicro, \u0027_get_server\u0027)"},{"line_number":542,"context_line":"    def test_set_boot_device_good(self, mock_get_server):"}],"source_content_type":"text/x-python","patch_set":19,"id":"5a890539_69dbbc1b","line":539,"updated":"2014-11-11 12:48:50.000000000","message":"ditto","commit_id":"b5a531aa4d1e8c5e0056d7aeceda467423009e55"}]}
