)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"ba6394bedfd9fcaba285fd59608ff5a66cdbfd33","unresolved":false,"context_lines":[{"line_number":10,"context_line":""},{"line_number":11,"context_line":"This means we talk to the kernel directly via netlink, so we avoid the"},{"line_number":12,"context_line":"overhead of generating/parsing/executing iproute commands, version skew"},{"line_number":13,"context_line":"in iproute output, and rely less on sudo."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ie176358e3dcfd85cf5d9a4b6235dc41246ef8e5d"},{"line_number":16,"context_line":"Depends-On: Ia9675dff9232e0e987a836ecaf9e842eb5c3cb18"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"1a122d0e_e289d370","line":13,"updated":"2016-05-04 23:40:38.000000000","message":"Closes-bug: 1492714?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":10,"context_line":""},{"line_number":11,"context_line":"This means we talk to the kernel directly via netlink, so we avoid the"},{"line_number":12,"context_line":"overhead of generating/parsing/executing iproute commands, version skew"},{"line_number":13,"context_line":"in iproute output, and rely less on sudo."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ie176358e3dcfd85cf5d9a4b6235dc41246ef8e5d"},{"line_number":16,"context_line":"Depends-On: Ia9675dff9232e0e987a836ecaf9e842eb5c3cb18"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"9abb7d3a_73c8eaa8","line":13,"in_reply_to":"1a122d0e_e289d370","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"ba6394bedfd9fcaba285fd59608ff5a66cdbfd33","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"1a122d0e_02e4cf39","line":18,"updated":"2016-05-04 23:40:38.000000000","message":"shall we add a DocImpact, UpgradeImpact or release note?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"9abb7d3a_5312060a","line":18,"in_reply_to":"1a122d0e_02e4cf39","updated":"2016-06-01 03:59:05.000000000","message":"Hrm, yes probably.  The upgrade impact is the equivalent of the Depends-On patches to devstack (need to define privsep.helper_command to use rootwrap xor need to modify sudoers to allow default privsep-helper command line).  I will add a relno that tries to describe that...","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"ef68bba4794d28247262f7016110a78bf2fc2d15","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Ie176358e3dcfd85cf5d9a4b6235dc41246ef8e5d"},{"line_number":16,"context_line":"Depends-On: Ia9675dff9232e0e987a836ecaf9e842eb5c3cb18"},{"line_number":17,"context_line":"Depends-On: Id6395b8497b9f5449893e17d07fc4b664ee041ce"},{"line_number":18,"context_line":"Depends-On: I91fe18f66f3c3bc2ccd1ca8be91be2915ed3e3ec"},{"line_number":19,"context_line":"Closes-bug: 1492714"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"3aaa91ec_a8e9bd1c","line":18,"range":{"start_line":17,"start_character":0,"end_line":18,"end_character":53},"updated":"2016-06-22 14:40:47.000000000","message":"merged","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"}],"etc/neutron.conf":[{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"fb858773bca24c5e5c9c773b30208f67fe4f6803","unresolved":false,"context_lines":[{"line_number":1011,"context_line":"[privsep]"},{"line_number":1012,"context_line":"user \u003d daemon"},{"line_number":1013,"context_line":"group \u003d daemon"},{"line_number":1014,"context_line":"# NB: CAP_SYSADMIN is required to enter net namespaces"},{"line_number":1015,"context_line":"capabilities \u003d CAP_SYS_ADMIN, CAP_NET_ADMIN"},{"line_number":1016,"context_line":"helper_command \u003d neutron-privsep-helper --config-file\u003d/etc/neutron/neutron.conf"},{"line_number":1017,"context_line":"rootwrap_conf \u003d /etc/neutron/rootwrap.conf"}],"source_content_type":"text/plain","patch_set":8,"id":"7a016987_0d619c39","line":1014,"updated":"2015-05-21 17:06:42.000000000","message":"CAP_SYSADMIN or CAP_SYS_ADMIN?","commit_id":"4842f3f06be892d5f39cc8b997354db15d4e9014"}],"etc/neutron/rootwrap.d/privsep.filters":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"ca188c0bc7df8940ba2a851e7b611e76b0785593","unresolved":false,"context_lines":[{"line_number":5,"context_line":"[Filters]"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"# oslo.privsep default neutron context"},{"line_number":8,"context_line":"privsep: PathFilter, privsep-helper, root, privsep-helper, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"7aa08908_cf352b47","line":8,"range":{"start_line":8,"start_character":43,"end_line":8,"end_character":58},"updated":"2016-06-06 13:55:55.000000000","message":"this should be removed in order for filter to work","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"27225e2d4594da5b42ea41b1c06b19ceff45c535","unresolved":false,"context_lines":[{"line_number":5,"context_line":"[Filters]"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"# oslo.privsep default neutron context"},{"line_number":8,"context_line":"privsep: PathFilter, privsep-helper, root, privsep-helper, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"7aa08908_ef03b974","line":8,"range":{"start_line":8,"start_character":43,"end_line":8,"end_character":58},"in_reply_to":"7aa08908_cf352b47","updated":"2016-06-14 06:58:04.000000000","message":"Oops, thanks.  Done.","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"ca188c0bc7df8940ba2a851e7b611e76b0785593","unresolved":false,"context_lines":[{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"},{"line_number":12,"context_line":"# suit local requirements."},{"line_number":13,"context_line":"privsep: PathFilter, privsep-helper, root, privsep-helper, --config-file, /etc, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"7aa08908_0f40d3a4","line":13,"range":{"start_line":13,"start_character":43,"end_line":13,"end_character":58},"updated":"2016-06-06 13:55:55.000000000","message":"ditto","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"27225e2d4594da5b42ea41b1c06b19ceff45c535","unresolved":false,"context_lines":[{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"},{"line_number":12,"context_line":"# suit local requirements."},{"line_number":13,"context_line":"privsep: PathFilter, privsep-helper, root, privsep-helper, --config-file, /etc, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"7aa08908_6ff8697d","line":13,"range":{"start_line":13,"start_character":43,"end_line":13,"end_character":58},"in_reply_to":"7aa08908_0f40d3a4","updated":"2016-06-14 06:58:04.000000000","message":"Done","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"e6f03d55beb1670e153a109b6ef4c06993ff240e","unresolved":false,"context_lines":[{"line_number":5,"context_line":"[Filters]"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"# oslo.privsep default neutron context"},{"line_number":8,"context_line":"privsep: PathFilter, privsep-helper, root, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"}],"source_content_type":"application/octet-stream","patch_set":24,"id":"3aaa91ec_7147954b","line":8,"updated":"2016-06-23 01:17:08.000000000","message":"is there any way to line wrap some of this?","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"71d11b4186893c0662cdec0528453274348f084b","unresolved":false,"context_lines":[{"line_number":5,"context_line":"[Filters]"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"# oslo.privsep default neutron context"},{"line_number":8,"context_line":"privsep: PathFilter, privsep-helper, root, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, /"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"# Same as above with a second `--config-file` arg, since many neutron"},{"line_number":11,"context_line":"# components are installed like that (eg: by devstack).  Adjust to"}],"source_content_type":"application/octet-stream","patch_set":24,"id":"3aaa91ec_cbcb35a4","line":8,"in_reply_to":"3aaa91ec_7147954b","updated":"2016-06-23 05:47:28.000000000","message":"Huh, apparently rootwrap uses the standard configparser.RawConfigParser(), so ... \u003ctypey typey\u003e ... what\u0027s in the next revision should work.\n\nIt looks a lot clearer too, thanks for the nudge :)","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"}],"neutron/agent/linux/ip_lib.py":[{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f2133a2993dd9aa74ac72dff2ccdf06690ad6c8a","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def add_vxlan(self, name, vni, group\u003dNone, dev\u003dNone, ttl\u003dNone, tos\u003dNone,"},{"line_number":142,"context_line":"                  local\u003dNone, port\u003dNone, proxy\u003dFalse):"},{"line_number":143,"context_line":"        # TODO(gus): add vxlan support to pyroute2.IPDB"},{"line_number":144,"context_line":"        cmd \u003d [\u0027add\u0027, name, \u0027type\u0027, \u0027vxlan\u0027, \u0027id\u0027, vni]"},{"line_number":145,"context_line":"        if group:"},{"line_number":146,"context_line":"                cmd.extend([\u0027group\u0027, group])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_f3e997e6","line":143,"updated":"2015-03-10 07:47:11.000000000","message":"scheduled","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"7830b04ffbc2f8a5d7d6885bd31193407dc4d0f7","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def add_vxlan(self, name, vni, group\u003dNone, dev\u003dNone, ttl\u003dNone, tos\u003dNone,"},{"line_number":142,"context_line":"                  local\u003dNone, port\u003dNone, proxy\u003dFalse):"},{"line_number":143,"context_line":"        # TODO(gus): add vxlan support to pyroute2.IPDB"},{"line_number":144,"context_line":"        cmd \u003d [\u0027add\u0027, name, \u0027type\u0027, \u0027vxlan\u0027, \u0027id\u0027, vni]"},{"line_number":145,"context_line":"        if group:"},{"line_number":146,"context_line":"                cmd.extend([\u0027group\u0027, group])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_607bfd7a","line":143,"in_reply_to":"9a80dd14_f3e997e6","updated":"2015-03-10 13:28:44.000000000","message":"Done: https://github.com/svinota/pyroute2/issues/112","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"14bf51a540c12a28dfc920ca0bab8f0e35baf864","unresolved":false,"context_lines":[{"line_number":278,"context_line":"        self._parent.name \u003d name"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"    def set_alias(self, alias_name):"},{"line_number":281,"context_line":"        # TODO(gus): add alias support to pyroute2.IPDB"},{"line_number":282,"context_line":"        args \u003d [\u0027set\u0027, self.name, \u0027alias\u0027, alias_name]"},{"line_number":283,"context_line":"        self._as_root([], tuple(args))"},{"line_number":284,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a016987_82f212d1","line":281,"updated":"2015-05-15 13:49:19.000000000","message":"I\u0027m not sure if it is what you need, but:\n\n1. create interface with ifalias::\n\n    ipdb.create(ifname\u003d\u0027dummy_A\u0027, kind\u003d\u0027dummy\u0027, ifalias\u003d\u0027alias_A\u0027).commit()\n\n2. assign ifalias::\n\n    with ipdb.interfaces.dummy_B as i:\n        i.ifalias \u003d \u0027alias_B\u0027","commit_id":"4842f3f06be892d5f39cc8b997354db15d4e9014"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"14bf51a540c12a28dfc920ca0bab8f0e35baf864","unresolved":false,"context_lines":[{"line_number":310,"context_line":"        # TODO(gus): add alias support to pyroute2.IPDB"},{"line_number":311,"context_line":"        args \u003d [\u0027show\u0027, self.name]"},{"line_number":312,"context_line":"        attrs \u003d self._parse_line(self._run([\u0027o\u0027], args))"},{"line_number":313,"context_line":"        return attrs.get(\u0027alias\u0027)"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"    @property"},{"line_number":316,"context_line":"    def attributes(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a016987_e2ae6697","line":313,"updated":"2015-05-15 13:49:19.000000000","message":"the code::\n\n    return ipdb.interfaces[self.name].ifalias\n\nwill return a string or None","commit_id":"4842f3f06be892d5f39cc8b997354db15d4e9014"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"14bf51a540c12a28dfc920ca0bab8f0e35baf864","unresolved":false,"context_lines":[{"line_number":333,"context_line":"    COMMAND \u003d \u0027addr\u0027"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"    def add(self, cidr, scope\u003d\u0027global\u0027):"},{"line_number":336,"context_line":"        # TODO(gus): add \u0027scope\u0027 to pyroute2 Interface.add_ip()"},{"line_number":337,"context_line":"        net \u003d netaddr.IPNetwork(cidr)"},{"line_number":338,"context_line":"        args \u003d [\u0027add\u0027, cidr,"},{"line_number":339,"context_line":"                \u0027scope\u0027, scope,"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a016987_37bde268","line":336,"updated":"2015-05-15 13:49:19.000000000","message":"Done [1], will be released in 0.3.9\n\n[1] https://github.com/svinota/pyroute2/commit/5ca488fcce46e2e85a0b0679c84f48f51e3b57d5#diff-9a3cf0d3c9635ad1425ec090b55d07edR130","commit_id":"4842f3f06be892d5f39cc8b997354db15d4e9014"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"61c290fa67492c0a671e6b35d9e67c1367a50914","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"class IfNameCache(object):"},{"line_number":91,"context_line":"    def __init__(self, ns\u003dNone, ipdevice\u003dNone):"},{"line_number":92,"context_line":"        self.cache \u003d {}"},{"line_number":93,"context_line":"        self.namespace \u003d ns"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # This just optimises the common case where we already know"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_000bb97d","line":92,"updated":"2016-04-21 10:13:05.000000000","message":"can we please preifx the value with _","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"80d8db1a6947874002585033163d3878a268b319","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"class IfNameCache(object):"},{"line_number":91,"context_line":"    def __init__(self, ns\u003dNone, ipdevice\u003dNone):"},{"line_number":92,"context_line":"        self.cache \u003d {}"},{"line_number":93,"context_line":"        self.namespace \u003d ns"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # This just optimises the common case where we already know"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_e3f4c7f1","line":92,"in_reply_to":"1a122d0e_000bb97d","updated":"2016-04-21 10:25:07.000000000","message":"Sure, done.","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"61c290fa67492c0a671e6b35d9e67c1367a50914","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        except KeyError:"},{"line_number":106,"context_line":"            ifname \u003d priv_ip.get_link_names(idx, ns\u003dself.namespace)[0]"},{"line_number":107,"context_line":"            self.cache[idx] \u003d ifname"},{"line_number":108,"context_line":"            return ifname"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class SubProcessBase(object):"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_801fc9b5","line":108,"updated":"2016-04-21 10:13:05.000000000","message":"when will these entries be aged?\n\nwhy not use oslo cache?","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"80d8db1a6947874002585033163d3878a268b319","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        except KeyError:"},{"line_number":106,"context_line":"            ifname \u003d priv_ip.get_link_names(idx, ns\u003dself.namespace)[0]"},{"line_number":107,"context_line":"            self.cache[idx] \u003d ifname"},{"line_number":108,"context_line":"            return ifname"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class SubProcessBase(object):"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_03a46305","line":108,"in_reply_to":"1a122d0e_801fc9b5","updated":"2016-04-21 10:25:07.000000000","message":"They won\u0027t be aged.  See how this is used below: It is just used as a local cache while parsing the output of various commands - and then thrown away.  Ditto why I\u0027m not using oslo.cache, this is literally just a dict and a priv_ip.get_link_names lookup that I moved up here so I can reuse the code in two places.\n\nI know, I\u0027ll rename the entire class to _IfNameCache.  It\u0027s private and not meant to be something we overthink.","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    \u0027boot\u0027: 3,"},{"line_number":59,"context_line":"    \u0027static\u0027: 4,"},{"line_number":60,"context_line":"}"},{"line_number":61,"context_line":"RT_SCOPE_NAMES \u003d dict((v, k) for k, v in RT_SCOPES.items())"},{"line_number":62,"context_line":"RT_PROTO_NAMES \u003d dict((v, k) for k, v in RT_PROTOS.items())"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"# Interface address flags (selected highlights)"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_36997f6f","line":61,"updated":"2016-04-23 09:19:56.000000000","message":"This isn\u0027t 1999, dictionary comprehension! ;)\n\nRT_SCOPE_NAMES \u003d {v: k for k, v in RT_SCOPES.items()}\n\nOr, if you are believer in the church of map:\n\ndict(map(reversed, RT_SCOPES.items()))\n\nNo need to change this, I just wanted to make it look like I was contributing.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    \u0027boot\u0027: 3,"},{"line_number":59,"context_line":"    \u0027static\u0027: 4,"},{"line_number":60,"context_line":"}"},{"line_number":61,"context_line":"RT_SCOPE_NAMES \u003d dict((v, k) for k, v in RT_SCOPES.items())"},{"line_number":62,"context_line":"RT_PROTO_NAMES \u003d dict((v, k) for k, v in RT_PROTOS.items())"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"# Interface address flags (selected highlights)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_bc1b3fc9","line":61,"in_reply_to":"1a122d0e_36997f6f","updated":"2016-06-01 03:56:38.000000000","message":"Done","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":65,"context_line":"IFA_F_NODAD \u003d 0x02"},{"line_number":66,"context_line":"IFA_F_DADFAILED \u003d 0x08"},{"line_number":67,"context_line":"IFA_F_TENTATIVE \u003d 0x40"},{"line_number":68,"context_line":"IFA_F_PERMANENT \u003d 0x80"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"# Interface flags"},{"line_number":71,"context_line":"IFF_ALLMULTI \u003d 1 \u003c\u003c 9"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_169c435c","line":68,"updated":"2016-04-23 09:19:56.000000000","message":"All of these constants sound like insensitive ways to describe immigrants applying for citizenship. :)","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":65,"context_line":"IFA_F_NODAD \u003d 0x02"},{"line_number":66,"context_line":"IFA_F_DADFAILED \u003d 0x08"},{"line_number":67,"context_line":"IFA_F_TENTATIVE \u003d 0x40"},{"line_number":68,"context_line":"IFA_F_PERMANENT \u003d 0x80"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"# Interface flags"},{"line_number":71,"context_line":"IFF_ALLMULTI \u003d 1 \u003c\u003c 9"}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_3c862fdb","line":68,"in_reply_to":"1a122d0e_169c435c","updated":"2016-06-01 03:56:38.000000000","message":":)","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":68,"context_line":"IFA_F_PERMANENT \u003d 0x80"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"# Interface flags"},{"line_number":71,"context_line":"IFF_ALLMULTI \u003d 1 \u003c\u003c 9"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def remove_interface_suffix(interface):"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_76a3f79e","line":71,"updated":"2016-04-23 09:19:56.000000000","message":"I\u0027m not sure 1 \u003c\u003c 9 is any more self explanatory than 2 ** 9 or just 512. Can you add a comment about what the significance of the number is?","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":68,"context_line":"IFA_F_PERMANENT \u003d 0x80"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"# Interface flags"},{"line_number":71,"context_line":"IFF_ALLMULTI \u003d 1 \u003c\u003c 9"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"def remove_interface_suffix(interface):"}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_5c58538a","line":71,"in_reply_to":"1a122d0e_76a3f79e","updated":"2016-06-01 03:56:38.000000000","message":"I just used this form because that\u0027s how it was expressed in the kernel header.  Changed to a boring hex literal.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"c62f20a6706a7be9369c323639629d35c911513c","unresolved":false,"context_lines":[{"line_number":880,"context_line":"                    pass"},{"line_number":881,"context_line":"            if \u0027RTA_PRIORITY\u0027 in attrs:"},{"line_number":882,"context_line":"                # Legacy says this should be a string in get_routes()"},{"line_number":883,"context_line":"                # but not in get_gateway().  omg, kill me now."},{"line_number":884,"context_line":"                entry[\u0027metric\u0027] \u003d str(attrs[\u0027RTA_PRIORITY\u0027])"},{"line_number":885,"context_line":"            if \u0027RTA_OIF\u0027 in attrs:"},{"line_number":886,"context_line":"                entry[\u0027dev\u0027] \u003d ifname_cache.get(attrs[\u0027RTA_OIF\u0027])"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_2f8659db","line":883,"range":{"start_line":883,"start_character":61,"end_line":883,"end_character":62},"updated":"2016-04-22 16:25:47.000000000","message":"Angus, could you please tell me the API description?\n\nWhy I\u0027m asking, look: there is a helper module in pyroute2:\nhttps://github.com/svinota/pyroute2/blob/master/pyroute2/netlink/rtnl/req.py\n\nWhat it does — it translates keyword args from\n\n  {\u0027dst\u0027: \u0027default\u0027,\n   \u0027gateway\u0027: \u002710.0.0.2/24\u0027,\n   \u0027oif\u0027: 2,\n   \u0027metrics\u0027: {\u0027mtu\u0027: 1360}}\n\n… to the RTNL-friendly format. It is done transparently in `IPRoute.route()`:\n\nhttps://github.com/svinota/pyroute2/blob/master/pyroute2/iproute.py#L1439\n\nIf I anyway do it there, may be it would be simpler to extend it a bit — and support Neutron keywords also? I do not think it will require a big effort.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":880,"context_line":"                    pass"},{"line_number":881,"context_line":"            if \u0027RTA_PRIORITY\u0027 in attrs:"},{"line_number":882,"context_line":"                # Legacy says this should be a string in get_routes()"},{"line_number":883,"context_line":"                # but not in get_gateway().  omg, kill me now."},{"line_number":884,"context_line":"                entry[\u0027metric\u0027] \u003d str(attrs[\u0027RTA_PRIORITY\u0027])"},{"line_number":885,"context_line":"            if \u0027RTA_OIF\u0027 in attrs:"},{"line_number":886,"context_line":"                entry[\u0027dev\u0027] \u003d ifname_cache.get(attrs[\u0027RTA_OIF\u0027])"}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_1cc9ab26","line":883,"range":{"start_line":883,"start_character":61,"end_line":883,"end_character":62},"in_reply_to":"1a122d0e_2f8659db","updated":"2016-06-01 03:56:38.000000000","message":"Honestly I\u0027d rather keep the back-compat here and avoid it escaping to pollute the ecosystem further down-river.  One day we may be able to change the neutron callers to use proper kernel/rtnetlink values instead of iproute string options...","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"c62f20a6706a7be9369c323639629d35c911513c","unresolved":false,"context_lines":[{"line_number":901,"context_line":"    def delete_onlink_route(self, cidr):"},{"line_number":902,"context_line":"        self.delete_route(cidr, scope\u003d\u0027link\u0027)"},{"line_number":903,"context_line":""},{"line_number":904,"context_line":"    def get_gateway(self, scope\u003dNone, filters\u003dNone, ip_version\u003dNone):"},{"line_number":905,"context_line":"        args \u003d dict("},{"line_number":906,"context_line":"            mask\u003d0,  # default route"},{"line_number":907,"context_line":"            oif\u003dself._maybe_ifindex(),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_ef9741e9","line":904,"range":{"start_line":904,"start_character":19,"end_line":904,"end_character":20},"updated":"2016-04-22 16:25:47.000000000","message":"I have to think a bit, but so far it looks like at least partly the route filtering is already implemented in the library.\n\nBut I have to provide docs. That\u0027s not so easy, as usual :)","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        # the index-\u003ename for the device that we probably just used in"},{"line_number":97,"context_line":"        # the query.  In many cases this is the only interface in the"},{"line_number":98,"context_line":"        # result too."},{"line_number":99,"context_line":"        if ipdevice is not None and ipdevice._index is not None:"},{"line_number":100,"context_line":"            self._cache[ipdevice._index] \u003d ipdevice.name"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def get(self, idx):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_3acdf0b7","line":99,"range":{"start_line":99,"start_character":8,"end_line":99,"end_character":64},"updated":"2016-04-22 23:14:57.000000000","message":"assuming ipdevice._index might be 0 whereas ipdevice would be an object:\n\nif ipdevice and ipdevice._index is not None:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        # the index-\u003ename for the device that we probably just used in"},{"line_number":97,"context_line":"        # the query.  In many cases this is the only interface in the"},{"line_number":98,"context_line":"        # result too."},{"line_number":99,"context_line":"        if ipdevice is not None and ipdevice._index is not None:"},{"line_number":100,"context_line":"            self._cache[ipdevice._index] \u003d ipdevice.name"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def get(self, idx):"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_138fde2a","line":99,"range":{"start_line":99,"start_character":8,"end_line":99,"end_character":64},"in_reply_to":"1a122d0e_3acdf0b7","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        if self.namespace !\u003d namespace2:"},{"line_number":207,"context_line":"            idx \u003d priv_ip.get_iface_index(name2, ns\u003dself.namespace)"},{"line_number":208,"context_line":"            priv_ip.link(\u0027set\u0027, index\u003didx, net_ns_fd\u003dnamespace2)"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        return (IPDevice(name1, namespace\u003dself.namespace),"},{"line_number":211,"context_line":"                IPDevice(name2, namespace\u003dnamespace2))"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_fd76d2a1","line":208,"updated":"2016-04-22 23:14:57.000000000","message":"does this operation still ensure the existence of namespace2? I.e. from self.ensure_namespace()?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        if self.namespace !\u003d namespace2:"},{"line_number":207,"context_line":"            idx \u003d priv_ip.get_iface_index(name2, ns\u003dself.namespace)"},{"line_number":208,"context_line":"            priv_ip.link(\u0027set\u0027, index\u003didx, net_ns_fd\u003dnamespace2)"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        return (IPDevice(name1, namespace\u003dself.namespace),"},{"line_number":211,"context_line":"                IPDevice(name2, namespace\u003dnamespace2))"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_73b46a81","line":208,"in_reply_to":"1a122d0e_fd76d2a1","updated":"2016-06-01 03:59:05.000000000","message":"Good call, no it doesn\u0027t: https://github.com/svinota/pyroute2/blob/e2b4f0c266ef540002c95ef6b6c7485eef7f0426/pyroute2/netlink/rtnl/ifinfmsg.py#L339\n\nFixed.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":286,"context_line":"            ifname\u003dname,"},{"line_number":287,"context_line":"            vxlan_id\u003dint(vni),"},{"line_number":288,"context_line":"            vxlan_group\u003dgroup,"},{"line_number":289,"context_line":"            vxlan_link\u003ddev_idx,"},{"line_number":290,"context_line":"            vxlan_ttl\u003dNone if ttl is None else int(ttl),"},{"line_number":291,"context_line":"            vxlan_tos\u003dNone if tos is None else int(tos),"},{"line_number":292,"context_line":"            vxlan_local\u003dlocal,"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_d867a4b5","line":289,"range":{"start_line":289,"start_character":23,"end_line":289,"end_character":30},"updated":"2016-04-22 23:14:57.000000000","message":"dev_idx might be undefined if dev is None","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":286,"context_line":"            ifname\u003dname,"},{"line_number":287,"context_line":"            vxlan_id\u003dint(vni),"},{"line_number":288,"context_line":"            vxlan_group\u003dgroup,"},{"line_number":289,"context_line":"            vxlan_link\u003ddev_idx,"},{"line_number":290,"context_line":"            vxlan_ttl\u003dNone if ttl is None else int(ttl),"},{"line_number":291,"context_line":"            vxlan_tos\u003dNone if tos is None else int(tos),"},{"line_number":292,"context_line":"            vxlan_local\u003dlocal,"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_b379b2ca","line":289,"range":{"start_line":289,"start_character":23,"end_line":289,"end_character":30},"in_reply_to":"1a122d0e_d867a4b5","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        self.rule \u003d IpRuleCommand(self)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"class IpRuleCommand(IpCommandBase):"},{"line_number":427,"context_line":"    COMMAND \u003d \u0027rule\u0027"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_8ec9667c","line":426,"updated":"2016-04-22 23:14:57.000000000","message":"Can we make use of pyroute2 in this class? Maybe at least for list_rules: https://github.com/svinota/pyroute2/blob/0.3.10/pyroute2/iproute.py#L344\n\nI\u0027m not sure how to go about using pyroute2 to add/delete rules though.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"67cc1d71899a75d0e9ba06dd517a1f2df9b6e48f","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        self.rule \u003d IpRuleCommand(self)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"class IpRuleCommand(IpCommandBase):"},{"line_number":427,"context_line":"    COMMAND \u003d \u0027rule\u0027"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_e5810b4f","line":426,"in_reply_to":"1a122d0e_8ec9667c","updated":"2016-04-23 18:45:57.000000000","message":"The command docs:\n\nhttps://github.com/svinota/pyroute2/blob/0.3.21/pyroute2/iproute.py#L1495\n\nUsage samples in tests:\n\nhttps://github.com/svinota/pyroute2/blob/0.3.21/tests/general/test_rule.py\n\nThe only notice — positional arguments are deprecated, the only positional argument will remain the command («add», «delete», «dump», etc.). One can still use the same API, but with argument names, like:\n\n    ip.rule(\"add\", table\u003d20, priority\u003d32000, src\u003d\"10.0.0.0\", src_len\u003d24)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":423,"context_line":"        self.rule \u003d IpRuleCommand(self)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"class IpRuleCommand(IpCommandBase):"},{"line_number":427,"context_line":"    COMMAND \u003d \u0027rule\u0027"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_334ca29d","line":426,"in_reply_to":"1a122d0e_e5810b4f","updated":"2016-06-01 03:59:05.000000000","message":"(IpRule* conversion left for a future change)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"67cc1d71899a75d0e9ba06dd517a1f2df9b6e48f","unresolved":false,"context_lines":[{"line_number":595,"context_line":""},{"line_number":596,"context_line":"    def _link_attr(self, attr_name):"},{"line_number":597,"context_line":"        details \u003d self._link_details()"},{"line_number":598,"context_line":"        for name, value in details.get(\u0027attrs\u0027, []):"},{"line_number":599,"context_line":"            if name \u003d\u003d attr_name:"},{"line_number":600,"context_line":"                return value"},{"line_number":601,"context_line":"        return None"},{"line_number":602,"context_line":""},{"line_number":603,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_c5eb2f11","line":600,"range":{"start_line":598,"start_character":8,"end_line":600,"end_character":28},"updated":"2016-04-23 18:45:57.000000000","message":"Get one NLA from the message:\n\n    msg.get_attr(\"IFLA_IFNAME\")\n\nIf NLA doesn\u0027t exist, `get_attr()` returns None. If there are multiple NLAs of the same name, it will return only the first one.\n\nTo get multiple NLAs of the same name from the message as a list:\n\n    msg.get_attrs(\"IFLA_MACVLAN_MACADDR\")\n\nIf NLAs do not exist, the function returns an empty list.\n\nAs I wrote in comments to PS18, I can provide a wrapper class that would return NLAs as an ordered dict, but I can not promise that in the future in the kernel there won\u0027t be more cases, when a RTNL message contains multiple NLAs with the same name (right now in RTNL it happens only for macvlan interfaces).\n\nThat that\u0027s up to you to decide.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":595,"context_line":""},{"line_number":596,"context_line":"    def _link_attr(self, attr_name):"},{"line_number":597,"context_line":"        details \u003d self._link_details()"},{"line_number":598,"context_line":"        for name, value in details.get(\u0027attrs\u0027, []):"},{"line_number":599,"context_line":"            if name \u003d\u003d attr_name:"},{"line_number":600,"context_line":"                return value"},{"line_number":601,"context_line":"        return None"},{"line_number":602,"context_line":""},{"line_number":603,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_f32dfaa8","line":600,"range":{"start_line":598,"start_character":8,"end_line":600,"end_character":28},"in_reply_to":"1a122d0e_05b9a779","updated":"2016-06-01 03:59:05.000000000","message":"Understood - this helper was only intended for cases where multiple values didn\u0027t make sense.\n\nFixed to use msg.get_attr(..)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"35ceae62690de26e4f433031665ac544666ed858","unresolved":false,"context_lines":[{"line_number":595,"context_line":""},{"line_number":596,"context_line":"    def _link_attr(self, attr_name):"},{"line_number":597,"context_line":"        details \u003d self._link_details()"},{"line_number":598,"context_line":"        for name, value in details.get(\u0027attrs\u0027, []):"},{"line_number":599,"context_line":"            if name \u003d\u003d attr_name:"},{"line_number":600,"context_line":"                return value"},{"line_number":601,"context_line":"        return None"},{"line_number":602,"context_line":""},{"line_number":603,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_05b9a779","line":600,"range":{"start_line":598,"start_character":8,"end_line":600,"end_character":28},"in_reply_to":"1a122d0e_c5eb2f11","updated":"2016-04-23 21:27:32.000000000","message":"\u003e only for macvlan interfaces\n\nAgain, I was wrong. Just found the same for IFLA_VLAN_QOS_MAPPING. Stay tuned :)\n\nNot to spam here with all this info anymore — just think twice about NLAs as dicts. It\u0027s easy to implement, but later it may cost a lot of efforts to work around the cases like I described.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":639,"context_line":"        }"},{"line_number":640,"context_line":"        ret \u003d {}"},{"line_number":641,"context_line":"        for name, value in details.get(\u0027attrs\u0027, []):"},{"line_number":642,"context_line":"            try:"},{"line_number":643,"context_line":"                key \u003d ATTRMAP[name]"},{"line_number":644,"context_line":"            except KeyError:"},{"line_number":645,"context_line":"                continue"},{"line_number":646,"context_line":"            ret[key] \u003d value"},{"line_number":647,"context_line":"        return ret"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_29880c22","line":646,"range":{"start_line":642,"start_character":12,"end_line":646,"end_character":28},"updated":"2016-04-22 23:14:57.000000000","message":"key \u003d ATTRMAP.get(name, None)\nif key:\n    ret[key] \u003d value","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":639,"context_line":"        }"},{"line_number":640,"context_line":"        ret \u003d {}"},{"line_number":641,"context_line":"        for name, value in details.get(\u0027attrs\u0027, []):"},{"line_number":642,"context_line":"            try:"},{"line_number":643,"context_line":"                key \u003d ATTRMAP[name]"},{"line_number":644,"context_line":"            except KeyError:"},{"line_number":645,"context_line":"                continue"},{"line_number":646,"context_line":"            ret[key] \u003d value"},{"line_number":647,"context_line":"        return ret"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_96129c55","line":646,"range":{"start_line":642,"start_character":12,"end_line":646,"end_character":28},"in_reply_to":"1a122d0e_29880c22","updated":"2016-06-01 03:59:05.000000000","message":"That implies the values can\u0027t be None, which is probably a reasonable check anyway.  Changed.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":684,"context_line":"        @param name: if it\u0027s not None, only a device with that matching name"},{"line_number":685,"context_line":"                     will be returned."},{"line_number":686,"context_line":"        \"\"\""},{"line_number":687,"context_line":"        if to is not None and not isinstance(to, netaddr.IPNetwork):"},{"line_number":688,"context_line":"            to \u003d netaddr.IPNetwork(to)"},{"line_number":689,"context_line":"        if filters is None:"},{"line_number":690,"context_line":"            filters \u003d ()"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_8959605e","line":687,"range":{"start_line":687,"start_character":8,"end_line":687,"end_character":25},"updated":"2016-04-22 23:14:57.000000000","message":"if to and ...","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":684,"context_line":"        @param name: if it\u0027s not None, only a device with that matching name"},{"line_number":685,"context_line":"                     will be returned."},{"line_number":686,"context_line":"        \"\"\""},{"line_number":687,"context_line":"        if to is not None and not isinstance(to, netaddr.IPNetwork):"},{"line_number":688,"context_line":"            to \u003d netaddr.IPNetwork(to)"},{"line_number":689,"context_line":"        if filters is None:"},{"line_number":690,"context_line":"            filters \u003d ()"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_162d0c95","line":687,"range":{"start_line":687,"start_character":8,"end_line":687,"end_character":25},"in_reply_to":"1a122d0e_8959605e","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":688,"context_line":"            to \u003d netaddr.IPNetwork(to)"},{"line_number":689,"context_line":"        if filters is None:"},{"line_number":690,"context_line":"            filters \u003d ()"},{"line_number":691,"context_line":"        if ifindex is None and name is not None:"},{"line_number":692,"context_line":"            ifindex \u003d priv_ip.get_iface_index(name, ns\u003dself._parent.namespace)"},{"line_number":693,"context_line":""},{"line_number":694,"context_line":"        known_filters \u003d ["}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_8db96b31","line":691,"range":{"start_line":691,"start_character":8,"end_line":691,"end_character":48},"updated":"2016-04-22 23:14:57.000000000","message":"if ifindex is None and name:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":688,"context_line":"            to \u003d netaddr.IPNetwork(to)"},{"line_number":689,"context_line":"        if filters is None:"},{"line_number":690,"context_line":"            filters \u003d ()"},{"line_number":691,"context_line":"        if ifindex is None and name is not None:"},{"line_number":692,"context_line":"            ifindex \u003d priv_ip.get_iface_index(name, ns\u003dself._parent.namespace)"},{"line_number":693,"context_line":""},{"line_number":694,"context_line":"        known_filters \u003d ["}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_761e1860","line":691,"range":{"start_line":691,"start_character":8,"end_line":691,"end_character":48},"in_reply_to":"1a122d0e_8db96b31","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":726,"context_line":"            attrs \u003d dict(addr.get(\u0027attrs\u0027, []))"},{"line_number":727,"context_line":"            net \u003d netaddr.IPNetwork(\u0027%s/%s\u0027 % (attrs[\u0027IFA_ADDRESS\u0027],"},{"line_number":728,"context_line":"                                               addr[\u0027prefixlen\u0027]))"},{"line_number":729,"context_line":"            if to is not None and net.ip not in to:"},{"line_number":730,"context_line":"                continue"},{"line_number":731,"context_line":"            flags \u003d attrs.get(\u0027IFA_FLAGS\u0027, addr.get(\u0027flags\u0027, 0))"},{"line_number":732,"context_line":"            if flags \u0026 filter_mask !\u003d filter_value:"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_cd036375","line":729,"range":{"start_line":729,"start_character":12,"end_line":729,"end_character":51},"updated":"2016-04-22 23:14:57.000000000","message":"if to and net.ip not in to:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":726,"context_line":"            attrs \u003d dict(addr.get(\u0027attrs\u0027, []))"},{"line_number":727,"context_line":"            net \u003d netaddr.IPNetwork(\u0027%s/%s\u0027 % (attrs[\u0027IFA_ADDRESS\u0027],"},{"line_number":728,"context_line":"                                               addr[\u0027prefixlen\u0027]))"},{"line_number":729,"context_line":"            if to is not None and net.ip not in to:"},{"line_number":730,"context_line":"                continue"},{"line_number":731,"context_line":"            flags \u003d attrs.get(\u0027IFA_FLAGS\u0027, addr.get(\u0027flags\u0027, 0))"},{"line_number":732,"context_line":"            if flags \u0026 filter_mask !\u003d filter_value:"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_b63c00c9","line":729,"range":{"start_line":729,"start_character":12,"end_line":729,"end_character":51},"in_reply_to":"1a122d0e_cd036375","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":779,"context_line":"    def __init__(self, parent, table\u003dNone):"},{"line_number":780,"context_line":"        super(IpRouteCommand, self).__init__(parent)"},{"line_number":781,"context_line":"        if table is None:"},{"line_number":782,"context_line":"            table \u003d 254  # aka \u0027main\u0027"},{"line_number":783,"context_line":"        self._table \u003d table"},{"line_number":784,"context_line":""},{"line_number":785,"context_line":"    def table(self, table):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_f0ad549c","line":782,"range":{"start_line":782,"start_character":20,"end_line":782,"end_character":23},"updated":"2016-04-22 23:14:57.000000000","message":"Please use a constant for 254","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":779,"context_line":"    def __init__(self, parent, table\u003dNone):"},{"line_number":780,"context_line":"        super(IpRouteCommand, self).__init__(parent)"},{"line_number":781,"context_line":"        if table is None:"},{"line_number":782,"context_line":"            table \u003d 254  # aka \u0027main\u0027"},{"line_number":783,"context_line":"        self._table \u003d table"},{"line_number":784,"context_line":""},{"line_number":785,"context_line":"    def table(self, table):"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_f66048d1","line":782,"range":{"start_line":782,"start_character":20,"end_line":782,"end_character":23},"in_reply_to":"1a122d0e_f0ad549c","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":800,"context_line":"        route_args \u003d dict("},{"line_number":801,"context_line":"            ns\u003dself._parent.namespace,"},{"line_number":802,"context_line":"            family\u003dIP_FAMILY[ip_version],"},{"line_number":803,"context_line":"            dst_len\u003d0,  # default route"},{"line_number":804,"context_line":"            gateway\u003dgateway,"},{"line_number":805,"context_line":"            table\u003dtable or self._table,"},{"line_number":806,"context_line":"            oif\u003dself._maybe_ifindex(),"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_909fc05e","line":803,"range":{"start_line":803,"start_character":20,"end_line":803,"end_character":21},"updated":"2016-04-22 23:14:57.000000000","message":"Please use a constant for this","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":800,"context_line":"        route_args \u003d dict("},{"line_number":801,"context_line":"            ns\u003dself._parent.namespace,"},{"line_number":802,"context_line":"            family\u003dIP_FAMILY[ip_version],"},{"line_number":803,"context_line":"            dst_len\u003d0,  # default route"},{"line_number":804,"context_line":"            gateway\u003dgateway,"},{"line_number":805,"context_line":"            table\u003dtable or self._table,"},{"line_number":806,"context_line":"            oif\u003dself._maybe_ifindex(),"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_369db0bc","line":803,"range":{"start_line":803,"start_character":20,"end_line":803,"end_character":21},"in_reply_to":"1a122d0e_909fc05e","updated":"2016-06-01 03:59:05.000000000","message":"This is actually a cidr prefix length of 0, so I don\u0027t feel like the 0 here is a \"magic\" constant that needs further explanation.  Re-raise the comment if you disagree.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":805,"context_line":"            table\u003dtable or self._table,"},{"line_number":806,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":807,"context_line":"        )"},{"line_number":808,"context_line":"        if metric is not None:"},{"line_number":809,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"},{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        priv_ip.route(\u0027replace\u0027, **route_args)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_4d7753d4","line":808,"range":{"start_line":808,"start_character":8,"end_line":808,"end_character":30},"updated":"2016-04-22 23:14:57.000000000","message":"if metric:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":805,"context_line":"            table\u003dtable or self._table,"},{"line_number":806,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":807,"context_line":"        )"},{"line_number":808,"context_line":"        if metric is not None:"},{"line_number":809,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"},{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        priv_ip.route(\u0027replace\u0027, **route_args)"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_d6b9c416","line":808,"range":{"start_line":808,"start_character":8,"end_line":808,"end_character":30},"in_reply_to":"1a122d0e_4d7753d4","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        priv_ip.route(\u0027replace\u0027, **route_args)"},{"line_number":812,"context_line":""},{"line_number":813,"context_line":"    def _run_as_root_detect_device_not_found(self, *args, **kwargs):"},{"line_number":814,"context_line":"        try:"},{"line_number":815,"context_line":"            return self._as_root(*args, **kwargs)"},{"line_number":816,"context_line":"        except RuntimeError as rte:"},{"line_number":817,"context_line":"            with excutils.save_and_reraise_exception() as ctx:"},{"line_number":818,"context_line":"                if \"Cannot find device\" in str(rte):"},{"line_number":819,"context_line":"                    ctx.reraise \u003d False"},{"line_number":820,"context_line":"                    raise exceptions.DeviceNotFoundError(device_name\u003dself.name)"},{"line_number":821,"context_line":""},{"line_number":822,"context_line":"    def delete_gateway(self, gateway, table\u003dNone):"},{"line_number":823,"context_line":"        ip_version \u003d get_ip_version(gateway)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_705024d5","line":820,"range":{"start_line":813,"start_character":3,"end_line":820,"end_character":79},"updated":"2016-04-22 23:14:57.000000000","message":"This method can be removed now as it\u0027s not longer used.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":810,"context_line":""},{"line_number":811,"context_line":"        priv_ip.route(\u0027replace\u0027, **route_args)"},{"line_number":812,"context_line":""},{"line_number":813,"context_line":"    def _run_as_root_detect_device_not_found(self, *args, **kwargs):"},{"line_number":814,"context_line":"        try:"},{"line_number":815,"context_line":"            return self._as_root(*args, **kwargs)"},{"line_number":816,"context_line":"        except RuntimeError as rte:"},{"line_number":817,"context_line":"            with excutils.save_and_reraise_exception() as ctx:"},{"line_number":818,"context_line":"                if \"Cannot find device\" in str(rte):"},{"line_number":819,"context_line":"                    ctx.reraise \u003d False"},{"line_number":820,"context_line":"                    raise exceptions.DeviceNotFoundError(device_name\u003dself.name)"},{"line_number":821,"context_line":""},{"line_number":822,"context_line":"    def delete_gateway(self, gateway, table\u003dNone):"},{"line_number":823,"context_line":"        ip_version \u003d get_ip_version(gateway)"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_163eac8b","line":820,"range":{"start_line":813,"start_character":3,"end_line":820,"end_character":79},"in_reply_to":"1a122d0e_705024d5","updated":"2016-06-01 03:59:05.000000000","message":"(Already done)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":825,"context_line":"            \u0027del\u0027,"},{"line_number":826,"context_line":"            ns\u003dself._parent.namespace,"},{"line_number":827,"context_line":"            family\u003dIP_FAMILY[ip_version],"},{"line_number":828,"context_line":"            dst_len\u003d0,  # default route"},{"line_number":829,"context_line":"            gateway\u003dgateway,"},{"line_number":830,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":831,"context_line":"            table\u003dtable or self._table,"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_709ae46f","line":828,"range":{"start_line":828,"start_character":20,"end_line":828,"end_character":21},"updated":"2016-04-22 23:14:57.000000000","message":"use constant","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":825,"context_line":"            \u0027del\u0027,"},{"line_number":826,"context_line":"            ns\u003dself._parent.namespace,"},{"line_number":827,"context_line":"            family\u003dIP_FAMILY[ip_version],"},{"line_number":828,"context_line":"            dst_len\u003d0,  # default route"},{"line_number":829,"context_line":"            gateway\u003dgateway,"},{"line_number":830,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":831,"context_line":"            table\u003dtable or self._table,"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_f6e5e837","line":828,"range":{"start_line":828,"start_character":20,"end_line":828,"end_character":21},"in_reply_to":"1a122d0e_709ae46f","updated":"2016-06-01 03:59:05.000000000","message":"(ditto - this value is actually a length of zero)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":863,"context_line":"        ret \u003d []"},{"line_number":864,"context_line":"        for route in priv_ip.get_routes(**args):"},{"line_number":865,"context_line":"            attrs \u003d dict(route.get(\u0027attrs\u0027, []))"},{"line_number":866,"context_line":"            if route[\u0027dst_len\u0027] !\u003d 0:"},{"line_number":867,"context_line":"                dst \u003d \u0027%s/%s\u0027 % (attrs[\u0027RTA_DST\u0027], route[\u0027dst_len\u0027])"},{"line_number":868,"context_line":"            else:"},{"line_number":869,"context_line":"                # prefixlen\u003d\u003d0 -\u003e default route"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_b0b8fcc8","line":866,"range":{"start_line":866,"start_character":35,"end_line":866,"end_character":36},"updated":"2016-04-22 23:14:57.000000000","message":"use constant","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":876,"context_line":"                \u0027scope\u0027: RT_SCOPE_NAMES[route[\u0027scope\u0027]],"},{"line_number":877,"context_line":"            }"},{"line_number":878,"context_line":"            for netlink_name, iproute_name in ATTRMAP.items():"},{"line_number":879,"context_line":"                try:"},{"line_number":880,"context_line":"                    entry[iproute_name] \u003d attrs[netlink_name]"},{"line_number":881,"context_line":"                except KeyError:"},{"line_number":882,"context_line":"                    pass"},{"line_number":883,"context_line":"            if \u0027RTA_PRIORITY\u0027 in attrs:"},{"line_number":884,"context_line":"                # Legacy says this should be a string in get_routes()"},{"line_number":885,"context_line":"                # but not in get_gateway().  omg, kill me now."}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_9077c001","line":882,"range":{"start_line":879,"start_character":16,"end_line":882,"end_character":24},"updated":"2016-04-22 23:14:57.000000000","message":"attr \u003d attrs.get(netlink_name, None)\nif attr:\n    entry[iproute_name] \u003d attr","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":876,"context_line":"                \u0027scope\u0027: RT_SCOPE_NAMES[route[\u0027scope\u0027]],"},{"line_number":877,"context_line":"            }"},{"line_number":878,"context_line":"            for netlink_name, iproute_name in ATTRMAP.items():"},{"line_number":879,"context_line":"                try:"},{"line_number":880,"context_line":"                    entry[iproute_name] \u003d attrs[netlink_name]"},{"line_number":881,"context_line":"                except KeyError:"},{"line_number":882,"context_line":"                    pass"},{"line_number":883,"context_line":"            if \u0027RTA_PRIORITY\u0027 in attrs:"},{"line_number":884,"context_line":"                # Legacy says this should be a string in get_routes()"},{"line_number":885,"context_line":"                # but not in get_gateway().  omg, kill me now."}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_d66704b5","line":882,"range":{"start_line":879,"start_character":16,"end_line":882,"end_character":24},"in_reply_to":"1a122d0e_9077c001","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":905,"context_line":""},{"line_number":906,"context_line":"    def get_gateway(self, scope\u003dNone, filters\u003dNone, ip_version\u003dNone):"},{"line_number":907,"context_line":"        args \u003d dict("},{"line_number":908,"context_line":"            dst_len\u003d0,  # default route"},{"line_number":909,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":910,"context_line":"            table\u003dself._table,"},{"line_number":911,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_d0877810","line":908,"range":{"start_line":908,"start_character":20,"end_line":908,"end_character":21},"updated":"2016-04-22 23:14:57.000000000","message":"use a constant","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":909,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":910,"context_line":"            table\u003dself._table,"},{"line_number":911,"context_line":"        )"},{"line_number":912,"context_line":"        if scope is not None:"},{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_f06f14fa","line":912,"range":{"start_line":912,"start_character":8,"end_line":912,"end_character":29},"updated":"2016-04-22 23:14:57.000000000","message":"if scope:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":909,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":910,"context_line":"            table\u003dself._table,"},{"line_number":911,"context_line":"        )"},{"line_number":912,"context_line":"        if scope is not None:"},{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_56295436","line":912,"range":{"start_line":912,"start_character":8,"end_line":912,"end_character":29},"in_reply_to":"1a122d0e_f06f14fa","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":911,"context_line":"        )"},{"line_number":912,"context_line":"        if scope is not None:"},{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"},{"line_number":916,"context_line":"        if filters is not None:"},{"line_number":917,"context_line":"            for i in range(0, len(filters), 2):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_707ca4b5","line":914,"range":{"start_line":914,"start_character":8,"end_line":914,"end_character":34},"updated":"2016-04-22 23:14:57.000000000","message":"if ip_version:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":911,"context_line":"        )"},{"line_number":912,"context_line":"        if scope is not None:"},{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"},{"line_number":916,"context_line":"        if filters is not None:"},{"line_number":917,"context_line":"            for i in range(0, len(filters), 2):"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_7624585f","line":914,"range":{"start_line":914,"start_character":8,"end_line":914,"end_character":34},"in_reply_to":"1a122d0e_707ca4b5","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"},{"line_number":916,"context_line":"        if filters is not None:"},{"line_number":917,"context_line":"            for i in range(0, len(filters), 2):"},{"line_number":918,"context_line":"                args[filters[i]] \u003d args[filters[i + 1]]"},{"line_number":919,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_502528c0","line":916,"range":{"start_line":916,"start_character":8,"end_line":916,"end_character":31},"updated":"2016-04-22 23:14:57.000000000","message":"if filters:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":913,"context_line":"            args[\u0027rtscope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":914,"context_line":"        if ip_version is not None:"},{"line_number":915,"context_line":"            args[\u0027family\u0027] \u003d IP_FAMILY[ip_version]"},{"line_number":916,"context_line":"        if filters is not None:"},{"line_number":917,"context_line":"            for i in range(0, len(filters), 2):"},{"line_number":918,"context_line":"                args[filters[i]] \u003d args[filters[i + 1]]"},{"line_number":919,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_362e5043","line":916,"range":{"start_line":916,"start_character":8,"end_line":916,"end_character":31},"in_reply_to":"1a122d0e_502528c0","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":938,"context_line":"            table\u003dtable or self._table,"},{"line_number":939,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":940,"context_line":"        )"},{"line_number":941,"context_line":"        if via is not None:"},{"line_number":942,"context_line":"            route_args[\u0027gateway\u0027] \u003d via"},{"line_number":943,"context_line":"        if metric is not None:"},{"line_number":944,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_f3227ea2","line":941,"range":{"start_line":941,"start_character":8,"end_line":941,"end_character":27},"updated":"2016-04-22 23:14:57.000000000","message":"if via:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":938,"context_line":"            table\u003dtable or self._table,"},{"line_number":939,"context_line":"            oif\u003dself._maybe_ifindex(),"},{"line_number":940,"context_line":"        )"},{"line_number":941,"context_line":"        if via is not None:"},{"line_number":942,"context_line":"            route_args[\u0027gateway\u0027] \u003d via"},{"line_number":943,"context_line":"        if metric is not None:"},{"line_number":944,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_d6fee4ac","line":941,"range":{"start_line":941,"start_character":8,"end_line":941,"end_character":27},"in_reply_to":"1a122d0e_f3227ea2","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":942,"context_line":"            route_args[\u0027gateway\u0027] \u003d via"},{"line_number":943,"context_line":"        if metric is not None:"},{"line_number":944,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"},{"line_number":945,"context_line":"        if scope is not None:"},{"line_number":946,"context_line":"            route_args[\u0027scope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"        priv_ip.route(cmd, **route_args)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_533a52ce","line":945,"range":{"start_line":945,"start_character":8,"end_line":945,"end_character":29},"updated":"2016-04-22 23:14:57.000000000","message":"if scope:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":942,"context_line":"            route_args[\u0027gateway\u0027] \u003d via"},{"line_number":943,"context_line":"        if metric is not None:"},{"line_number":944,"context_line":"            route_args[\u0027priority\u0027] \u003d metric"},{"line_number":945,"context_line":"        if scope is not None:"},{"line_number":946,"context_line":"            route_args[\u0027scope\u0027] \u003d RT_SCOPES[scope]"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"        priv_ip.route(cmd, **route_args)"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_f60168b0","line":945,"range":{"start_line":945,"start_character":8,"end_line":945,"end_character":29},"in_reply_to":"1a122d0e_533a52ce","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":963,"context_line":""},{"line_number":964,"context_line":"    @property"},{"line_number":965,"context_line":"    def index(self):"},{"line_number":966,"context_line":"        if self._index is None and self.name is not None:"},{"line_number":967,"context_line":"            self._index \u003d priv_ip.get_iface_index(self.name, ns\u003dself.namespace)"},{"line_number":968,"context_line":"        return self._index"},{"line_number":969,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_d37302b3","line":966,"range":{"start_line":966,"start_character":35,"end_line":966,"end_character":57},"updated":"2016-04-22 23:14:57.000000000","message":"self.name:","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":963,"context_line":""},{"line_number":964,"context_line":"    @property"},{"line_number":965,"context_line":"    def index(self):"},{"line_number":966,"context_line":"        if self._index is None and self.name is not None:"},{"line_number":967,"context_line":"            self._index \u003d priv_ip.get_iface_index(self.name, ns\u003dself.namespace)"},{"line_number":968,"context_line":"        return self._index"},{"line_number":969,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_b6fb60c0","line":966,"range":{"start_line":966,"start_character":35,"end_line":966,"end_character":57},"in_reply_to":"1a122d0e_d37302b3","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":968,"context_line":"        return self._index"},{"line_number":969,"context_line":""},{"line_number":970,"context_line":""},{"line_number":971,"context_line":"class IpNeighCommand(IpDeviceCommandBase):"},{"line_number":972,"context_line":"    COMMAND \u003d \u0027neigh\u0027"},{"line_number":973,"context_line":""},{"line_number":974,"context_line":"    def add(self, ip_address, mac_address):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_d381424f","line":971,"updated":"2016-04-22 23:14:57.000000000","message":"Can we use pyroute2 here? https://github.com/svinota/pyroute2/blob/0.3.10/pyroute2/iproute.py#L536","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":968,"context_line":"        return self._index"},{"line_number":969,"context_line":""},{"line_number":970,"context_line":""},{"line_number":971,"context_line":"class IpNeighCommand(IpDeviceCommandBase):"},{"line_number":972,"context_line":"    COMMAND \u003d \u0027neigh\u0027"},{"line_number":973,"context_line":""},{"line_number":974,"context_line":"    def add(self, ip_address, mac_address):"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_961f3c07","line":971,"in_reply_to":"1a122d0e_d381424f","updated":"2016-06-01 03:59:05.000000000","message":"Yes, but intentionally left until a later change.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":1008,"context_line":"    COMMAND \u003d \u0027netns\u0027"},{"line_number":1009,"context_line":""},{"line_number":1010,"context_line":"    def add(self, name):"},{"line_number":1011,"context_line":"        self._as_root([], (\u0027add\u0027, name), use_root_namespace\u003dTrue)"},{"line_number":1012,"context_line":"        wrapper \u003d IPWrapper(namespace\u003dname)"},{"line_number":1013,"context_line":"        wrapper.netns.execute([\u0027sysctl\u0027, \u0027-w\u0027,"},{"line_number":1014,"context_line":"                               \u0027net.ipv4.conf.all.promote_secondaries\u003d1\u0027])"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_98aa4cd1","line":1011,"updated":"2016-04-22 23:14:57.000000000","message":"Use pyroute2 to create the namespace?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":1008,"context_line":"    COMMAND \u003d \u0027netns\u0027"},{"line_number":1009,"context_line":""},{"line_number":1010,"context_line":"    def add(self, name):"},{"line_number":1011,"context_line":"        self._as_root([], (\u0027add\u0027, name), use_root_namespace\u003dTrue)"},{"line_number":1012,"context_line":"        wrapper \u003d IPWrapper(namespace\u003dname)"},{"line_number":1013,"context_line":"        wrapper.netns.execute([\u0027sysctl\u0027, \u0027-w\u0027,"},{"line_number":1014,"context_line":"                               \u0027net.ipv4.conf.all.promote_secondaries\u003d1\u0027])"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_76b29807","line":1011,"in_reply_to":"1a122d0e_98aa4cd1","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":1015,"context_line":"        return wrapper"},{"line_number":1016,"context_line":""},{"line_number":1017,"context_line":"    def delete(self, name):"},{"line_number":1018,"context_line":"        self._as_root([], (\u0027delete\u0027, name), use_root_namespace\u003dTrue)"},{"line_number":1019,"context_line":""},{"line_number":1020,"context_line":"    def execute(self, cmds, addl_env\u003dNone, check_exit_code\u003dTrue,"},{"line_number":1021,"context_line":"                log_fail_as_error\u003dTrue, extra_ok_codes\u003dNone,"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_38821853","line":1018,"updated":"2016-04-22 23:14:57.000000000","message":"Use pyroute2 to delete the namespace?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":1015,"context_line":"        return wrapper"},{"line_number":1016,"context_line":""},{"line_number":1017,"context_line":"    def delete(self, name):"},{"line_number":1018,"context_line":"        self._as_root([], (\u0027delete\u0027, name), use_root_namespace\u003dTrue)"},{"line_number":1019,"context_line":""},{"line_number":1020,"context_line":"    def execute(self, cmds, addl_env\u003dNone, check_exit_code\u003dTrue,"},{"line_number":1021,"context_line":"                log_fail_as_error\u003dTrue, extra_ok_codes\u003dNone,"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_b6d08020","line":1018,"in_reply_to":"1a122d0e_38821853","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":1039,"context_line":"        return name in priv_ip.netns_list()"},{"line_number":1040,"context_line":""},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"def vlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1043,"context_line":"    \"\"\"Return True if VLAN ID is in use by an interface, else False.\"\"\""},{"line_number":1044,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1045,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1046,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1047,"context_line":"    return \u0027802.1Q id %s \u0027 % segmentation_id in interfaces"},{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"def vxlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1051,"context_line":"    \"\"\"Return True if VXLAN VNID is in use by an interface, else False.\"\"\""},{"line_number":1052,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1053,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1054,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1055,"context_line":"    return \u0027vxlan id %s \u0027 % segmentation_id in interfaces"},{"line_number":1056,"context_line":""},{"line_number":1057,"context_line":""},{"line_number":1058,"context_line":"def device_exists(device_name, namespace\u003dNone):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_93550ac8","line":1055,"range":{"start_line":1042,"start_character":0,"end_line":1055,"end_character":57},"updated":"2016-04-22 23:14:57.000000000","message":"Can we get vlan and vxlan ids from pyroute2? That would eliminate the need to call the execute method here.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":1039,"context_line":"        return name in priv_ip.netns_list()"},{"line_number":1040,"context_line":""},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"def vlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1043,"context_line":"    \"\"\"Return True if VLAN ID is in use by an interface, else False.\"\"\""},{"line_number":1044,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1045,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1046,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1047,"context_line":"    return \u0027802.1Q id %s \u0027 % segmentation_id in interfaces"},{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"def vxlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1051,"context_line":"    \"\"\"Return True if VXLAN VNID is in use by an interface, else False.\"\"\""},{"line_number":1052,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1053,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1054,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1055,"context_line":"    return \u0027vxlan id %s \u0027 % segmentation_id in interfaces"},{"line_number":1056,"context_line":""},{"line_number":1057,"context_line":""},{"line_number":1058,"context_line":"def device_exists(device_name, namespace\u003dNone):"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_9ccc7b6b","line":1055,"range":{"start_line":1042,"start_character":0,"end_line":1055,"end_character":57},"in_reply_to":"1a122d0e_2541430c","updated":"2016-06-01 03:59:05.000000000","message":"Done.  @svinota it would be great if you could double-check I\u0027ve done this sensibly.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"67cc1d71899a75d0e9ba06dd517a1f2df9b6e48f","unresolved":false,"context_lines":[{"line_number":1039,"context_line":"        return name in priv_ip.netns_list()"},{"line_number":1040,"context_line":""},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"def vlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1043,"context_line":"    \"\"\"Return True if VLAN ID is in use by an interface, else False.\"\"\""},{"line_number":1044,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1045,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1046,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1047,"context_line":"    return \u0027802.1Q id %s \u0027 % segmentation_id in interfaces"},{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"def vxlan_in_use(segmentation_id, namespace\u003dNone):"},{"line_number":1051,"context_line":"    \"\"\"Return True if VXLAN VNID is in use by an interface, else False.\"\"\""},{"line_number":1052,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1053,"context_line":"    interfaces \u003d ip_wrapper.netns.execute([\"ip\", \"-d\", \"link\", \"list\"],"},{"line_number":1054,"context_line":"                                          check_exit_code\u003dTrue)"},{"line_number":1055,"context_line":"    return \u0027vxlan id %s \u0027 % segmentation_id in interfaces"},{"line_number":1056,"context_line":""},{"line_number":1057,"context_line":""},{"line_number":1058,"context_line":"def device_exists(device_name, namespace\u003dNone):"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_2541430c","line":1055,"range":{"start_line":1042,"start_character":0,"end_line":1055,"end_character":57},"in_reply_to":"1a122d0e_93550ac8","updated":"2016-04-23 18:45:57.000000000","message":"Yes we can:\n\n  # assume idx ← VLAN interface index\n  #\n  # get VLAN id:\n  In [8]: (ip.link(\"get\", index\u003didx)[0]\n     ...:         .get_attr(\"IFLA_LINKINFO\")\n     ...:         .get_attr(\"IFLA_INFO_DATA\")\n     ...:         .get_attr(\"IFLA_VLAN_ID\"))\n  Out[8]: 809\n\n  # get the master interface index for VLAN\n  In [9]: (ip.link(\"get\", index\u003didx)[0]\n     ...:         .get_attr(\"IFLA_LINK\"))\n  Out[9]: 33489","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":1092,"context_line":""},{"line_number":1093,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1094,"context_line":"    table \u003d ip_wrapper.netns.execute("},{"line_number":1095,"context_line":"        [\u0027ip\u0027, \u0027-%s\u0027 % ip_version, \u0027route\u0027],"},{"line_number":1096,"context_line":"        check_exit_code\u003dTrue)"},{"line_number":1097,"context_line":""},{"line_number":1098,"context_line":"    routes \u003d []"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_33f4f6cd","line":1095,"updated":"2016-04-22 23:14:57.000000000","message":"use a pyroute2 equivalent?","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"26b1fce9d10699f7a89230ca408a5a388821e434","unresolved":false,"context_lines":[{"line_number":1092,"context_line":""},{"line_number":1093,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1094,"context_line":"    table \u003d ip_wrapper.netns.execute("},{"line_number":1095,"context_line":"        [\u0027ip\u0027, \u0027-%s\u0027 % ip_version, \u0027route\u0027],"},{"line_number":1096,"context_line":"        check_exit_code\u003dTrue)"},{"line_number":1097,"context_line":""},{"line_number":1098,"context_line":"    routes \u003d []"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_9bf194d0","line":1095,"in_reply_to":"1a122d0e_33f4f6cd","updated":"2016-04-24 01:50:00.000000000","message":"Yes, there\u0027s lots of other commands that can be changed.  I\u0027ve been updating this change to add more over time, but I\u0027m also concious that a larger change is harder to review - so at some point I feel I should hold off.  Happy to rewrite this entire file in the one change if you feel that would be more straightforward to review.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":1092,"context_line":""},{"line_number":1093,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1094,"context_line":"    table \u003d ip_wrapper.netns.execute("},{"line_number":1095,"context_line":"        [\u0027ip\u0027, \u0027-%s\u0027 % ip_version, \u0027route\u0027],"},{"line_number":1096,"context_line":"        check_exit_code\u003dTrue)"},{"line_number":1097,"context_line":""},{"line_number":1098,"context_line":"    routes \u003d []"}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_5c333362","line":1095,"in_reply_to":"1a122d0e_7d5d7478","updated":"2016-06-01 03:59:05.000000000","message":"Yep, leaving to a later change.  We\u0027re done when grep run_as_root ip_lib.py exits non-zero ;)","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"d9bfd75674f4ffd939a6754ac3714eb8fccc9dad","unresolved":false,"context_lines":[{"line_number":1092,"context_line":""},{"line_number":1093,"context_line":"    ip_wrapper \u003d IPWrapper(namespace\u003dnamespace)"},{"line_number":1094,"context_line":"    table \u003d ip_wrapper.netns.execute("},{"line_number":1095,"context_line":"        [\u0027ip\u0027, \u0027-%s\u0027 % ip_version, \u0027route\u0027],"},{"line_number":1096,"context_line":"        check_exit_code\u003dTrue)"},{"line_number":1097,"context_line":""},{"line_number":1098,"context_line":"    routes \u003d []"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_7d5d7478","line":1095,"in_reply_to":"1a122d0e_9bf194d0","updated":"2016-04-25 16:22:26.000000000","message":"I agree that this patch is already large enough as-is. I\u0027m happy to review follow-up patches, just as long as we\u0027re making note of what more we can update.","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"dcad034db80103ebefd5b8e9710f901c5112db67","unresolved":false,"context_lines":[{"line_number":652,"context_line":""},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"class IpAddrCommand(IpDeviceCommandBase):"},{"line_number":655,"context_line":"    COMMAND \u003d \u0027addr\u0027"},{"line_number":656,"context_line":""},{"line_number":657,"context_line":"    def add(self, cidr, scope\u003d\u0027global\u0027, add_broadcast\u003dTrue):"},{"line_number":658,"context_line":"        net \u003d netaddr.IPNetwork(cidr)"}],"source_content_type":"text/x-python","patch_set":21,"id":"9abb7d3a_96e35833","line":655,"range":{"start_line":655,"start_character":4,"end_line":655,"end_character":11},"updated":"2016-06-02 14:13:43.000000000","message":"Just to be curious — do we still need this COMMAND attribute?","commit_id":"36a247c179a8c848ad2371ecd8de10fc02f3db96"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"f7294b6ca730df2df391b886089628a225bb99fa","unresolved":false,"context_lines":[{"line_number":652,"context_line":""},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"class IpAddrCommand(IpDeviceCommandBase):"},{"line_number":655,"context_line":"    COMMAND \u003d \u0027addr\u0027"},{"line_number":656,"context_line":""},{"line_number":657,"context_line":"    def add(self, cidr, scope\u003d\u0027global\u0027, add_broadcast\u003dTrue):"},{"line_number":658,"context_line":"        net \u003d netaddr.IPNetwork(cidr)"}],"source_content_type":"text/x-python","patch_set":21,"id":"7aa08908_2d033075","line":655,"range":{"start_line":655,"start_character":4,"end_line":655,"end_character":11},"in_reply_to":"9abb7d3a_96e35833","updated":"2016-06-06 07:15:39.000000000","message":"I don\u0027t think so, but it is a part of IpCommandBase, of which we are still a subclass.  I was leaving it in just in case - until we rip out all the _run/_as_root stuff entirely.\n\nIf I was writing this module again from scratch, it would be composed quite differently :)","commit_id":"36a247c179a8c848ad2371ecd8de10fc02f3db96"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"dcad034db80103ebefd5b8e9710f901c5112db67","unresolved":false,"context_lines":[{"line_number":1036,"context_line":"        return name in priv_ip.netns_list()"},{"line_number":1037,"context_line":""},{"line_number":1038,"context_line":""},{"line_number":1039,"context_line":"def _nested_attrs(msg, *attrs):"},{"line_number":1040,"context_line":"    if not msg:"},{"line_number":1041,"context_line":"        pass"},{"line_number":1042,"context_line":"    elif not attrs:"},{"line_number":1043,"context_line":"        yield msg"},{"line_number":1044,"context_line":"    else:"},{"line_number":1045,"context_line":"        for value in msg.get_attrs(attrs[0]):"},{"line_number":1046,"context_line":"            for x in _nested_attrs(value, *attrs[1:]):"},{"line_number":1047,"context_line":"                yield x"},{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"def vlan_in_use(segmentation_id, namespace\u003dNone):"}],"source_content_type":"text/x-python","patch_set":21,"id":"9abb7d3a_f672a4af","line":1047,"range":{"start_line":1039,"start_character":0,"end_line":1047,"end_character":23},"updated":"2016-06-02 14:13:43.000000000","message":"I can not say it looks simple enough :) But it works, I tested.\n\nJust in case, I added a method like that into the library (but implemented a bit differently). Starting with 0.4.2 it will be possible to call:\n\n    vid \u003d msg.get_nested(\u0027IFLA_LINKINFO\u0027,\n                         \u0027IFLA_INFO_DATA,\n                         \u0027IFLA_VLAN_ID\u0027)\n\n… and if no IFLA_LINKINFO/IFLA_INFO_DATA/IFLA_VLAN_ID exists in the message, vid will be None.\n\nhttps://github.com/svinota/pyroute2/commit/c413b25b61b01ce60618e05dc5b24c9301cf600f","commit_id":"36a247c179a8c848ad2371ecd8de10fc02f3db96"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"f7294b6ca730df2df391b886089628a225bb99fa","unresolved":false,"context_lines":[{"line_number":1036,"context_line":"        return name in priv_ip.netns_list()"},{"line_number":1037,"context_line":""},{"line_number":1038,"context_line":""},{"line_number":1039,"context_line":"def _nested_attrs(msg, *attrs):"},{"line_number":1040,"context_line":"    if not msg:"},{"line_number":1041,"context_line":"        pass"},{"line_number":1042,"context_line":"    elif not attrs:"},{"line_number":1043,"context_line":"        yield msg"},{"line_number":1044,"context_line":"    else:"},{"line_number":1045,"context_line":"        for value in msg.get_attrs(attrs[0]):"},{"line_number":1046,"context_line":"            for x in _nested_attrs(value, *attrs[1:]):"},{"line_number":1047,"context_line":"                yield x"},{"line_number":1048,"context_line":""},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"def vlan_in_use(segmentation_id, namespace\u003dNone):"}],"source_content_type":"text/x-python","patch_set":21,"id":"7aa08908_ade2809d","line":1047,"range":{"start_line":1039,"start_character":0,"end_line":1047,"end_character":23},"in_reply_to":"9abb7d3a_f672a4af","updated":"2016-06-06 07:15:39.000000000","message":"Yeah fine, your version is a lot simpler :P I was trying to be good and not assume there was only a single value for each attribute!  Replaced with your version.\n\nOh, and I remember why it wasn\u0027t using msg.get_attr() before - these are just dumb dict/lists, not actually nlmsg_base objects :(","commit_id":"36a247c179a8c848ad2371ecd8de10fc02f3db96"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"7ddc634bbad7f041efdfb2eff795c137f66ceabd","unresolved":false,"context_lines":[{"line_number":339,"context_line":"            idx \u003d priv_ip.get_iface_index(self.name, ns\u003dself.namespace)"},{"line_number":340,"context_line":"            self._index \u003d idx  # May as well cache what we just learned"},{"line_number":341,"context_line":"            return True"},{"line_number":342,"context_line":"        except KeyError:"},{"line_number":343,"context_line":"            return False"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def delete_addr_and_conntrack_state(self, cidr):"}],"source_content_type":"text/x-python","patch_set":22,"id":"7aa08908_9d0eba32","line":342,"range":{"start_line":342,"start_character":15,"end_line":342,"end_character":23},"updated":"2016-06-06 14:54:30.000000000","message":"OSError is thrown if namespace does not exists","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"27225e2d4594da5b42ea41b1c06b19ceff45c535","unresolved":false,"context_lines":[{"line_number":339,"context_line":"            idx \u003d priv_ip.get_iface_index(self.name, ns\u003dself.namespace)"},{"line_number":340,"context_line":"            self._index \u003d idx  # May as well cache what we just learned"},{"line_number":341,"context_line":"            return True"},{"line_number":342,"context_line":"        except KeyError:"},{"line_number":343,"context_line":"            return False"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def delete_addr_and_conntrack_state(self, cidr):"}],"source_content_type":"text/x-python","patch_set":22,"id":"7aa08908_7684485d","line":342,"range":{"start_line":342,"start_character":15,"end_line":342,"end_character":23},"in_reply_to":"7aa08908_9d0eba32","updated":"2016-06-14 06:58:04.000000000","message":"Done","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"7ddc634bbad7f041efdfb2eff795c137f66ceabd","unresolved":false,"context_lines":[{"line_number":1140,"context_line":"        # Ensure the device is up, even if it is already up. If the device"},{"line_number":1141,"context_line":"        # doesn\u0027t exist, a KeyError will be raised."},{"line_number":1142,"context_line":"        dev.link.set_up()"},{"line_number":1143,"context_line":"    except KeyError:"},{"line_number":1144,"context_line":"        return False"},{"line_number":1145,"context_line":"    return True"},{"line_number":1146,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"7aa08908_7d4dce71","line":1143,"range":{"start_line":1143,"start_character":11,"end_line":1143,"end_character":19},"updated":"2016-06-06 14:54:30.000000000","message":"OSError is thrown if namespace does not exists","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"27225e2d4594da5b42ea41b1c06b19ceff45c535","unresolved":false,"context_lines":[{"line_number":1140,"context_line":"        # Ensure the device is up, even if it is already up. If the device"},{"line_number":1141,"context_line":"        # doesn\u0027t exist, a KeyError will be raised."},{"line_number":1142,"context_line":"        dev.link.set_up()"},{"line_number":1143,"context_line":"    except KeyError:"},{"line_number":1144,"context_line":"        return False"},{"line_number":1145,"context_line":"    return True"},{"line_number":1146,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"7aa08908_368f6076","line":1143,"range":{"start_line":1143,"start_character":11,"end_line":1143,"end_character":19},"in_reply_to":"7aa08908_7d4dce71","updated":"2016-06-14 06:58:04.000000000","message":"Done","commit_id":"cf587b0a717b03a25aef60c5a6ab01f585434be2"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"267ff7ac0c5033798f78f9f6fa29513450c3518e","unresolved":false,"context_lines":[{"line_number":1018,"context_line":"                               \u0027net.ipv4.conf.all.promote_secondaries\u003d1\u0027])"},{"line_number":1019,"context_line":"        return wrapper"},{"line_number":1020,"context_line":""},{"line_number":1021,"context_line":"    def delete(self, name):"},{"line_number":1022,"context_line":"        priv_ip.netns_remove(name)"},{"line_number":1023,"context_line":""},{"line_number":1024,"context_line":"    def execute(self, cmds, addl_env\u003dNone, check_exit_code\u003dTrue,"},{"line_number":1025,"context_line":"                log_fail_as_error\u003dTrue, extra_ok_codes\u003dNone,"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_0dacbf8a","line":1022,"range":{"start_line":1021,"start_character":4,"end_line":1022,"end_character":34},"updated":"2016-06-14 12:57:33.000000000","message":"callers of this method are expecting RuntimeError, now it\u0027ll raise OSError in case namespace does not exist","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"aae411f8dfe257961187aa690691c653ce1af715","unresolved":false,"context_lines":[{"line_number":1018,"context_line":"                               \u0027net.ipv4.conf.all.promote_secondaries\u003d1\u0027])"},{"line_number":1019,"context_line":"        return wrapper"},{"line_number":1020,"context_line":""},{"line_number":1021,"context_line":"    def delete(self, name):"},{"line_number":1022,"context_line":"        priv_ip.netns_remove(name)"},{"line_number":1023,"context_line":""},{"line_number":1024,"context_line":"    def execute(self, cmds, addl_env\u003dNone, check_exit_code\u003dTrue,"},{"line_number":1025,"context_line":"                log_fail_as_error\u003dTrue, extra_ok_codes\u003dNone,"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_eb893f27","line":1022,"range":{"start_line":1021,"start_character":4,"end_line":1022,"end_character":34},"in_reply_to":"7aa08908_0dacbf8a","updated":"2016-06-14 21:22:48.000000000","message":"Yes, I hadn\u0027t anticipated quite so much code that acted on such a nondescript exception as \"RuntimeError\" :(\nWe\u0027ll never be able to find them all spread through the larger codebase, so I\u0027ll change my new code to continue to raise that same generic exception.","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"e6f03d55beb1670e153a109b6ef4c06993ff240e","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import re"},{"line_number":17,"context_line":"import socket"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import errno"},{"line_number":20,"context_line":"import eventlet"},{"line_number":21,"context_line":"import netaddr"},{"line_number":22,"context_line":"from neutron_lib import constants"}],"source_content_type":"text/x-python","patch_set":24,"id":"3aaa91ec_b19e1db6","line":19,"updated":"2016-06-23 01:17:08.000000000","message":"this is a standard module so it should be grouped on top with re and socket. \n\nhttps://docs.python.org/2/library/errno.html","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"71d11b4186893c0662cdec0528453274348f084b","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import re"},{"line_number":17,"context_line":"import socket"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import errno"},{"line_number":20,"context_line":"import eventlet"},{"line_number":21,"context_line":"import netaddr"},{"line_number":22,"context_line":"from neutron_lib import constants"}],"source_content_type":"text/x-python","patch_set":24,"id":"3aaa91ec_4808eb2c","line":19,"in_reply_to":"3aaa91ec_b19e1db6","updated":"2016-06-23 05:47:28.000000000","message":"Yep.  As it happens, errno isn\u0027t used at all in the current revision, so this import should have been removed: Done.","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"}],"neutron/agent/linux/pyroute2.py":[{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"12bc7037af969017aa299fb775c3cd4188dfcf6c","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    return (_MpConnection(s1), _MpConnection(s2))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"def _maybe_monkeypatch_pyroute2_for_eventlet():"},{"line_number":101,"context_line":"    eventlet \u003d sys.modules.get(\u0027eventlet\u0027, None)"},{"line_number":102,"context_line":"    if (eventlet is None or"},{"line_number":103,"context_line":"        eventlet.patcher.is_monkey_patched(\u0027multiprocessing\u0027)):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_dd6387af","line":100,"updated":"2015-03-04 21:21:53.000000000","message":"Strictly speaking, it is not a monkey patch: no running object is being patched, but changes the import process.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"a124695a5d7c0b1703d48baa8cd7001e6ff88df2","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    return (_MpConnection(s1), _MpConnection(s2))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"def _maybe_monkeypatch_pyroute2_for_eventlet():"},{"line_number":101,"context_line":"    eventlet \u003d sys.modules.get(\u0027eventlet\u0027, None)"},{"line_number":102,"context_line":"    if (eventlet is None or"},{"line_number":103,"context_line":"        eventlet.patcher.is_monkey_patched(\u0027multiprocessing\u0027)):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_0596a594","line":100,"in_reply_to":"9a80dd14_dd6387af","updated":"2015-03-04 23:17:23.000000000","message":"Ack, I\u0027ll rename it to use a less specific verb.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"12bc7037af969017aa299fb775c3cd4188dfcf6c","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"# These symbols are re-exported here, since they must be imported"},{"line_number":115,"context_line":"# _after_ the monkeypatch above."},{"line_number":116,"context_line":"from pyroute2 import *  # noqa pylint: disable\u003dwildcard-import"},{"line_number":117,"context_line":"from pyroute2 import netns  # noqa"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5dcb1772","line":115,"updated":"2015-03-04 21:21:53.000000000","message":"There is no need to write import strings _after_ the baseclass patching. When you use \"root\" imports like \"from pyroute2 import IPRoute\", you get a proxy that loads the actual class only being referred.\n\nSo, you can safely do this:\n\n    from pyroute2 import IPRoute\n    from pyroute2 import config\n\n    … [your own wrapper]\n\n    config.SocketBase \u003d …\n\n    ip \u003d IPRoute()  # here the module will be actually loaded\n\nPEP8 über alles :)\n\nPS: but I\u0027m not sure, will it be broken in the case of `from pyroute2 import netns`. Have to check.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"a3ea38b4c28489da109e8fe1c1564b0f1bc86051","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"# These symbols are re-exported here, since they must be imported"},{"line_number":115,"context_line":"# _after_ the monkeypatch above."},{"line_number":116,"context_line":"from pyroute2 import *  # noqa pylint: disable\u003dwildcard-import"},{"line_number":117,"context_line":"from pyroute2 import netns  # noqa"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_4277b302","line":115,"in_reply_to":"9a80dd14_5dcb1772","updated":"2015-03-04 22:50:56.000000000","message":"Netns import fixed: https://github.com/svinota/pyroute2/commit/ffe9799c24905ffedece1efc1217ba740d32afc5","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"a124695a5d7c0b1703d48baa8cd7001e6ff88df2","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"# These symbols are re-exported here, since they must be imported"},{"line_number":115,"context_line":"# _after_ the monkeypatch above."},{"line_number":116,"context_line":"from pyroute2 import *  # noqa pylint: disable\u003dwildcard-import"},{"line_number":117,"context_line":"from pyroute2 import netns  # noqa"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_2548092d","line":115,"in_reply_to":"9a80dd14_5dcb1772","updated":"2015-03-04 23:17:23.000000000","message":"Yeah, I added the `import *` below only for consistency - the comment was really regarding the netns import.  If you\u0027ve addressed that then great! I\u0027ll move the imports back to their Rightful Place.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"12bc7037af969017aa299fb775c3cd4188dfcf6c","unresolved":false,"context_lines":[{"line_number":114,"context_line":"# These symbols are re-exported here, since they must be imported"},{"line_number":115,"context_line":"# _after_ the monkeypatch above."},{"line_number":116,"context_line":"from pyroute2 import *  # noqa pylint: disable\u003dwildcard-import"},{"line_number":117,"context_line":"from pyroute2 import netns  # noqa"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_5dceb75b","line":117,"updated":"2015-03-04 21:21:53.000000000","message":"You gave me one more idea, how to do that — via metaclass. I will try this approach also, just in case.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f2133a2993dd9aa74ac72dff2ccdf06690ad6c8a","unresolved":false,"context_lines":[{"line_number":117,"context_line":"# These symbols are re-exported here, since they must be imported"},{"line_number":118,"context_line":"# _after_ _config is modified above."},{"line_number":119,"context_line":"# TODO(gus): Move once/if pyroute2.netns release no longer requires this."},{"line_number":120,"context_line":"from pyroute2 import netns  # noqa"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_33ac0f8c","line":120,"updated":"2015-03-10 07:47:11.000000000","message":"fixed, available in the master, and will be in the release 0.3.6","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"61c290fa67492c0a671e6b35d9e67c1367a50914","unresolved":false,"context_lines":[{"line_number":21,"context_line":"try:"},{"line_number":22,"context_line":"    import cPickle as pickle"},{"line_number":23,"context_line":"except ImportError:"},{"line_number":24,"context_line":"    import pickle"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"# This module is an eventlet-friendly version of pyroute2.  In order"},{"line_number":27,"context_line":"# to function correctly, it is critical that this file is imported"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_e0d2fdcf","line":24,"updated":"2016-04-21 10:13:05.000000000","message":"what is pickle? if this is third party then it needs to be added to the requirements","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"80d8db1a6947874002585033163d3878a268b319","unresolved":false,"context_lines":[{"line_number":21,"context_line":"try:"},{"line_number":22,"context_line":"    import cPickle as pickle"},{"line_number":23,"context_line":"except ImportError:"},{"line_number":24,"context_line":"    import pickle"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"# This module is an eventlet-friendly version of pyroute2.  In order"},{"line_number":27,"context_line":"# to function correctly, it is critical that this file is imported"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_43fc9bb7","line":24,"in_reply_to":"1a122d0e_e0d2fdcf","updated":"2016-04-21 10:25:07.000000000","message":"No, it\u0027s a standard python library that has an optional C accelerated version (and in py3 there is only the accelerated version, under the unaccelerated name).","commit_id":"94fbadcc2ca31cdd243c4e86ccf8df5d43c466c6"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"9c88fa770fa92d723bb7a4ab4135f1e89a06d674","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":3,"context_line":"#    you may not use this file except in compliance with the License."},{"line_number":4,"context_line":"#    You may obtain a copy of the License at"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_9678812d","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":1},"updated":"2016-04-22 08:11:26.000000000","message":"I\u0027m not sure it\u0027s of the high priority, but anyways: this code is included in the library, so maybe there is no need in one more wrapper.\n\nhttps://github.com/svinota/pyroute2/blob/master/tests/eventlet/test_eventlet.py\nhttps://github.com/svinota/pyroute2/blob/master/pyroute2/config/eventlet.py","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"137012f8f88a874292eba3ecb79c82d8f3e30349","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":3,"context_line":"#    you may not use this file except in compliance with the License."},{"line_number":4,"context_line":"#    You may obtain a copy of the License at"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_f5c6fd47","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":1},"in_reply_to":"1a122d0e_9678812d","updated":"2016-04-22 13:16:16.000000000","message":"Yep, I meant to get around to that - thanks for the prompt.  Since neutron has a single \"eventlet.monkey_patch()\" point, it actually made the logic a bit cleaner too.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"87a06bb8397fd584ce9972bd90bcfce6ac5ac808","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":3,"context_line":"#    you may not use this file except in compliance with the License."},{"line_number":4,"context_line":"#    You may obtain a copy of the License at"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_264b2db2","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":1},"in_reply_to":"1a122d0e_f5c6fd47","updated":"2016-04-22 14:06:19.000000000","message":"Cool","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        for name in _socketmethods:"},{"line_number":61,"context_line":"            f \u003d functools.partial(_forward, name)"},{"line_number":62,"context_line":"            f.__name__ \u003d name"},{"line_number":63,"context_line":"            setattr(_SocketWrapper, name, types.MethodType(f, self))"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def fileno(self):"},{"line_number":66,"context_line":"        return self._sock.fileno()"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_569ebb54","line":63,"updated":"2016-04-23 09:19:56.000000000","message":"If this is setting methods on the class instead of the instance, doesn\u0027t each initialization end up overriding the methods set from the previous inits? i.e. every instance of _SocketWrapper will receive the latest instance of _SocketWrapper rather than the the correct one?\n\nMore generally, this seems like a poor man\u0027s subclass. Why can\u0027t this just be a subclass of socket.socket? I assume it has something to do with the \u0027monkeypatch friendly\u0027 comment, but I\u0027m having trouble seeing it.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        c \u003d None"},{"line_number":96,"context_line":"        while c !\u003d \u0027\\n\u0027:"},{"line_number":97,"context_line":"            c \u003d self.sock.recv(1)"},{"line_number":98,"context_line":"            buf +\u003d c"},{"line_number":99,"context_line":"        return buf"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_b6ad8f8a","line":98,"updated":"2016-04-23 09:19:56.000000000","message":"My understanding is that appending to strings is expensive because a string is immutable. Under the hood this is creating a new string based on the old string plus the new string, and then the old one falls out of reference to eventually be garbage collected. lists are mutable though, so the pythonic version of this would look something like:\n\nbuf \u003d []\nc \u003d None\nwhile c !\u003d \u0027\\n\u0027:\n    c \u003d self.sock.recv(1)\n    buf.append(c)\nreturn b\u0027\u0027.join(buf)","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"}],"neutron/agent/privileged/_commands/ip_lib.py":[{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"12bc7037af969017aa299fb775c3cd4188dfcf6c","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    iface \u003d ipdb.by_name[name]"},{"line_number":73,"context_line":"    iface.begin()"},{"line_number":74,"context_line":"    iface.remove()"},{"line_number":75,"context_line":"    iface.commit()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"def SetLinkUp(name, up, ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_fd83ebc9","line":75,"updated":"2015-03-04 21:21:53.000000000","message":"alternative syntax:\n\n    with iface as i:\n        i.remove()\n\n(commit() will be called automatically from the __exit__())","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"a124695a5d7c0b1703d48baa8cd7001e6ff88df2","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    iface \u003d ipdb.by_name[name]"},{"line_number":73,"context_line":"    iface.begin()"},{"line_number":74,"context_line":"    iface.remove()"},{"line_number":75,"context_line":"    iface.commit()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"def SetLinkUp(name, up, ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_e5d6f1c4","line":75,"in_reply_to":"9a80dd14_fd83ebc9","updated":"2015-03-04 23:17:23.000000000","message":"My concern with the pyroute2 contextmanager idiom was that commit() would still be called even when the \"body\" code raised an exception...\n\nBut Oh!  I see that fear was unfounded and the pyroute2 code checks for this.  Yay - I will move a bunch of these single-interface cases over to `with`.","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f2133a2993dd9aa74ac72dff2ccdf06690ad6c8a","unresolved":false,"context_lines":[{"line_number":53,"context_line":"@privileged.entrypoint"},{"line_number":54,"context_line":"def GetLinkAttrs(link_name, ns\u003dNone):"},{"line_number":55,"context_line":"    ipdb \u003d _ipdb(ns\u003dns)"},{"line_number":56,"context_line":"    return ipdb.by_name[link_name]"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"@privileged.entrypoint"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_b3e63fe6","line":56,"updated":"2015-03-10 07:47:11.000000000","message":"keep in mind also dump/load functionality of the IPDB interfaces (can be used also with JSON)","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f2133a2993dd9aa74ac72dff2ccdf06690ad6c8a","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"@privileged.entrypoint"},{"line_number":60,"context_line":"def UpdateLinkAttrs(link_name, attrs, ns\u003dNone):"},{"line_number":61,"context_line":"    ipdb \u003d _ipdb(ns\u003dns)"},{"line_number":62,"context_line":"    with ipdb.by_name[link_name] as iface:"},{"line_number":63,"context_line":"        for k, v in attrs:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_73076782","line":60,"updated":"2015-03-10 07:47:11.000000000","message":"in particular, here the `load()` method would help","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"}],"neutron/agent/privileged/_commands/ipset.py":[{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"52536be31e7a77437d1d00fe29b6b124de6a3c6f","unresolved":false,"context_lines":[{"line_number":19,"context_line":"def _apply(cmd, input\u003dNone, namespace\u003dNone):"},{"line_number":20,"context_line":"    if input is not None:"},{"line_number":21,"context_line":"        input \u003d \u0027\\n\u0027.join(input)"},{"line_number":22,"context_line":"    cmd \u003d []"},{"line_number":23,"context_line":"    if namespace:"},{"line_number":24,"context_line":"        cmd.extend([\u0027ip\u0027, \u0027netns\u0027, \u0027exec\u0027, namespace])"},{"line_number":25,"context_line":"    return utils.execute(cmd, process_input\u003dinput)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_e99e8eb7","line":22,"updated":"2015-03-02 12:53:35.000000000","message":"cmd \u003d cmd[:]","commit_id":"2507bfa5e2902b247b7bf15f76024c1ba26b35c4"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"5e5b65404e89c761c0cc89b7e0895ad9e6b622ad","unresolved":false,"context_lines":[{"line_number":19,"context_line":"def _apply(cmd, input\u003dNone, namespace\u003dNone):"},{"line_number":20,"context_line":"    if input is not None:"},{"line_number":21,"context_line":"        input \u003d \u0027\\n\u0027.join(input)"},{"line_number":22,"context_line":"    cmd \u003d []"},{"line_number":23,"context_line":"    if namespace:"},{"line_number":24,"context_line":"        cmd.extend([\u0027ip\u0027, \u0027netns\u0027, \u0027exec\u0027, namespace])"},{"line_number":25,"context_line":"    return utils.execute(cmd, process_input\u003dinput)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_d0bea2ad","line":22,"in_reply_to":"ba7be1f8_e99e8eb7","updated":"2015-03-03 04:41:54.000000000","message":"Oh how terrible, thanks.  You\u0027ve also discovered that this example module is entirely untested :/","commit_id":"2507bfa5e2902b247b7bf15f76024c1ba26b35c4"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"52536be31e7a77437d1d00fe29b6b124de6a3c6f","unresolved":false,"context_lines":[{"line_number":21,"context_line":"        input \u003d \u0027\\n\u0027.join(input)"},{"line_number":22,"context_line":"    cmd \u003d []"},{"line_number":23,"context_line":"    if namespace:"},{"line_number":24,"context_line":"        cmd.extend([\u0027ip\u0027, \u0027netns\u0027, \u0027exec\u0027, namespace])"},{"line_number":25,"context_line":"    return utils.execute(cmd, process_input\u003dinput)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_e98bee1b","line":24,"updated":"2015-03-02 12:53:35.000000000","message":"cmd[:0] \u003d [\u0027ip\u0027, \u0027netns\u0027, \u0027exec\u0027, namespace]","commit_id":"2507bfa5e2902b247b7bf15f76024c1ba26b35c4"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"5e5b65404e89c761c0cc89b7e0895ad9e6b622ad","unresolved":false,"context_lines":[{"line_number":21,"context_line":"        input \u003d \u0027\\n\u0027.join(input)"},{"line_number":22,"context_line":"    cmd \u003d []"},{"line_number":23,"context_line":"    if namespace:"},{"line_number":24,"context_line":"        cmd.extend([\u0027ip\u0027, \u0027netns\u0027, \u0027exec\u0027, namespace])"},{"line_number":25,"context_line":"    return utils.execute(cmd, process_input\u003dinput)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ba7be1f8_b0468ebe","line":24,"in_reply_to":"ba7be1f8_e98bee1b","updated":"2015-03-03 04:41:54.000000000","message":"ditto - although I fixed both in a slightly different way.","commit_id":"2507bfa5e2902b247b7bf15f76024c1ba26b35c4"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"12bc7037af969017aa299fb775c3cd4188dfcf6c","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"def Create(set_name, family, namespace\u003dNone):"},{"line_number":27,"context_line":"    _apply([\u0027ipset\u0027, \u0027create\u0027, \u0027-exist\u0027, set_name,"},{"line_number":28,"context_line":"            \u0027hash:ip\u0027, \u0027family\u0027, family],"},{"line_number":29,"context_line":"           namespace\u003dnamespace)"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_1d60bf31","line":27,"updated":"2015-03-04 21:21:53.000000000","message":"a good idea to look onto ipset also. Thanks!","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"a124695a5d7c0b1703d48baa8cd7001e6ff88df2","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"def Create(set_name, family, namespace\u003dNone):"},{"line_number":27,"context_line":"    _apply([\u0027ipset\u0027, \u0027create\u0027, \u0027-exist\u0027, set_name,"},{"line_number":28,"context_line":"            \u0027hash:ip\u0027, \u0027family\u0027, family],"},{"line_number":29,"context_line":"           namespace\u003dnamespace)"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_859535e6","line":27,"in_reply_to":"9a80dd14_1d60bf31","updated":"2015-03-04 23:17:23.000000000","message":"(For my immediate purposes, this module is also meant as an example of how shelling out to commmands could be performed.  So pyroute2.ipset would be good, but then I would need to find another example ;)","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f5becf7b24a1fb795dadf197b1a04293bae9f603","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"def Create(set_name, family, namespace\u003dNone):"},{"line_number":27,"context_line":"    _apply([\u0027ipset\u0027, \u0027create\u0027, \u0027-exist\u0027, set_name,"},{"line_number":28,"context_line":"            \u0027hash:ip\u0027, \u0027family\u0027, family],"},{"line_number":29,"context_line":"           namespace\u003dnamespace)"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a80dd14_3eb55d31","line":27,"in_reply_to":"9a80dd14_859535e6","updated":"2015-03-05 11:14:50.000000000","message":"No worries — it will take time to implement ipset functionality.\n\nBut the work is started, yeah: https://github.com/svinota/pyroute2/milestones/0.3.6","commit_id":"f1ba55914cc587729dafca29d43a48367fd36cea"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"f2133a2993dd9aa74ac72dff2ccdf06690ad6c8a","unresolved":false,"context_lines":[{"line_number":28,"context_line":"def Create(set_name, family, namespace\u003dNone):"},{"line_number":29,"context_line":"    apply([\u0027ipset\u0027, \u0027create\u0027, \u0027-exist\u0027, set_name,"},{"line_number":30,"context_line":"           \u0027hash:ip\u0027, \u0027family\u0027, family],"},{"line_number":31,"context_line":"          namespace\u003dnamespace)"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"@privileged.entrypoint"}],"source_content_type":"text/x-python","patch_set":4,"id":"9a80dd14_13246b0b","line":31,"updated":"2015-03-10 07:47:11.000000000","message":"I do remember, yep.\n\nBut just in case — https://github.com/svinota/pyroute2/blob/master/pyroute2/ipset.py\n\nWill be released with 0.3.6","commit_id":"8a38211df3cc0b556d77be93bc647bbebe5080f7"}],"neutron/agent/privileged/daemon.py":[{"author":{"_account_id":8645,"name":"Trinath Somanchi","email":"trinath.somanchi@freescale.com","username":"trinaths"},"change_message_id":"acd5f1d1a9451d4833a31a27bf84df9a80d91769","unresolved":false,"context_lines":[{"line_number":253,"context_line":""},{"line_number":254,"context_line":"class Daemon(daemon.Daemon):"},{"line_number":255,"context_line":"    def __init__(self, serializer, caps\u003d(), **kwargs):"},{"line_number":256,"context_line":"        self.stream \u003d serializer"},{"line_number":257,"context_line":"        self.caps \u003d caps"},{"line_number":258,"context_line":"        super(Daemon, self).__init__(**kwargs)"},{"line_number":259,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"fa32b979_893c0494","line":256,"updated":"2015-06-25 06:30:33.000000000","message":"I see this error with respect to the number of arguments.\n\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.349 11594 DEBUG neutron.common.config [-] command line: /usr/local/bin/neutron-privsep-helper --config-file\u003d/etc/neutron/neutron.conf /tmp/tmpl4eM9B/privsep.sock setup_logging /opt/stack/new/neutron/neutron/common/config.py:211\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.349 11594 INFO neutron.agent.privileged.daemon [-] privsep daemon starting\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon [-] __init__() takes at least 2 arguments (3 given)\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon Traceback (most recent call last):\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon   File \"/opt/stack/new/neutron/neutron/agent/privileged/daemon.py\", line 363, in main\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon     group\u003dcfg.CONF.privsep.group).start()\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon   File \"/opt/stack/new/neutron/neutron/agent/privileged/daemon.py\", line 258, in __init__\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon     super(Daemon, self).__init__(**kwargs)\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon TypeError: __init__() takes at least 2 arguments (3 given)\n2015-06-25 00:15:33.401 | 2015-06-25 05:45:33.350 11594 ERROR neutron.agent.privileged.daemon \n2015-06-25 00:15:33.401 | __init__() takes at least 2 arguments (3 given)","commit_id":"a8eab9257c7b1afb33de704162a80192a965ff72"}],"neutron/cmd/netns_cleanup.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"82a4f24e4dbb45ac912a69950a5cf2c078c46362","unresolved":false,"context_lines":[{"line_number":199,"context_line":"    conf()"},{"line_number":200,"context_line":"    config.setup_logging()"},{"line_number":201,"context_line":"    priv_context.init("},{"line_number":202,"context_line":"        root_helper\u003dshlex.split(config.get_root_helper(conf)))"},{"line_number":203,"context_line":"    cleanup_network_namespaces(conf)"}],"source_content_type":"text/x-python","patch_set":28,"id":"3aaa91ec_1813985c","line":202,"range":{"start_line":202,"start_character":32,"end_line":202,"end_character":38},"updated":"2016-06-23 21:44:30.000000000","message":"should be agent_config","commit_id":"77d07005357dfcc3e8fa40bf942fbcba40553846"}],"neutron/plugins/ml2/drivers/macvtap/agent/macvtap_neutron_agent.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"7c50337c370bd5b002607b114fe18f28b58d11f8","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from oslo_config import cfg"},{"line_number":23,"context_line":"from oslo_log import log as logging"},{"line_number":24,"context_line":"import oslo_messaging"},{"line_number":25,"context_line":"from olso_privsep import priv_context"},{"line_number":26,"context_line":"from oslo_service import service"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"from neutron._i18n import _LE, _LI"}],"source_content_type":"text/x-python","patch_set":25,"id":"3aaa91ec_3727a1b7","line":25,"range":{"start_line":25,"start_character":5,"end_line":25,"end_character":9},"updated":"2016-06-23 13:11:29.000000000","message":"oslo","commit_id":"82db643f947b8edc3e40eed17a6d17588ca4f377"}],"neutron/privileged/ip_lib.py":[{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        else:"},{"line_number":50,"context_line":"            # NB: `flags\u003d0` will fail if the netns doesn\u0027t already"},{"line_number":51,"context_line":"            # exist (good)"},{"line_number":52,"context_line":"            ip \u003d pyroute2.NetNS(ns, flags\u003d0)"},{"line_number":53,"context_line":"        _ip_cache[ns] \u003d ip"},{"line_number":54,"context_line":"    return ip"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_96717347","line":52,"updated":"2016-04-23 09:19:56.000000000","message":"How expensive is this construction? My concern is that we will have slightly different behavior when a namespace is deleted out from underneath an agent depending on whether or not there is already an IPRoute object constructed in this cache. (if in cache, this command returns the cached version, if out of cache, it will fail on this construction)\n\nThis isn\u0027t an issue as long as the subsequent IP command they try to run would fail with the same error of the namespace not existing.\n\nOn thinking about this further, I suspect that the connection this will hold to the namespace will actually prevent the namespace from being deleted. For example, if this is holding a connection and I run \u0027ip netns delete namespace\u0027, will that just remove the link to the descriptor in the /var/run/netns directory and actually leave the namespace hiding in invisbility until the agent is restarted and \u0027.close()\u0027 is called on all of these?","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        else:"},{"line_number":50,"context_line":"            # NB: `flags\u003d0` will fail if the netns doesn\u0027t already"},{"line_number":51,"context_line":"            # exist (good)"},{"line_number":52,"context_line":"            ip \u003d pyroute2.NetNS(ns, flags\u003d0)"},{"line_number":53,"context_line":"        _ip_cache[ns] \u003d ip"},{"line_number":54,"context_line":"    return ip"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_dc560329","line":52,"in_reply_to":"1a122d0e_96717347","updated":"2016-06-01 03:56:38.000000000","message":"Yes, the latter (aiui).  It will keep the netns alive until the cached FD is closed, but it won\u0027t appear in /var/run/netns.\n\nIs \"continue to work across manual deletions / recreations of internally used network namespaces without requiring a process restart or neutron destroy/recreate\" a thing we actually need to support?\n\nAs to cost: without this cache we\u0027re effectively reconnecting to netlink again for every message we send.  For namespaces that also involves a fork and some other stuff (inside pyroute2).  I\u0027m sure if we benchmarked it it wouldn\u0027t turn up as _that_ significant a speedup, so it depends how much we care about supporting the \"manually delete a live namespace\" use-case.\n\n--\n\nOne day in the distant future we could (theoretically) drop /var/run/netns global binds and use network namespaces as they were intended:  We could create our own \"anonymous\" netns\u0027s that would only live exactly as long as we wanted them to.  They would be cleaned up automatically by the kernel when no longer in use, we wouldn\u0027t need uid\u003d0, etc.  In that glorious and impossibly distant future, we would _need_ to cache the netns fds, since that reference would be the only thing keeping them alive.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":57,"context_line":"@atexit.register"},{"line_number":58,"context_line":"def _close_cache():"},{"line_number":59,"context_line":"    for name, ip in _ip_cache.items():"},{"line_number":60,"context_line":"        del _ip_cache[name]"},{"line_number":61,"context_line":"        ip.close()"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_f68ee725","line":60,"updated":"2016-04-23 09:19:56.000000000","message":"In python3, .items() returns a view, which is a reflection of the current dictionary state. So it\u0027s not safe to diddle the dictionary while you iterate over it like this.\n\n\u003e\u003e\u003e x \u003d {\u0027a\u0027: 1, \u0027b\u0027: {}, \u0027c\u0027: None}\n\u003e\u003e\u003e for k, v in x.items():\n...     del x[k]\n...     print(v)\n...\n1\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nRuntimeError: dictionary changed size during iteration\n\n\nMore saferly:\n\nfor ip in _ip_cache.values():\n    ip.close()\n_ip_cache.clear()\n\n\nAlso, is it possible for \u0027close()\u0027 to throw? If so, might want to wrap:\n\nfor ip in _ip_cache.values():\n    try:\n        ip.close()\n    except Exception:\n        LOG.exception(\"Failure closing namespace\")","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"c1aafa93ef1571764d13f9ab33b97c4e34d536ab","unresolved":false,"context_lines":[{"line_number":57,"context_line":"@atexit.register"},{"line_number":58,"context_line":"def _close_cache():"},{"line_number":59,"context_line":"    for name, ip in _ip_cache.items():"},{"line_number":60,"context_line":"        del _ip_cache[name]"},{"line_number":61,"context_line":"        ip.close()"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9abb7d3a_c72f5086","line":60,"in_reply_to":"1a122d0e_f68ee725","updated":"2016-06-01 03:56:38.000000000","message":"Good point, fixed.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"36f767112b9d957d7b69871e268b51233a1e3a42","unresolved":false,"context_lines":[{"line_number":77,"context_line":"    links \u003d get_links(*args, **kwargs)"},{"line_number":78,"context_line":"    ret \u003d []"},{"line_number":79,"context_line":"    for link in links:"},{"line_number":80,"context_line":"        for attr in link.get(\u0027attrs\u0027, []):"},{"line_number":81,"context_line":"            if attr[0] \u003d\u003d \u0027IFLA_IFNAME\u0027:"},{"line_number":82,"context_line":"                ret.append(attr[1])"},{"line_number":83,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_d6912b48","line":80,"updated":"2016-04-23 09:19:56.000000000","message":"any way to make \u0027attrs\u0027 a dictionary in the return value of get_links? Or is it a backwards compat thing?","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"653370a9f91de476dc5b28c4da1a73d6515fff63","unresolved":false,"context_lines":[{"line_number":77,"context_line":"    links \u003d get_links(*args, **kwargs)"},{"line_number":78,"context_line":"    ret \u003d []"},{"line_number":79,"context_line":"    for link in links:"},{"line_number":80,"context_line":"        for attr in link.get(\u0027attrs\u0027, []):"},{"line_number":81,"context_line":"            if attr[0] \u003d\u003d \u0027IFLA_IFNAME\u0027:"},{"line_number":82,"context_line":"                ret.append(attr[1])"},{"line_number":83,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_8a72e40f","line":80,"in_reply_to":"1a122d0e_6cafa8e3","updated":"2016-04-23 17:30:31.000000000","message":"Mea culpa, not in VLAN filtering, but on macvlan interfaces:\n\nhttp://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/tree/drivers/net/macvlan.c?h\u003dv4.6-rc2#n1440\n\nHere in IFLA_MACVLAN_MACADDR_DATA may go multiple NLAs of the same IFLA_MACVLAN_MACADDR type.","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"b90cbf892acc7e63bfbac6de89a95f197b4f9980","unresolved":false,"context_lines":[{"line_number":77,"context_line":"    links \u003d get_links(*args, **kwargs)"},{"line_number":78,"context_line":"    ret \u003d []"},{"line_number":79,"context_line":"    for link in links:"},{"line_number":80,"context_line":"        for attr in link.get(\u0027attrs\u0027, []):"},{"line_number":81,"context_line":"            if attr[0] \u003d\u003d \u0027IFLA_IFNAME\u0027:"},{"line_number":82,"context_line":"                ret.append(attr[1])"},{"line_number":83,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_6cafa8e3","line":80,"in_reply_to":"1a122d0e_d6912b48","updated":"2016-04-23 12:20:39.000000000","message":"That\u0027s the netlink feature:\n\nissue 1. NLAs are **not** unique within one message, and there can me several NLAs with the same name. This happens in some rare cases, but still happens (IIRC, it is the case in the bridge VLAN filtering, where multiple vlan_info may occur in one message, but I have to check to be sure)\nissue 2. **Sometimes** the NLA order matters.\n\nThere is no common netlink code in the kernel that would enforce NLA uniqueness, so one RTNL parts may provide it, while other may not. Thus the pyroute2 parser, being generic, returns NLAs as a chain (list), not as a dict. The `IPRoute` class doesn\u0027t touch messages and returns them as is.\n\nIf you wish, I can provide a wrapper with the same API as `IPRoute`, but that will return messages with NLAs as an ordered dict (to save the order, see issue 2), not as a list. That\u0027s easy from the library\u0027s perspective. But it is a serious architectural choice for the library users: planning a project on that assumption later may make it impossible to work with the cases when there are several NLAs with the same name (issue 1).","commit_id":"45a09339f7136dc7fb8d1ca57be3c35b55e75558"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"@atexit.register"},{"line_number":58,"context_line":"def _close_cache():"},{"line_number":59,"context_line":"    for name, ip in _ip_cache.items():"},{"line_number":60,"context_line":"        del _ip_cache[name]"},{"line_number":61,"context_line":"        ip.close()"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"# NB: The return from this can be large.  If possible, restrict to"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_e7be45fe","line":61,"range":{"start_line":59,"start_character":4,"end_line":61,"end_character":18},"updated":"2016-04-22 23:14:57.000000000","message":"would this be better as the following? This is valid, but using \u0027del\u0027 here makes it look like you\u0027re using the \u0027ip\u0027 reference after it\u0027s been deleted:\n\nfor name in _ip_cache.keys():\n    _ip_cache.pop(name).close()","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"f6f9345b4b36c732b7c05ef6310b9accef475319","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"@atexit.register"},{"line_number":58,"context_line":"def _close_cache():"},{"line_number":59,"context_line":"    for name, ip in _ip_cache.items():"},{"line_number":60,"context_line":"        del _ip_cache[name]"},{"line_number":61,"context_line":"        ip.close()"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"# NB: The return from this can be large.  If possible, restrict to"}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_509b3fc9","line":61,"range":{"start_line":59,"start_character":4,"end_line":61,"end_character":18},"in_reply_to":"1a122d0e_e7be45fe","updated":"2016-04-25 16:36:24.000000000","message":"Disregard this suggestion, Kevin\u0027s comment on PS18 made me realize that this is also incompatible with python3. His suggestion is better:\n\nfor ip in _ip_cache.values():\n    ip.close()\n_ip_cache.clear()","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"5596fb9e6096163fac859ea297f4df3a976c8600","unresolved":false,"context_lines":[{"line_number":76,"context_line":"def get_link_names(*args, **kwargs):"},{"line_number":77,"context_line":"    links \u003d get_links(*args, **kwargs)"},{"line_number":78,"context_line":"    ret \u003d []"},{"line_number":79,"context_line":"    for link in links:"},{"line_number":80,"context_line":"        for attr in link.get(\u0027attrs\u0027, []):"},{"line_number":81,"context_line":"            if attr[0] \u003d\u003d \u0027IFLA_IFNAME\u0027:"},{"line_number":82,"context_line":"                ret.append(attr[1])"},{"line_number":83,"context_line":"                break"},{"line_number":84,"context_line":"    return ret"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_e5a0eba7","line":83,"range":{"start_line":79,"start_character":4,"end_line":83,"end_character":21},"updated":"2016-04-23 20:00:31.000000000","message":"…\n\n  return [x.get_attr(\"IFLA_IFNAME\") for x in get_links()]","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":76,"context_line":"def get_link_names(*args, **kwargs):"},{"line_number":77,"context_line":"    links \u003d get_links(*args, **kwargs)"},{"line_number":78,"context_line":"    ret \u003d []"},{"line_number":79,"context_line":"    for link in links:"},{"line_number":80,"context_line":"        for attr in link.get(\u0027attrs\u0027, []):"},{"line_number":81,"context_line":"            if attr[0] \u003d\u003d \u0027IFLA_IFNAME\u0027:"},{"line_number":82,"context_line":"                ret.append(attr[1])"},{"line_number":83,"context_line":"                break"},{"line_number":84,"context_line":"    return ret"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_07c15854","line":83,"range":{"start_line":79,"start_character":4,"end_line":83,"end_character":21},"in_reply_to":"1a122d0e_e5a0eba7","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":16800,"name":"Rawlin Peters","email":"rawlin.peters@hpe.com","username":"rawlin"},"change_message_id":"b2b67c84afb3e85494eaa48f6ca85e8353777c12","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"@privileged.default.entrypoint"},{"line_number":140,"context_line":"def netns_remove(name):"},{"line_number":141,"context_line":"    ip \u003d _ip_cache.get(name, None)"},{"line_number":142,"context_line":"    if ip is not None:"},{"line_number":143,"context_line":"        ip.close()"},{"line_number":144,"context_line":"        del _ip_cache[name]"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    netns.remove(name)"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"1a122d0e_e7dbe519","line":144,"range":{"start_line":141,"start_character":4,"end_line":144,"end_character":27},"updated":"2016-04-22 23:14:57.000000000","message":"Similar to above, you can use pop() here:\n\nip \u003d _ip_cache.pop(name, None):\nif ip:\n    ip.close()","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"ead9070c9568fe10debdb77e421235d03b704b88","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"@privileged.default.entrypoint"},{"line_number":140,"context_line":"def netns_remove(name):"},{"line_number":141,"context_line":"    ip \u003d _ip_cache.get(name, None)"},{"line_number":142,"context_line":"    if ip is not None:"},{"line_number":143,"context_line":"        ip.close()"},{"line_number":144,"context_line":"        del _ip_cache[name]"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    netns.remove(name)"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9abb7d3a_c7c3d055","line":144,"range":{"start_line":141,"start_character":4,"end_line":144,"end_character":27},"in_reply_to":"1a122d0e_e7dbe519","updated":"2016-06-01 03:59:05.000000000","message":"Done","commit_id":"e669d44e877069ad0aa04ccc6377f781b5ae2341"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"267ff7ac0c5033798f78f9f6fa29513450c3518e","unresolved":false,"context_lines":[{"line_number":107,"context_line":"@privileged.default.entrypoint"},{"line_number":108,"context_line":"def link(command, ns\u003dNone, **kwargs):"},{"line_number":109,"context_line":"    ip \u003d _ip(ns\u003dns)"},{"line_number":110,"context_line":"    return ip.link(command, **kwargs).dump()"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"@privileged.default.entrypoint"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_4ddfe70c","line":110,"range":{"start_line":110,"start_character":11,"end_line":110,"end_character":44},"updated":"2016-06-14 12:57:33.000000000","message":"AttributeError: \u0027list\u0027 object has no attribute \u0027dump\u0027","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"},{"author":{"_account_id":15361,"name":"Peter V. Saveliev","email":"peter@svinota.eu","username":"svinota"},"change_message_id":"c5cc87ab1a36b57d98b919b462504cc329356e98","unresolved":false,"context_lines":[{"line_number":107,"context_line":"@privileged.default.entrypoint"},{"line_number":108,"context_line":"def link(command, ns\u003dNone, **kwargs):"},{"line_number":109,"context_line":"    ip \u003d _ip(ns\u003dns)"},{"line_number":110,"context_line":"    return ip.link(command, **kwargs).dump()"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"@privileged.default.entrypoint"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_d1787491","line":110,"range":{"start_line":110,"start_character":11,"end_line":110,"end_character":44},"updated":"2016-06-14 22:11:25.000000000","message":"That would work::\n\n    [x.dump() for x in ip.link(…)]\n\nThe IPRoute() methods return lists of messages. And lists here are plain Python lists.\n\nKeep in mind, that if you don\u0027t do `load()` on the other side, you will get plain dicts, no `get_attr()` or `get_nested()` will work, you will have to use own methods.\n\nTo call `load()` you will have also to instantiate the proper nlmsg class for the corresponding dump.\n\nI\u0027ll try to look more deeply into the oslo.privsep to see how it could work a bit simpler.","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"267ff7ac0c5033798f78f9f6fa29513450c3518e","unresolved":false,"context_lines":[{"line_number":119,"context_line":"@privileged.default.entrypoint"},{"line_number":120,"context_line":"def addr(command, ns\u003dNone, **kwargs):"},{"line_number":121,"context_line":"    ip \u003d _ip(ns\u003dns)"},{"line_number":122,"context_line":"    return ip.addr(command, **kwargs).dump()"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"@privileged.default.entrypoint"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_0d1f9fb7","line":122,"range":{"start_line":122,"start_character":11,"end_line":122,"end_character":44},"updated":"2016-06-14 12:57:33.000000000","message":"AttributeError: \u0027list\u0027 object has no attribute \u0027dump\u0027","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"267ff7ac0c5033798f78f9f6fa29513450c3518e","unresolved":false,"context_lines":[{"line_number":154,"context_line":"@privileged.default.entrypoint"},{"line_number":155,"context_line":"def route(command, ns\u003dNone, **kwargs):"},{"line_number":156,"context_line":"    ip \u003d _ip(ns\u003dns)"},{"line_number":157,"context_line":"    return ip.route(command, **kwargs).dump()"}],"source_content_type":"text/x-python","patch_set":23,"id":"7aa08908_8de54fdd","line":157,"range":{"start_line":157,"start_character":11,"end_line":157,"end_character":45},"updated":"2016-06-14 12:57:33.000000000","message":"AttributeError: \u0027list\u0027 object has no attribute \u0027dump\u0027","commit_id":"a670b61afd7a6883fb9e44105b264d2dab7cdd88"}],"neutron/tests/unit/agent/linux/test_ip_lib.py":[{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"e6f03d55beb1670e153a109b6ef4c06993ff240e","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import mock"},{"line_number":17,"context_line":"import netaddr"},{"line_number":18,"context_line":"import socket"},{"line_number":19,"context_line":"import testtools"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from neutron.agent.common import utils  # noqa"}],"source_content_type":"text/x-python","patch_set":24,"id":"3aaa91ec_d1d00956","line":18,"updated":"2016-06-23 01:17:08.000000000","message":"socket is a std module so it should be in a new grouping at the top.","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"},{"author":{"_account_id":11279,"name":"Angus Lees","email":"gus@inodes.org","username":"gus"},"change_message_id":"71d11b4186893c0662cdec0528453274348f084b","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import mock"},{"line_number":17,"context_line":"import netaddr"},{"line_number":18,"context_line":"import socket"},{"line_number":19,"context_line":"import testtools"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from neutron.agent.common import utils  # noqa"}],"source_content_type":"text/x-python","patch_set":24,"id":"3aaa91ec_cb0a1521","line":18,"in_reply_to":"3aaa91ec_d1d00956","updated":"2016-06-23 05:47:28.000000000","message":"Hah, I just assumed the top block was std modules without even reading what they were.  Fixed.","commit_id":"8976df0e4aa5aa877280379444681f82a479ced9"}]}
