)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0663fc03c76c5184c07903c447c2a3abeeeab580","unresolved":false,"context_lines":[{"line_number":3,"context_line":"AuthorDate: 2015-02-27 18:00:20 +0800"},{"line_number":4,"context_line":"Commit:     gong yong sheng \u003cgong.yongsheng@99cloud.net\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-03-05 21:22:11 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add extra subnet route to ha router"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add scope in HA virtual route mode to"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"9a80dd14_bb914d9c","line":6,"updated":"2015-03-05 15:58:34.000000000","message":"This patch should be rebased on https://review.openstack.org/#/c/160430/, I\u0027m assuming you rebased on master by mistake.","commit_id":"ab58ce02c76f379eb612f73b3cb1ae64710cb023"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"3b3a017d7c8620591faaaf70387d8f1fe739d517","unresolved":false,"context_lines":[{"line_number":3,"context_line":"AuthorDate: 2015-02-27 18:00:20 +0800"},{"line_number":4,"context_line":"Commit:     gong yong sheng \u003cgong.yongsheng@99cloud.net\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-03-05 21:22:11 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add extra subnet route to ha router"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add scope in HA virtual route mode to"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"9a80dd14_2c27c913","line":6,"in_reply_to":"9a80dd14_bb914d9c","updated":"2015-03-09 10:17:39.000000000","message":"Done","commit_id":"ab58ce02c76f379eb612f73b3cb1ae64710cb023"}],"neutron/agent/l3/ha_router.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"64e0b57174d063e256ae5aa80bb4789f969ae272","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        # Filter out all of the old routes while keeping only the default route"},{"line_number":180,"context_line":"        default_gw \u003d (\u0027::/0\u0027, \u00270.0.0.0/0\u0027)"},{"line_number":181,"context_line":"        instance.virtual_routes \u003d [route for route in instance.virtual_routes"},{"line_number":182,"context_line":"                                   if route.destination in default_gw or"},{"line_number":183,"context_line":"                                   not route.nexthop]"},{"line_number":184,"context_line":"        for route in new_routes:"},{"line_number":185,"context_line":"            instance.virtual_routes.append(keepalived.KeepalivedVirtualRoute("}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_8bfe2a04","line":182,"updated":"2015-02-27 14:02:38.000000000","message":"This would turn into:\n\nor route.scope \u003d\u003d \u0027link\u0027","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c7c5b19b78d7a33a40b4cd6592fd2c4944f48019","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        # Filter out all of the old routes while keeping only the default route"},{"line_number":180,"context_line":"        default_gw \u003d (\u0027::/0\u0027, \u00270.0.0.0/0\u0027)"},{"line_number":181,"context_line":"        instance.virtual_routes \u003d [route for route in instance.virtual_routes"},{"line_number":182,"context_line":"                                   if route.destination in default_gw or"},{"line_number":183,"context_line":"                                   not route.nexthop]"},{"line_number":184,"context_line":"        for route in new_routes:"},{"line_number":185,"context_line":"            instance.virtual_routes.append(keepalived.KeepalivedVirtualRoute("}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_2e92ac9f","line":182,"in_reply_to":"ba7be1f8_8bfe2a04","updated":"2015-02-27 14:47:49.000000000","message":"Done","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"64e0b57174d063e256ae5aa80bb4789f969ae272","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        self._add_vip(ex_gw_port[\u0027ip_cidr\u0027], interface_name)"},{"line_number":243,"context_line":"        self._add_default_gw_virtual_route(ex_gw_port, interface_name)"},{"line_number":244,"context_line":"        self._add_extra_subnet_onlink_routes(ex_gw_port, interface_name)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def _add_extra_subnet_onlink_routes(self, ex_gw_port, interface_name):"},{"line_number":247,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":248,"context_line":"        instance \u003d self._get_keepalived_instance()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_0b395ad8","line":245,"updated":"2015-02-27 14:02:38.000000000","message":"Please modify the L3 agent router lifecycle functional test to assert extra_subnets.","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c7c5b19b78d7a33a40b4cd6592fd2c4944f48019","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        self._add_vip(ex_gw_port[\u0027ip_cidr\u0027], interface_name)"},{"line_number":243,"context_line":"        self._add_default_gw_virtual_route(ex_gw_port, interface_name)"},{"line_number":244,"context_line":"        self._add_extra_subnet_onlink_routes(ex_gw_port, interface_name)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def _add_extra_subnet_onlink_routes(self, ex_gw_port, interface_name):"},{"line_number":247,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":248,"context_line":"        instance \u003d self._get_keepalived_instance()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_8ecf18b3","line":245,"in_reply_to":"ba7be1f8_0b395ad8","updated":"2015-02-27 14:47:49.000000000","message":"can u point me where is the function tests? thanks","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"ac2a4ce948b578002612f91b821a58ae124d1393","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        self._add_vip(ex_gw_port[\u0027ip_cidr\u0027], interface_name)"},{"line_number":243,"context_line":"        self._add_default_gw_virtual_route(ex_gw_port, interface_name)"},{"line_number":244,"context_line":"        self._add_extra_subnet_onlink_routes(ex_gw_port, interface_name)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def _add_extra_subnet_onlink_routes(self, ex_gw_port, interface_name):"},{"line_number":247,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":248,"context_line":"        instance \u003d self._get_keepalived_instance()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_6173d515","line":245,"in_reply_to":"ba7be1f8_8ecf18b3","updated":"2015-02-27 14:50:13.000000000","message":"neutron/tests/functional/agent/test_l3_agent\n\nfunction _router_lifecycle.","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"639b5a42296698d0cf58f5eb92240e47a028a2e6","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":249,"context_line":"        instance \u003d self._get_keepalived_instance()"},{"line_number":250,"context_line":"        instance.virtual_routes \u003d ("},{"line_number":251,"context_line":"            [route for route in instance.virtual_routes if route.nexthop])"},{"line_number":252,"context_line":"        onlink_route_cidrs \u003d set(s[\u0027cidr\u0027] for s in extra_subnets)"},{"line_number":253,"context_line":"        for onlink_route_cidr in onlink_route_cidrs:"},{"line_number":254,"context_line":"            instance.virtual_routes.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_d01fe559","line":251,"updated":"2015-02-27 16:11:44.000000000","message":"if route.scope !\u003d \u0027link\u0027\n\n?\n\nMaybe it\u0027s time to start splitting up instance.virtual_routes to separate lists then writing all of them at the end so we can stop this filtering all of the time. For example:\n\n    default_gateway\n    extra_routes\n    extra_subnets\n\nThen we write all 3 lists to the virtual_routes section. You definitely don\u0027t have to do that in this patch though, way out of scope... Just something I had in mind for a while.","commit_id":"f5f134e3df15449058e80e6a673975dec0b1a1ee"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"3045bdff1784d0f00cfc5b1739ffdff215b524cb","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":249,"context_line":"        instance \u003d self._get_keepalived_instance()"},{"line_number":250,"context_line":"        instance.virtual_routes \u003d ("},{"line_number":251,"context_line":"            [route for route in instance.virtual_routes if route.nexthop])"},{"line_number":252,"context_line":"        onlink_route_cidrs \u003d set(s[\u0027cidr\u0027] for s in extra_subnets)"},{"line_number":253,"context_line":"        for onlink_route_cidr in onlink_route_cidrs:"},{"line_number":254,"context_line":"            instance.virtual_routes.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_d9761fd8","line":251,"in_reply_to":"ba7be1f8_40495d8a","updated":"2015-02-28 01:32:06.000000000","message":"can we do this split in a new patch?","commit_id":"f5f134e3df15449058e80e6a673975dec0b1a1ee"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"7311d052c93148d96b1b28be321eb7849d258f83","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":249,"context_line":"        instance \u003d self._get_keepalived_instance()"},{"line_number":250,"context_line":"        instance.virtual_routes \u003d ("},{"line_number":251,"context_line":"            [route for route in instance.virtual_routes if route.nexthop])"},{"line_number":252,"context_line":"        onlink_route_cidrs \u003d set(s[\u0027cidr\u0027] for s in extra_subnets)"},{"line_number":253,"context_line":"        for onlink_route_cidr in onlink_route_cidrs:"},{"line_number":254,"context_line":"            instance.virtual_routes.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_40495d8a","line":251,"in_reply_to":"ba7be1f8_d01fe559","updated":"2015-02-27 19:51:47.000000000","message":"I\u0027ve been thinking about this some more and I think that the current situation is just too fragile and complicated, and this patch only makes it worse... Let\u0027s split up virtual_routes into 3 lists so that they\u0027re decoupled and add_gw, routes_updated and onlink_routes don\u0027t have to care about each other. If you don\u0027t have the time to do that in this patch let me know and I\u0027ll take it over.","commit_id":"f5f134e3df15449058e80e6a673975dec0b1a1ee"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"8b8b713df9bcec14ec18316ffe536c9f9d987bb3","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        extra_subnets \u003d ex_gw_port.get(\u0027extra_subnets\u0027, [])"},{"line_number":249,"context_line":"        instance \u003d self._get_keepalived_instance()"},{"line_number":250,"context_line":"        instance.virtual_routes \u003d ("},{"line_number":251,"context_line":"            [route for route in instance.virtual_routes if route.nexthop])"},{"line_number":252,"context_line":"        onlink_route_cidrs \u003d set(s[\u0027cidr\u0027] for s in extra_subnets)"},{"line_number":253,"context_line":"        for onlink_route_cidr in onlink_route_cidrs:"},{"line_number":254,"context_line":"            instance.virtual_routes.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_41db0d1b","line":251,"in_reply_to":"ba7be1f8_d9761fd8","updated":"2015-02-28 18:38:37.000000000","message":"I think what would make sense is that I push a patch that splits virtual_routes into two lists, then you rebase this patch on it and simply add a third list. I\u0027ll try to get a patch up for review Monday.","commit_id":"f5f134e3df15449058e80e6a673975dec0b1a1ee"}],"neutron/agent/linux/ip_lib.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0ca72bba0848b857d80a32f320e80735b654411a","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(namespace\u003dNone, ipv6\u003dFalse):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    The dictionary format is: {\u0027destination\u0027: cidr,"}],"source_content_type":"text/x-python","patch_set":20,"id":"ba3cc151_25fa2d76","line":706,"updated":"2015-07-01 02:13:10.000000000","message":"In order to be consistent with the other ip_lib functions we should use \u0027ip_version\u0027 here and not a bool.","commit_id":"5730f446aea279bc351ebad51ebc8f9c928d1d66"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"78da532e625037b29b18ba272332532ebcdd62a5","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(namespace\u003dNone, ipv6\u003dFalse):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    The dictionary format is: {\u0027destination\u0027: cidr,"}],"source_content_type":"text/x-python","patch_set":20,"id":"ba3cc151_e0dc3314","line":706,"in_reply_to":"ba3cc151_25fa2d76","updated":"2015-07-01 02:56:39.000000000","message":"Done","commit_id":"5730f446aea279bc351ebad51ebc8f9c928d1d66"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0ca72bba0848b857d80a32f320e80735b654411a","unresolved":false,"context_lines":[{"line_number":714,"context_line":""},{"line_number":715,"context_line":"    routes \u003d []"},{"line_number":716,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":717,"context_line":"    ipversions \u003d [\u0027\u0027]"},{"line_number":718,"context_line":"    if ipv6:"},{"line_number":719,"context_line":"        ipversions.append(\u0027-6\u0027)"},{"line_number":720,"context_line":"    for ipversion in ipversions:"}],"source_content_type":"text/x-python","patch_set":20,"id":"ba3cc151_051da9bc","line":717,"updated":"2015-07-01 02:13:10.000000000","message":"You can simplify this to:\n\n  table \u003d ip_wrapper.netns.execute([\u0027ip\u0027, \u0027route\u0027], check_exit_code\u003dTrue)\n  if ip_version \u003d\u003d 6:\n      table +\u003d ip_wrapper.netns.execute([\u0027ip\u0027, ip_version, \u0027route\u0027], check_exit_code\u003dTrue)\n\nThen lines 731+\n\nThis way you eliminate the loop. Seems simpler to me although it\u0027s not a big difference.","commit_id":"5730f446aea279bc351ebad51ebc8f9c928d1d66"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"fbfdebbf5d5111fd34a020b9a4fff1d58d7ab4eb","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(namespace\u003dNone, ip_versions\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param namespace"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_1fb5ca2f","line":706,"updated":"2015-07-01 18:16:59.000000000","message":"We could also not put a default here, and force callers to specify it.","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"acd66fb44d3fd0618b5668dc14d33fd0c99604ea","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(namespace\u003dNone, ip_versions\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param namespace"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_f0ea53da","line":706,"in_reply_to":"ba3cc151_1fb5ca2f","updated":"2015-07-02 22:29:00.000000000","message":"Done","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"fbfdebbf5d5111fd34a020b9a4fff1d58d7ab4eb","unresolved":false,"context_lines":[{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param namespace"},{"line_number":710,"context_line":"    @param ip_versions: the routes of versions to return, None or empty means"},{"line_number":711,"context_line":"    4."},{"line_number":712,"context_line":"    @return: a list of dictionaries, each representing a route."},{"line_number":713,"context_line":"    The dictionary format is: {\u0027destination\u0027: cidr,"},{"line_number":714,"context_line":"                               \u0027nexthop\u0027: ip,"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_8c33fa61","line":711,"updated":"2015-07-01 18:16:59.000000000","message":"Changing this slightly will let it fit on a single line:\n\n\u0027route table versions to return, None or empty means 4\u0027","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"acd66fb44d3fd0618b5668dc14d33fd0c99604ea","unresolved":false,"context_lines":[{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param namespace"},{"line_number":710,"context_line":"    @param ip_versions: the routes of versions to return, None or empty means"},{"line_number":711,"context_line":"    4."},{"line_number":712,"context_line":"    @return: a list of dictionaries, each representing a route."},{"line_number":713,"context_line":"    The dictionary format is: {\u0027destination\u0027: cidr,"},{"line_number":714,"context_line":"                               \u0027nexthop\u0027: ip,"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_d0eb8fda","line":711,"in_reply_to":"ba3cc151_8c33fa61","updated":"2015-07-02 22:29:00.000000000","message":"Done","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"fbfdebbf5d5111fd34a020b9a4fff1d58d7ab4eb","unresolved":false,"context_lines":[{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    routes \u003d []"},{"line_number":720,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":721,"context_line":"    _ipversions \u003d [4] if not ip_versions else ip_versions"},{"line_number":722,"context_line":""},{"line_number":723,"context_line":"    for _ipversion in _ipversions:"},{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_cc3902a6","line":721,"updated":"2015-07-01 18:16:59.000000000","message":"Why use this _variable ?\n\nif not ip_versions:\n    ip_versions \u003d [4]","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"acd66fb44d3fd0618b5668dc14d33fd0c99604ea","unresolved":false,"context_lines":[{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    routes \u003d []"},{"line_number":720,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":721,"context_line":"    _ipversions \u003d [4] if not ip_versions else ip_versions"},{"line_number":722,"context_line":""},{"line_number":723,"context_line":"    for _ipversion in _ipversions:"},{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_90c0a751","line":721,"in_reply_to":"ba3cc151_cc3902a6","updated":"2015-07-02 22:29:00.000000000","message":"Done","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"fbfdebbf5d5111fd34a020b9a4fff1d58d7ab4eb","unresolved":false,"context_lines":[{"line_number":720,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":721,"context_line":"    _ipversions \u003d [4] if not ip_versions else ip_versions"},{"line_number":722,"context_line":""},{"line_number":723,"context_line":"    for _ipversion in _ipversions:"},{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"},{"line_number":725,"context_line":"        # in ip command for ipv4"},{"line_number":726,"context_line":"        cmds \u003d ([\u0027ip\u0027, \u0027-\u0027 + str(_ipversion), \u0027route\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_ac44be1a","line":723,"updated":"2015-07-01 18:16:59.000000000","message":"Here too, \u0027for version in ip_versions:\u0027","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"acd66fb44d3fd0618b5668dc14d33fd0c99604ea","unresolved":false,"context_lines":[{"line_number":720,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":721,"context_line":"    _ipversions \u003d [4] if not ip_versions else ip_versions"},{"line_number":722,"context_line":""},{"line_number":723,"context_line":"    for _ipversion in _ipversions:"},{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"},{"line_number":725,"context_line":"        # in ip command for ipv4"},{"line_number":726,"context_line":"        cmds \u003d ([\u0027ip\u0027, \u0027-\u0027 + str(_ipversion), \u0027route\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_50b69ff9","line":723,"in_reply_to":"ba3cc151_ac44be1a","updated":"2015-07-02 22:29:00.000000000","message":"Done","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"fbfdebbf5d5111fd34a020b9a4fff1d58d7ab4eb","unresolved":false,"context_lines":[{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"},{"line_number":725,"context_line":"        # in ip command for ipv4"},{"line_number":726,"context_line":"        cmds \u003d ([\u0027ip\u0027, \u0027-\u0027 + str(_ipversion), \u0027route\u0027]"},{"line_number":727,"context_line":"                if _ipversion and _ipversion !\u003d 4 else [\u0027ip\u0027, \u0027route\u0027])"},{"line_number":728,"context_line":"        table \u003d ip_wrapper.netns.execute(cmds,"},{"line_number":729,"context_line":"                                         check_exit_code\u003dTrue)"},{"line_number":730,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_8cdbfa4e","line":727,"updated":"2015-07-01 18:16:59.000000000","message":"I removed this and did not see any unit test failures, so it seems unnecessary, which then makes creating cmds unnecessary here.","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"acd66fb44d3fd0618b5668dc14d33fd0c99604ea","unresolved":false,"context_lines":[{"line_number":724,"context_line":"        # To comply with previous calls (from test cases) without version"},{"line_number":725,"context_line":"        # in ip command for ipv4"},{"line_number":726,"context_line":"        cmds \u003d ([\u0027ip\u0027, \u0027-\u0027 + str(_ipversion), \u0027route\u0027]"},{"line_number":727,"context_line":"                if _ipversion and _ipversion !\u003d 4 else [\u0027ip\u0027, \u0027route\u0027])"},{"line_number":728,"context_line":"        table \u003d ip_wrapper.netns.execute(cmds,"},{"line_number":729,"context_line":"                                         check_exit_code\u003dTrue)"},{"line_number":730,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba3cc151_f0d1f323","line":727,"in_reply_to":"ba3cc151_8cdbfa4e","updated":"2015-07-02 22:29:00.000000000","message":"Done","commit_id":"cadc8d6e65f650111f2a5436d871456286a58ac5"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"13eb3ae19132407e8eff99c5d5cb8adc4938674e","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(ip_versions, namespace\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param ip_versions: the routes of versions to return, for example"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba3cc151_b0a92b26","line":706,"updated":"2015-07-02 22:53:01.000000000","message":"Essentially this method just calls itself twice, once for each ip_version passed to it (Assuming the caller passed [4, 6]). Brian, should we change the API instead to accept a singular ip_version like the rest of the commands, and have the callers call it twice? Seems like a more consistent API and there are no performance drawbacks (I checked, I do not see a way for \u0027ip\u0027 to output both the ipv4 and ipv6 routing table in a single call).","commit_id":"8f1507d43c34cf3ec2583f959eb1f489a4edb98c"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"9dbd7aa7bcf71a3da94722df6f8acd76b6e44a46","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(ip_versions, namespace\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param ip_versions: the routes of versions to return, for example"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba3cc151_055e5445","line":706,"in_reply_to":"ba3cc151_2a07e782","updated":"2015-07-06 11:27:26.000000000","message":"sure","commit_id":"8f1507d43c34cf3ec2583f959eb1f489a4edb98c"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"7766139713717700d7b8b32f6c7a3ad9d14944b1","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(ip_versions, namespace\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param ip_versions: the routes of versions to return, for example"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba3cc151_2a07e782","line":706,"in_reply_to":"ba3cc151_a4a6ceab","updated":"2015-07-03 02:11:15.000000000","message":"Gongysh what do you think? Looks like Brian and I are on the same page here.","commit_id":"8f1507d43c34cf3ec2583f959eb1f489a4edb98c"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"4e14badac4619499fc6f17b1871655f1a90dc56c","unresolved":false,"context_lines":[{"line_number":703,"context_line":"        return True"},{"line_number":704,"context_line":""},{"line_number":705,"context_line":""},{"line_number":706,"context_line":"def get_routing_table(ip_versions, namespace\u003dNone):"},{"line_number":707,"context_line":"    \"\"\"Return a list of dictionaries, each representing a route."},{"line_number":708,"context_line":""},{"line_number":709,"context_line":"    @param ip_versions: the routes of versions to return, for example"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba3cc151_a4a6ceab","line":706,"in_reply_to":"ba3cc151_b0a92b26","updated":"2015-07-03 00:36:37.000000000","message":"Sure, if we enforce ip_version must be passed that works for me.","commit_id":"8f1507d43c34cf3ec2583f959eb1f489a4edb98c"}],"neutron/agent/linux/keepalived.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"64e0b57174d063e256ae5aa80bb4789f969ae272","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class KeepalivedVirtualRoute(object):"},{"line_number":96,"context_line":"    \"\"\"A virtual route entry of a keepalived configuration.\"\"\""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def __init__(self, destination, nexthop, interface_name\u003dNone):"},{"line_number":99,"context_line":"        \"\"\""},{"line_number":100,"context_line":"        @param nexthop: route is on link route if it is empty"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_59088b2d","line":97,"updated":"2015-02-27 14:02:38.000000000","message":"Missing unit tests additions for the new functionality.","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c7c5b19b78d7a33a40b4cd6592fd2c4944f48019","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class KeepalivedVirtualRoute(object):"},{"line_number":96,"context_line":"    \"\"\"A virtual route entry of a keepalived configuration.\"\"\""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def __init__(self, destination, nexthop, interface_name\u003dNone):"},{"line_number":99,"context_line":"        \"\"\""},{"line_number":100,"context_line":"        @param nexthop: route is on link route if it is empty"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_6e190479","line":97,"in_reply_to":"ba7be1f8_59088b2d","updated":"2015-02-27 14:47:49.000000000","message":"add unit tests after the implements are agreed. thanks","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"64e0b57174d063e256ae5aa80bb4789f969ae272","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        if self.nexthop:"},{"line_number":109,"context_line":"            output +\u003d \u0027 via %s\u0027 % self.nexthop"},{"line_number":110,"context_line":"        if self.interface_name:"},{"line_number":111,"context_line":"            output +\u003d \u0027 dev %s\u0027 % self.interface_name"},{"line_number":112,"context_line":"        if not self.nexthop:"},{"line_number":113,"context_line":"            output +\u003d \u0027 scope link\u0027"},{"line_number":114,"context_line":"        return output"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_992be393","line":111,"updated":"2015-02-27 14:02:38.000000000","message":"I\u0027d rather this class not have this kind of logic and leave that up to the caller. Please add scope as an optional parameter.","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"c7c5b19b78d7a33a40b4cd6592fd2c4944f48019","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        if self.nexthop:"},{"line_number":109,"context_line":"            output +\u003d \u0027 via %s\u0027 % self.nexthop"},{"line_number":110,"context_line":"        if self.interface_name:"},{"line_number":111,"context_line":"            output +\u003d \u0027 dev %s\u0027 % self.interface_name"},{"line_number":112,"context_line":"        if not self.nexthop:"},{"line_number":113,"context_line":"            output +\u003d \u0027 scope link\u0027"},{"line_number":114,"context_line":"        return output"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba7be1f8_6b2bb694","line":111,"in_reply_to":"ba7be1f8_992be393","updated":"2015-02-27 14:47:49.000000000","message":"Done","commit_id":"631da49a33fd40ba50879b95cd715d60f554e922"}],"neutron/tests/functional/agent/test_l3_agent.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"837adfc59252d5840e9f04eec9a4d0b5cdc8ba30","unresolved":false,"context_lines":[{"line_number":253,"context_line":"        self.assertTrue(len(internal_devices))"},{"line_number":254,"context_line":"        for device in internal_devices:"},{"line_number":255,"context_line":"            self.assertTrue(self.device_exists_with_ip_mac("},{"line_number":256,"context_line":"                device, self.agent.get_internal_device_name, router.ns_name))"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    def _assert_extra_routes(self, router):"},{"line_number":259,"context_line":"        routes \u003d ip_lib.get_routing_table(namespace\u003drouter.ns_name)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba7be1f8_3b77fa3c","line":256,"updated":"2015-03-02 17:38:50.000000000","message":"You should add a similar method to online routes.","commit_id":"6df9c381043f8a1f0e98ead9b1ef05107307d7e2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0ad5fbc4cb189e7371b82db4d4aa86b0e9294376","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        self.assertTrue(len(internal_devices))"},{"line_number":253,"context_line":"        for device in internal_devices:"},{"line_number":254,"context_line":"            self.assertTrue(self.device_exists_with_ip_mac("},{"line_number":255,"context_line":"                device, self.agent.get_internal_device_name, router.ns_name))"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    def _assert_extra_routes(self, router):"},{"line_number":258,"context_line":"        routes \u003d ip_lib.get_routing_table(namespace\u003drouter.ns_name)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba7be1f8_fbeba275","line":255,"updated":"2015-03-02 17:42:46.000000000","message":"Reposting my comment from PS4 so it\u0027s not lost:\n\nOnlink routes should be asserted here as well.","commit_id":"71eb08fbaab825c050a2a394942b824e5b27ce4b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"b60b27c684c4387872df305253aa5158431b8c6b","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        self.assertTrue(len(internal_devices))"},{"line_number":253,"context_line":"        for device in internal_devices:"},{"line_number":254,"context_line":"            self.assertTrue(self.device_exists_with_ip_mac("},{"line_number":255,"context_line":"                device, self.agent.get_internal_device_name, router.ns_name))"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    def _assert_extra_routes(self, router):"},{"line_number":258,"context_line":"        routes \u003d ip_lib.get_routing_table(namespace\u003drouter.ns_name)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba7be1f8_dea5ec04","line":255,"updated":"2015-03-02 17:48:35.000000000","message":"Here you need to get the onlink routes and assert that they\u0027re in the routing table as well. This will require a slight modification to ip_lib.get_routing_table (So that it populates the scope as well, if it exists), and its functional test (So that it asserts the new scope attribute).","commit_id":"f839bc0a8ea76d326d11b1b34b18e3b52257d71e"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"cdb9e7876e68ac92ec160048894d79ecd28940b1","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        self.assertTrue(len(internal_devices))"},{"line_number":253,"context_line":"        for device in internal_devices:"},{"line_number":254,"context_line":"            self.assertTrue(self.device_exists_with_ip_mac("},{"line_number":255,"context_line":"                device, self.agent.get_internal_device_name, router.ns_name))"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    def _assert_extra_routes(self, router):"},{"line_number":258,"context_line":"        routes \u003d ip_lib.get_routing_table(namespace\u003drouter.ns_name)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a80dd14_dc40ff37","line":255,"in_reply_to":"9a80dd14_87dc8676","updated":"2015-03-04 13:55:14.000000000","message":"Why would a test be in another patch?","commit_id":"f839bc0a8ea76d326d11b1b34b18e3b52257d71e"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"b95efc6a784e50d6bee38ae12fc4d47ca5564d6a","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        self.assertTrue(len(internal_devices))"},{"line_number":253,"context_line":"        for device in internal_devices:"},{"line_number":254,"context_line":"            self.assertTrue(self.device_exists_with_ip_mac("},{"line_number":255,"context_line":"                device, self.agent.get_internal_device_name, router.ns_name))"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    def _assert_extra_routes(self, router):"},{"line_number":258,"context_line":"        routes \u003d ip_lib.get_routing_table(namespace\u003drouter.ns_name)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a80dd14_87dc8676","line":255,"in_reply_to":"ba7be1f8_dea5ec04","updated":"2015-03-04 05:02:50.000000000","message":"the onlink routes is on gateway port, not on interface port.\nIn addition, to test the l3 agent\u0027s extra subnet route on gw interface, it should be another patch. If you agree, I will file a bug and fix it.","commit_id":"f839bc0a8ea76d326d11b1b34b18e3b52257d71e"},{"author":{"_account_id":7715,"name":"Hirofumi Ichihara","email":"ichihara.hirofumi@gmail.com","username":"Hirofumi-Ichihara"},"change_message_id":"4ef0e56e916bdeb828f1fadc9f9b215d8fef0d56","unresolved":false,"context_lines":[{"line_number":453,"context_line":"            external_port[\u0027id\u0027])"},{"line_number":454,"context_line":"        onlink_route_cidrs \u003d [route[\u0027destination\u0027] for route in routes"},{"line_number":455,"context_line":"                              if route[\u0027scope\u0027] \u003d\u003d \u0027link\u0027"},{"line_number":456,"context_line":"                              and route[\u0027dev\u0027] \u003d\u003d external_device_name]"},{"line_number":457,"context_line":"        for onlink_subnet in external_port[\u0027extra_subnets\u0027]:"},{"line_number":458,"context_line":"            self.assertIn(onlink_subnet, onlink_route_cidrs)"},{"line_number":459,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9a80dd14_4d02723f","line":456,"updated":"2015-03-05 08:49:41.000000000","message":"route[\u0027dev\u0027] -\u003e route[\u0027device\u0027]","commit_id":"dbfec8a406642673f814adfc0d6f315c6b622f06"},{"author":{"_account_id":2874,"name":"yong sheng gong","email":"gong.yongsheng@99cloud.net","username":"gongysh"},"change_message_id":"9e9a814d974e01a2410f299e743a0c3a5458c213","unresolved":false,"context_lines":[{"line_number":453,"context_line":"            external_port[\u0027id\u0027])"},{"line_number":454,"context_line":"        onlink_route_cidrs \u003d [route[\u0027destination\u0027] for route in routes"},{"line_number":455,"context_line":"                              if route[\u0027scope\u0027] \u003d\u003d \u0027link\u0027"},{"line_number":456,"context_line":"                              and route[\u0027dev\u0027] \u003d\u003d external_device_name]"},{"line_number":457,"context_line":"        for onlink_subnet in external_port[\u0027extra_subnets\u0027]:"},{"line_number":458,"context_line":"            self.assertIn(onlink_subnet, onlink_route_cidrs)"},{"line_number":459,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"9a80dd14_03368b52","line":456,"in_reply_to":"9a80dd14_4d02723f","updated":"2015-03-05 09:24:12.000000000","message":"Thanks, Done","commit_id":"dbfec8a406642673f814adfc0d6f315c6b622f06"}]}
