)]}'
{"neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"c5d45fd5fa1070b0d149c9bc76ad4654917aefec","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    # history"},{"line_number":128,"context_line":"    #   1.0 Initial version"},{"line_number":129,"context_line":"    #   1.1 Support Security Group RPC"},{"line_number":130,"context_line":"    #   1.2 Support DVR (Distributed Virtual Router) RPC"},{"line_number":131,"context_line":"    #   1.3 Added param devices_to_update to security_groups_provider_updated"},{"line_number":132,"context_line":"    target \u003d oslo_messaging.Target(version\u003d\u00271.3\u0027)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_8b7aab22","line":130,"updated":"2015-08-21 13:02:45.000000000","message":"Should we bump version here as it adds method to this endpoint?","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"0f27b6e433093814ed1e88dcd4b4a4a3eb834e37","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    # history"},{"line_number":128,"context_line":"    #   1.0 Initial version"},{"line_number":129,"context_line":"    #   1.1 Support Security Group RPC"},{"line_number":130,"context_line":"    #   1.2 Support DVR (Distributed Virtual Router) RPC"},{"line_number":131,"context_line":"    #   1.3 Added param devices_to_update to security_groups_provider_updated"},{"line_number":132,"context_line":"    target \u003d oslo_messaging.Target(version\u003d\u00271.3\u0027)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_46fd65af","line":130,"in_reply_to":"fa1b9901_518a0465","updated":"2015-08-21 13:48:49.000000000","message":"Exactly, I thought API and callback should be in sync :) Or we just version API?","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    # history"},{"line_number":128,"context_line":"    #   1.0 Initial version"},{"line_number":129,"context_line":"    #   1.1 Support Security Group RPC"},{"line_number":130,"context_line":"    #   1.2 Support DVR (Distributed Virtual Router) RPC"},{"line_number":131,"context_line":"    #   1.3 Added param devices_to_update to security_groups_provider_updated"},{"line_number":132,"context_line":"    target \u003d oslo_messaging.Target(version\u003d\u00271.3\u0027)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_a358f38a","line":130,"in_reply_to":"fa1b9901_518a0465","updated":"2015-08-21 13:48:22.000000000","message":"I\u0027m a little confused by that.\n\nShouldn\u0027t we change it here too?,\n\nalso, on the other side, we don\u0027t bump the target version, (I saw that didn\u0027t happen for 1.2 or 1.1, I guess to leave the other notifications in compatible state?.\n\nI\u0027m trying to understand the logic of that yet.","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"50718d6e1d0c6b0075c8f69a20b53d82b1749b05","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    # history"},{"line_number":128,"context_line":"    #   1.0 Initial version"},{"line_number":129,"context_line":"    #   1.1 Support Security Group RPC"},{"line_number":130,"context_line":"    #   1.2 Support DVR (Distributed Virtual Router) RPC"},{"line_number":131,"context_line":"    #   1.3 Added param devices_to_update to security_groups_provider_updated"},{"line_number":132,"context_line":"    target \u003d oslo_messaging.Target(version\u003d\u00271.3\u0027)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_518a0465","line":130,"in_reply_to":"fa1b9901_8b7aab22","updated":"2015-08-21 13:35:28.000000000","message":"check neutron.plugins.ml2.rpc","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"50718d6e1d0c6b0075c8f69a20b53d82b1749b05","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    def network_update(self, context, **kwargs):"},{"line_number":404,"context_line":"        network_id \u003d kwargs[\u0027network\u0027][\u0027id\u0027]"},{"line_number":405,"context_line":"        for port_id in self.network_ports[network_id]:"},{"line_number":406,"context_line":"            self.updated_ports.add(port_id)"},{"line_number":407,"context_line":"        LOG.debug(\"network_update message processed for network \""},{"line_number":408,"context_line":"                  \"%(network_id)s, with ports: %(ports)s\","},{"line_number":409,"context_line":"                  {\u0027network_id\u0027: network_id,"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_a3a9d391","line":406,"updated":"2015-08-21 13:35:28.000000000","message":"You could end up in a very subtle corner case where the same port is now both in the \"updated\" and in the \"deleted\" sets.\n\nThis could happen for instance, if within an iteration of the agent, you first associated a qos policy to a network and then delete a port.\n\nThis corner case should be easy to handle, or maybe not handle it at all and just leave a note so that should this eventually really happen the neutron developers of the future will understand what is going on.","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"fb67e51dbf7976f20fe6dbce9a201c3fa28a9e1b","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    def network_update(self, context, **kwargs):"},{"line_number":404,"context_line":"        network_id \u003d kwargs[\u0027network\u0027][\u0027id\u0027]"},{"line_number":405,"context_line":"        for port_id in self.network_ports[network_id]:"},{"line_number":406,"context_line":"            self.updated_ports.add(port_id)"},{"line_number":407,"context_line":"        LOG.debug(\"network_update message processed for network \""},{"line_number":408,"context_line":"                  \"%(network_id)s, with ports: %(ports)s\","},{"line_number":409,"context_line":"                  {\u0027network_id\u0027: network_id,"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_ba09b4df","line":406,"in_reply_to":"fa1b9901_438d57d1","updated":"2015-08-24 13:32:02.000000000","message":"Hmm wouldn\u0027t we have the same issue with port_update, port_delete inversion? \n\nMay be we should add the same update avoidance (I\u0027m adding in PS2) when port is marked to be deleted in port_update?","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    def network_update(self, context, **kwargs):"},{"line_number":404,"context_line":"        network_id \u003d kwargs[\u0027network\u0027][\u0027id\u0027]"},{"line_number":405,"context_line":"        for port_id in self.network_ports[network_id]:"},{"line_number":406,"context_line":"            self.updated_ports.add(port_id)"},{"line_number":407,"context_line":"        LOG.debug(\"network_update message processed for network \""},{"line_number":408,"context_line":"                  \"%(network_id)s, with ports: %(ports)s\","},{"line_number":409,"context_line":"                  {\u0027network_id\u0027: network_id,"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_438d57d1","line":406,"in_reply_to":"fa1b9901_a3a9d391","updated":"2015-08-21 13:48:22.000000000","message":"+++!, thanks\n\nProbably I can subtract deleted_ports from updated_ports before processing?\n\nAnd add a note there to explain why is that needed.","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"c5d45fd5fa1070b0d149c9bc76ad4654917aefec","unresolved":false,"context_lines":[{"line_number":412,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":413,"context_line":"        for port_set in self.network_ports.values():"},{"line_number":414,"context_line":"            if port_id in port_set:"},{"line_number":415,"context_line":"                port_set.remove(port_id)"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def process_deleted_ports(self, port_info):"},{"line_number":418,"context_line":"        # don\u0027t try to process removed ports as deleted ports since"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_56451a40","line":415,"updated":"2015-08-21 13:02:45.000000000","message":"Port can be in only one network, right? So\n\n break","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":412,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":413,"context_line":"        for port_set in self.network_ports.values():"},{"line_number":414,"context_line":"            if port_id in port_set:"},{"line_number":415,"context_line":"                port_set.remove(port_id)"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def process_deleted_ports(self, port_info):"},{"line_number":418,"context_line":"        # don\u0027t try to process removed ports as deleted ports since"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_66442949","line":415,"in_reply_to":"fa1b9901_11880c70","updated":"2015-08-21 13:48:22.000000000","message":"lol,\ntrue.\n\nI wonder if there\u0027s any corner case which could lead us to such thing?\n\nProbably I should also clean before switching a port network_id (right at L1319)","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"50718d6e1d0c6b0075c8f69a20b53d82b1749b05","unresolved":false,"context_lines":[{"line_number":412,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":413,"context_line":"        for port_set in self.network_ports.values():"},{"line_number":414,"context_line":"            if port_id in port_set:"},{"line_number":415,"context_line":"                port_set.remove(port_id)"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def process_deleted_ports(self, port_info):"},{"line_number":418,"context_line":"        # don\u0027t try to process removed ports as deleted ports since"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_11880c70","line":415,"in_reply_to":"fa1b9901_56451a40","updated":"2015-08-21 13:35:28.000000000","message":"nah let\u0027s spin right round!\nhttps://www.youtube.com/watch?v\u003dPGNiXGX2nLU","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"65a646fc5e6c7a384b1af95da0550a4cabe18901","unresolved":false,"context_lines":[{"line_number":400,"context_line":"        port_id \u003d kwargs.get(\u0027port_id\u0027)"},{"line_number":401,"context_line":"        self.deleted_ports.add(port_id)"},{"line_number":402,"context_line":"        if port_id in self.updated_ports:"},{"line_number":403,"context_line":"            self.updated_ports.remove(port_id)"},{"line_number":404,"context_line":"        LOG.debug(\"port_delete message processed for port %s\", port_id)"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    def network_update(self, context, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa1b9901_8eb3d94c","line":403,"updated":"2015-08-26 11:48:24.000000000","message":"python\u0027s set type has a handy method called \u0027discard\u0027","commit_id":"1ba35c3a62f53cd9a86bd882ed0854906b08c5fe"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"7d497159cc774b753ee269205b19b37164e570b2","unresolved":false,"context_lines":[{"line_number":400,"context_line":"        port_id \u003d kwargs.get(\u0027port_id\u0027)"},{"line_number":401,"context_line":"        self.deleted_ports.add(port_id)"},{"line_number":402,"context_line":"        if port_id in self.updated_ports:"},{"line_number":403,"context_line":"            self.updated_ports.remove(port_id)"},{"line_number":404,"context_line":"        LOG.debug(\"port_delete message processed for port %s\", port_id)"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    def network_update(self, context, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa1b9901_ce2311bc","line":403,"in_reply_to":"fa1b9901_8eb3d94c","updated":"2015-08-26 12:07:51.000000000","message":"Thanks!! :)","commit_id":"1ba35c3a62f53cd9a86bd882ed0854906b08c5fe"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"65a646fc5e6c7a384b1af95da0550a4cabe18901","unresolved":false,"context_lines":[{"line_number":418,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":419,"context_line":"        for port_set in self.network_ports.values():"},{"line_number":420,"context_line":"            if port_id in port_set:"},{"line_number":421,"context_line":"                port_set.remove(port_id)"},{"line_number":422,"context_line":"                break"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"    def process_deleted_ports(self, port_info):"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa1b9901_0e434914","line":421,"updated":"2015-08-26 11:48:24.000000000","message":"discard should not be used here instead otherwise you won\u0027t be able to break","commit_id":"1ba35c3a62f53cd9a86bd882ed0854906b08c5fe"},{"author":{"_account_id":12171,"name":"Moshe Levi","email":"moshele@nvidia.com","username":"moshele"},"change_message_id":"5a4f868ddf13601baecfb3f18b7a30830a0ac306","unresolved":false,"context_lines":[{"line_number":404,"context_line":""},{"line_number":405,"context_line":"    def network_update(self, context, **kwargs):"},{"line_number":406,"context_line":"        network_id \u003d kwargs[\u0027network\u0027][\u0027id\u0027]"},{"line_number":407,"context_line":"        for port_id in self.network_ports[network_id]:"},{"line_number":408,"context_line":"            # notifications could arrive out of order, if the port is deleted"},{"line_number":409,"context_line":"            # we don\u0027t want to update it anymore"},{"line_number":410,"context_line":"            if port_id not in self.deleted_ports:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_697e7fb0","line":407,"updated":"2015-08-26 12:36:13.000000000","message":"don\u0027t you need to delete the network_id on delete network or we don\u0027t care?","commit_id":"be2e1bbfe3bbf6d083c3da9ec2d1043fc047ed83"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"3e9d1e50278ea06515da4970f6866061a4b364dc","unresolved":false,"context_lines":[{"line_number":404,"context_line":""},{"line_number":405,"context_line":"    def network_update(self, context, **kwargs):"},{"line_number":406,"context_line":"        network_id \u003d kwargs[\u0027network\u0027][\u0027id\u0027]"},{"line_number":407,"context_line":"        for port_id in self.network_ports[network_id]:"},{"line_number":408,"context_line":"            # notifications could arrive out of order, if the port is deleted"},{"line_number":409,"context_line":"            # we don\u0027t want to update it anymore"},{"line_number":410,"context_line":"            if port_id not in self.deleted_ports:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_d105f10f","line":407,"in_reply_to":"fa1b9901_697e7fb0","updated":"2015-08-26 13:04:28.000000000","message":"It will be empty when we have no ports on such network.","commit_id":"be2e1bbfe3bbf6d083c3da9ec2d1043fc047ed83"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a432641aa342f66a49f19818f67e18f867435753","unresolved":false,"context_lines":[{"line_number":412,"context_line":"        LOG.debug(\"network_update message processed for network \""},{"line_number":413,"context_line":"                  \"%(network_id)s, with ports: %(ports)s\","},{"line_number":414,"context_line":"                  {\u0027network_id\u0027: network_id,"},{"line_number":415,"context_line":"                   \u0027ports\u0027: self.network_ports[network_id]})"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":418,"context_line":"        for port_set in self.network_ports.values():"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_e378c291","line":415,"updated":"2015-08-28 07:01:35.000000000","message":"It may be useful if we have information on delete_ports since they are not processed anymore. It is just a thought.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"5e904f6d9102288d931d6c4f68f7261b7a3cbbfc","unresolved":false,"context_lines":[{"line_number":412,"context_line":"        LOG.debug(\"network_update message processed for network \""},{"line_number":413,"context_line":"                  \"%(network_id)s, with ports: %(ports)s\","},{"line_number":414,"context_line":"                  {\u0027network_id\u0027: network_id,"},{"line_number":415,"context_line":"                   \u0027ports\u0027: self.network_ports[network_id]})"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def _clean_network_ports(self, port_id):"},{"line_number":418,"context_line":"        for port_set in self.network_ports.values():"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_e630d0a0","line":415,"in_reply_to":"da20952f_e378c291","updated":"2015-08-28 07:13:07.000000000","message":"good suggestion, I will add if I need to respin or otherwise in a follow up.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"}],"neutron/plugins/ml2/plugin.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"846bb70eae79d4f1e5667fc6b763e8e28766bda4","unresolved":false,"context_lines":[{"line_number":671,"context_line":"            if (qos_consts.QOS_POLICY_ID in network and"},{"line_number":672,"context_line":"                    original_network[qos_consts.QOS_POLICY_ID] !\u003d"},{"line_number":673,"context_line":"                    updated_network[qos_consts.QOS_POLICY_ID]):"},{"line_number":674,"context_line":"                need_network_update_notify \u003d True"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"            mech_context \u003d driver_context.NetworkContext("},{"line_number":677,"context_line":"                self, context, updated_network,"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_d6592afe","line":674,"updated":"2015-08-21 13:06:15.000000000","message":"Suggestion, just:\n\n need_network_update_notify \u003d (\n     qos_consts.QOS_POLICY_ID in network and\n     original_network[qos_consts.QOS_POLICY_ID] !\u003d \n     updated_network[qos_consts.QOS_POLICY_ID])\n\nand remove L656","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":671,"context_line":"            if (qos_consts.QOS_POLICY_ID in network and"},{"line_number":672,"context_line":"                    original_network[qos_consts.QOS_POLICY_ID] !\u003d"},{"line_number":673,"context_line":"                    updated_network[qos_consts.QOS_POLICY_ID]):"},{"line_number":674,"context_line":"                need_network_update_notify \u003d True"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"            mech_context \u003d driver_context.NetworkContext("},{"line_number":677,"context_line":"                self, context, updated_network,"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_067a0d88","line":674,"in_reply_to":"fa1b9901_d6592afe","updated":"2015-08-21 13:48:22.000000000","message":"right!","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"50718d6e1d0c6b0075c8f69a20b53d82b1749b05","unresolved":false,"context_lines":[{"line_number":676,"context_line":"            mech_context \u003d driver_context.NetworkContext("},{"line_number":677,"context_line":"                self, context, updated_network,"},{"line_number":678,"context_line":"                original_network\u003doriginal_network)"},{"line_number":679,"context_line":""},{"line_number":680,"context_line":"            self.mechanism_manager.update_network_precommit(mech_context)"},{"line_number":681,"context_line":""},{"line_number":682,"context_line":"        # TODO(apech) - handle errors raised by update_network, potentially"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_71570858","line":679,"updated":"2015-08-21 13:35:28.000000000","message":"aaaaaahhhh an unrelated change!!!!","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":676,"context_line":"            mech_context \u003d driver_context.NetworkContext("},{"line_number":677,"context_line":"                self, context, updated_network,"},{"line_number":678,"context_line":"                original_network\u003doriginal_network)"},{"line_number":679,"context_line":""},{"line_number":680,"context_line":"            self.mechanism_manager.update_network_precommit(mech_context)"},{"line_number":681,"context_line":""},{"line_number":682,"context_line":"        # TODO(apech) - handle errors raised by update_network, potentially"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_66c74996","line":679,"in_reply_to":"fa1b9901_71570858","updated":"2015-08-21 13:48:22.000000000","message":"die unrelated change!!!. :)\n                                   __\n                      ____________| \u0026|____\n  unrelated change   /_____________\\   \u0026\u0026\u0026\u0026|\n                     \\_____________/   ____|\n                                  |__|\n\ndon\u0027t ask... I had that sword in my editor yet...","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"c479f3d864bd4835f13d17bb6ee8e7f33582be81","unresolved":false,"context_lines":[{"line_number":666,"context_line":"            self.type_manager.extend_network_dict_provider(context,"},{"line_number":667,"context_line":"                                                           updated_network)"},{"line_number":668,"context_line":""},{"line_number":669,"context_line":"            # TODO(QoS): Move out to the extension framework somehow."},{"line_number":670,"context_line":"            need_network_update_notify \u003d ("},{"line_number":671,"context_line":"                qos_consts.QOS_POLICY_ID in net_data and"},{"line_number":672,"context_line":"                original_network[qos_consts.QOS_POLICY_ID] !\u003d"}],"source_content_type":"text/x-python","patch_set":5,"id":"da20952f_b9725fac","line":669,"updated":"2015-08-26 15:47:09.000000000","message":"+1000","commit_id":"be2e1bbfe3bbf6d083c3da9ec2d1043fc047ed83"}],"neutron/plugins/ml2/rpc.py":[{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"623a78eea382305a87152add0683e6e84cc5a470","unresolved":false,"context_lines":[{"line_number":297,"context_line":"                                                          topics.NETWORK,"},{"line_number":298,"context_line":"                                                          topics.UPDATE)"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"        target \u003d oslo_messaging.Target(topic\u003dtopic, version\u003d\u00271.0\u0027)"},{"line_number":301,"context_line":"        self.client \u003d n_rpc.get_client(target)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"    def network_delete(self, context, network_id):"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_4666c5bb","line":300,"updated":"2015-08-21 13:48:22.000000000","message":"don\u0027t we need to change the target here?, or is it left for compatibility of the previous calls?\n\nSince upgrade of the server should happen first, agents last, server could still send the old messages to the old agents, and fail on the new ones?.\n\n/me is confused\n/me needs @akihiro","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"8836aecd0766d33ddedbe303b5b8468d5c560af4","unresolved":false,"context_lines":[{"line_number":297,"context_line":"                                                          topics.NETWORK,"},{"line_number":298,"context_line":"                                                          topics.UPDATE)"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"        target \u003d oslo_messaging.Target(topic\u003dtopic, version\u003d\u00271.0\u0027)"},{"line_number":301,"context_line":"        self.client \u003d n_rpc.get_client(target)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"    def network_delete(self, context, network_id):"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_1f269216","line":300,"in_reply_to":"fa1b9901_4666c5bb","updated":"2015-08-24 10:43:13.000000000","message":"It is a client side of RPC, so we need to keep the version of Target.  otherwise, methods added in the initial version will have a newer version.\nIn this case, we need to specify version\u003d1.2 in network_update explicitly.\n\nThere is a good write-up by Russel.\nhttp://docs.openstack.org/developer/neutron/devref/rpc_api.html","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"8836aecd0766d33ddedbe303b5b8468d5c560af4","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_7f878ed7","line":323,"updated":"2015-08-24 10:43:13.000000000","message":"Please pass version\u003d\"1.2\" to prepare.","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"730e2f8a2174c7c8cf64e8cd832ebb84628d1564","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_bff2066e","line":323,"in_reply_to":"fa1b9901_7f878ed7","updated":"2015-08-24 10:51:10.000000000","message":"Thanks amotoki!!!","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"3cb824a0e4dbf809088870a2573f43317ccf5c2c","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_7a723caf","line":323,"in_reply_to":"fa1b9901_ba51b410","updated":"2015-08-24 10:54:41.000000000","message":"note to the future reader, we\u0027re talking about this: https://bugs.launchpad.net/neutron/+bug/1112634 (thanks amotoki)","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"4dd9f01dc7f6ef92b433b91e0e49f037c22d498f","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa1b9901_ba51b410","line":323,"in_reply_to":"fa1b9901_bff2066e","updated":"2015-08-24 10:52:54.000000000","message":"As per IRC talk, we need to bump server side (OVS) to 1.4 and use 1.4 here.\n\nEventually we must split the RPC endpoints per feature in the OVS agent.","commit_id":"5c9d4fc22e9fafa241d9fcd916cfda981f88b405"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"6edb71a258deb2fff251fc0102ef254fd3d7294a","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_105f310f","line":323,"updated":"2015-08-28 11:09:33.000000000","message":"this breaks rolling upgrades. neutron server is upgraded first and will start requiring version 1.4 from the ovs agent...","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"92097dd5c139bc8028abb833d466b02d4ae21d15","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_8a4ea094","line":323,"in_reply_to":"da20952f_0e986dbf","updated":"2015-08-28 15:08:45.000000000","message":"About RPC versioning and rolling upgrade, to make it work, we need to combine RPC versioning and version capping. This is what nova does.\nIn this strategy, when upgrade, we first cap RPC version to an older version, upgrade all components to a latest version (at this point, only older version of RPC methods are used) and finally uncap RPC version and we get newer version of RPC methods.\n\nBTW, Neutron does not support version capping at now, so it does not harm anything even if we add a new topic or a new method without bumping RPC version. It works, but the reason I suggested to bump the version is because I hope live upgrade with version capping (and versioned object) and I don\u0027t want neutron community to have no good convention.\n\nRussel has an experience in Nova RPC and I would like to loop him here.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"fb517dc7ebfefc2692ad7cac8b77bc1b01380483","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_307ef519","line":323,"in_reply_to":"da20952f_105f310f","updated":"2015-08-28 11:17:16.000000000","message":"won\u0027t it be ignored by old agent?","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"0fccb07fe41abc486e1281a6fede74d3a9dbbdb6","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_0e986dbf","line":323,"in_reply_to":"da20952f_2bc76346","updated":"2015-08-28 12:12:16.000000000","message":"I checked port_delete was added at the end of Kilo, could somebody double check it?.\n\nThis is why I didn\u0027t touch port_delete.\n\nBtw, again it\u0027s a new topic and it should be ok for rolling upgrades.\n\nAbout incrementing the version, I don\u0027t know. I guess it\u0027s not strictly necessary since, as rosella said, it\u0027s a new topic which older agents won\u0027t subscribe,  @akihiro suggested to bump it, not sure if we\u0027re missing any reason here, I\u0027ll loop him here to check the conversation.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"9ff64eacfe99ed263e3a825681e00c5d6e947d1e","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_d064594a","line":323,"in_reply_to":"da20952f_307ef519","updated":"2015-08-28 11:20:23.000000000","message":"not sure. It\u0027s true that a new topic is created...but then I don\u0027t see the reason to have a new topic and increase the version","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"38a198414410ef1f669f756acf776ea1cdab7ef9","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_4b604acf","line":323,"in_reply_to":"da20952f_59c86422","updated":"2015-08-31 10:58:24.000000000","message":"thanks for the explanation Russell!","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":1561,"name":"Russell Bryant","email":"rbryant@redhat.com","username":"russellb"},"change_message_id":"7c4b1c01caaa9fc0163552f38e67c3bf948a4b39","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_e873a47e","line":323,"in_reply_to":"da20952f_8a4ea094","updated":"2015-08-28 15:35:02.000000000","message":"Lots of good discussion in here.\n\n1) Do we need to update the version number?\n\nShort answer: yes.\n\nThis interface uses multiple topics, but it puts them all together with a single version stream.  Even though this is a new topic, it\u0027s still a change to the overall interface under this version stream.  The version should be incremented.\n\nAs pointed out, in practice, no error will be generated on older rpc servers unless they subscribe to this new topic.  However, it would be easy to already be subscribed to this.  It\u0027d be easy to just say network.* and port.*, for example.\n\nHowever, we really need to keep a sane convention for version increments.  A new method is always a minor version increment.\n\n2) Does this break rolling upgrades?\n\nNo, if the current agents don\u0027t consume from this topic.\n\n3) What about version capping?\n\nThis is going to be needed eventually, for sure.  In any case where an older agent is going to receive messages from the neutron server, we need to ensure it works in a backwards compatible manner, which will likely eventually require adding version capping support.  It doesn\u0027t appear that this change forces us to add it, but reviewers should be on the lookout for this.\n\n4) What about when port_delete was added?\n\nIf port delete was added without bumping the version, that was wrong.  It should have increased the version.\n\n\nPlease feel free to add me to any reviews updating rpc interfaces.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"f146240a3c91da82adaba5f778b30637d2f10fb8","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_2bc76346","line":323,"in_reply_to":"da20952f_8b8790d6","updated":"2015-08-28 12:00:56.000000000","message":"@Rossela: We should. And we should fix the bug with port_delete not bumped the version :)\n\nThe reason behind the version is to get the exact ERROR we see with unsupported version, I guess otherwise we\u0027ll get AttributeError with TRACE (just guessing)","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"6ea13143780ba98aaba3c50c1cb757d1f027b111","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_8b754f99","line":323,"in_reply_to":"da20952f_d064594a","updated":"2015-08-28 11:50:06.000000000","message":"I don\u0027t think it\u0027s an issue. If neutron is running with RPC client side (neutron plugin) 1.4 and agent is running with server side of rpc 1.3, everything is ok untill 1.4 method is called from client (neutron plugin).\n\nOnce method is called, agent will print ERROR in log, that someone called method from 1.4 version and it\u0027s not supported, nothing else happens.\n\nBasically it means we won\u0027t be able to run network_updates with new neutron-server and old bits of agent, which is IMHO acceptable.\n\nSince it\u0027s a fanout and no result is expected from the call on ml2 plugin side, we\u0027re ok on server side as well.\n\nI\u0027ll post a link to useful document Akihiro posted in PS1.\nhttp://docs.openstack.org/developer/neutron/devref/rpc_api.html","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":6788,"name":"Rossella Sblendido","email":"rsblendido@suse.com","username":"rossella-o"},"change_message_id":"68575a14793199b49edfe7e59a7033f9f0fb92b5","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_8b8790d6","line":323,"in_reply_to":"da20952f_d064594a","updated":"2015-08-28 11:50:22.000000000","message":"I tested it, it doesn\u0027t break rolling upgrades since it\u0027s a new topic. Do we need to bump the version though? port_delete was added after the other methods and didn\u0027t bump the version.","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"cf9ba591cbbbebc92b38254fd4d602661a943fed","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def network_update(self, context, network):"},{"line_number":322,"context_line":"        cctxt \u003d self.client.prepare(topic\u003dself.topic_network_update,"},{"line_number":323,"context_line":"                                    fanout\u003dTrue, version\u003d\u00271.4\u0027)"},{"line_number":324,"context_line":"        cctxt.cast(context, \u0027network_update\u0027, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_59c86422","line":323,"in_reply_to":"da20952f_e873a47e","updated":"2015-08-28 16:43:16.000000000","message":"+1 to having an easy to follow convention.\n\nAlso versioned objects, + the remote callback \u0026 object retrieval should make this easier.\n\nThe idea is that agents can subscribe to certain object streams in specific versions, or request an object by type+id+version to the server.\n\nWe need to address rolling upgrades yet, because objects are sent by fanout and server needs either capping, or dynamic discovery of what versions do agents support (To send the object updates via the \u003ctype\u003e_\u003cversion\u003e fanout topics).\n\nhttp://docs.openstack.org/developer/neutron/devref/rpc_callbacks.html","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"}],"neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py":[{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"bea43565bb2453caa25040c64af377f4f30fc98d","unresolved":false,"context_lines":[{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    def test_network_update(self):"},{"line_number":643,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":644,"context_line":"        network \u003d {\u0027id\u0027: \u0027123\u0027}"},{"line_number":645,"context_line":"        port \u003d {\u0027id\u0027: \u0027abc\u0027, \u0027network_id\u0027: \u0027123\u0027}"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa1b9901_6c5ecaea","line":644,"updated":"2015-08-25 12:23:21.000000000","message":"refactoring the ids to constants...","commit_id":"5231f39915f4fbb6b1259543b7e29662d869cfa5"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"c2fcdaba8886c20074ce58fe20d279cf0784d575","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port\u003dport)"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set([port[\u0027id\u0027]]), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"da20952f_67e4113b","line":670,"updated":"2015-08-26 20:57:19.000000000","message":"I\u0027m confused about what this is verifying. Based on the new logic in the agent, it seems to me that if a port_delete arrives first, the port will be in deleted_ports so it shouldn\u0027t be added to updated_ports. But this assertion is checking that it is in there...\n\nAlso, port_delete doesn\u0027t take port as an argument, it extracts port_id directly from the kwargs. I think what is happening here is that the port_delete is adding None instead of the port_id to deleted_ports so the logic to skip a deleted port isn\u0027t working.","commit_id":"be2e1bbfe3bbf6d083c3da9ec2d1043fc047ed83"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"46a2b29bbe3486f60cf9e0c292f2d59327756d69","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port\u003dport)"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set([port[\u0027id\u0027]]), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"da20952f_a9a0a9f5","line":670,"in_reply_to":"da20952f_67e4113b","updated":"2015-08-27 07:32:04.000000000","message":"Oh crap, you\u0027re right, good catch, how was I able to write such stupid test, using .assertEqual was not even some evil way of monkey patching...\n\nFixing...","commit_id":"be2e1bbfe3bbf6d083c3da9ec2d1043fc047ed83"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"b5e971b59fa9e6cddcd4ab4dc313af3339fed002","unresolved":false,"context_lines":[{"line_number":646,"context_line":"                               physical_network\u003d\"physnet\")"},{"line_number":647,"context_line":"        self.assertEqual(set([TEST_PORT_ID1]), self.agent.updated_ports)"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_a973bbb0","line":649,"updated":"2015-08-27 11:56:38.000000000","message":"maybe you are lacking a unit test that validate that a port delete also removes the port from updated_ports, and network_ports","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"9ab22b759d069af1b37074d73aeee23134fbcc55","unresolved":false,"context_lines":[{"line_number":646,"context_line":"                               physical_network\u003d\"physnet\")"},{"line_number":647,"context_line":"        self.assertEqual(set([TEST_PORT_ID1]), self.agent.updated_ports)"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_ac2664b8","line":649,"in_reply_to":"da20952f_7d09dd2b","updated":"2015-08-27 13:37:21.000000000","message":"Done","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a8c26b58d8814a24cc0885f5b572c7a6d21e03d1","unresolved":false,"context_lines":[{"line_number":646,"context_line":"                               physical_network\u003d\"physnet\")"},{"line_number":647,"context_line":"        self.assertEqual(set([TEST_PORT_ID1]), self.agent.updated_ports)"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_7d09dd2b","line":649,"in_reply_to":"da20952f_a973bbb0","updated":"2015-08-27 13:08:59.000000000","message":"removing from network ports is handled by the inner logic of the main rpc loop, imagine somebody sends a port delete while you\u0027re in the main loop, you\u0027ll fail to find the port network you were looking for.\n\nMay be I should validate that inner logic will do the _update_port_network or remove/cleanup.\n\nBut port_delete, even if it\u0027s a bit off_topic from this specific patch, is quite relate, I will add that.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"19e4c10d51eea4a7843f134183082e7e88e3924f","unresolved":false,"context_lines":[{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":655,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_c974ef9d","line":652,"updated":"2015-08-27 11:55:10.000000000","message":"Why change from TEST_NETWORK_ID1 to network[\u0027id\u0027] ?","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a8c26b58d8814a24cc0885f5b572c7a6d21e03d1","unresolved":false,"context_lines":[{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":655,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_fd1ded66","line":652,"in_reply_to":"da20952f_c974ef9d","updated":"2015-08-27 13:08:59.000000000","message":"Because if I needed to change the network ID then I only need to\ndo it on one place rather than two :)","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"0cc5716cbfbb99bdde76f697a5213cee659dfb6d","unresolved":false,"context_lines":[{"line_number":649,"context_line":"    def test_network_update(self):"},{"line_number":650,"context_line":"        \"\"\"Network update marks port for update. \"\"\""},{"line_number":651,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":652,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":655,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_16d2fb00","line":652,"in_reply_to":"da20952f_fd1ded66","updated":"2015-08-27 15:29:02.000000000","message":"Which is the TEST_NETWORK_ID1 constant but nevermind :)","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"19e4c10d51eea4a7843f134183082e7e88e3924f","unresolved":false,"context_lines":[{"line_number":662,"context_line":"        so we ensure the port is not marked for update."},{"line_number":663,"context_line":"        \"\"\""},{"line_number":664,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":665,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_e9a0d3f6","line":665,"updated":"2015-08-27 11:55:10.000000000","message":"Ditto.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"0cc5716cbfbb99bdde76f697a5213cee659dfb6d","unresolved":false,"context_lines":[{"line_number":662,"context_line":"        so we ensure the port is not marked for update."},{"line_number":663,"context_line":"        \"\"\""},{"line_number":664,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":665,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_9604cb7e","line":665,"in_reply_to":"da20952f_bd2695b8","updated":"2015-08-27 15:29:02.000000000","message":"Same \"nevermind\" :)","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a8c26b58d8814a24cc0885f5b572c7a6d21e03d1","unresolved":false,"context_lines":[{"line_number":662,"context_line":"        so we ensure the port is not marked for update."},{"line_number":663,"context_line":"        \"\"\""},{"line_number":664,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":665,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_bd2695b8","line":665,"in_reply_to":"da20952f_e9a0d3f6","updated":"2015-08-27 13:08:59.000000000","message":"Same reason.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"19e4c10d51eea4a7843f134183082e7e88e3924f","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set(), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_0963c7dd","line":670,"updated":"2015-08-27 11:55:10.000000000","message":"Nit: self.assertFalse(self.agent.updated_ports)","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"b5e971b59fa9e6cddcd4ab4dc313af3339fed002","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set(), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_49c53f8c","line":670,"in_reply_to":"da20952f_0963c7dd","updated":"2015-08-27 11:56:38.000000000","message":"I\u0027d use empty set explicitly otherwise we\u0027ll end up introducing some bug that sets updated_ports to None and we will miss it","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a8c26b58d8814a24cc0885f5b572c7a6d21e03d1","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set(), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_1d3221f2","line":670,"in_reply_to":"da20952f_09c5073b","updated":"2015-08-27 13:08:59.000000000","message":"And that\u0027s subjective, but set() seems like more explicit to the test reader.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"11640d97efdb45bf250cce7e1864c4966450d618","unresolved":false,"context_lines":[{"line_number":667,"context_line":"        self.agent._update_port_network(port[\u0027id\u0027], port[\u0027network_id\u0027])"},{"line_number":668,"context_line":"        self.agent.port_delete(context\u003dNone, port_id\u003dport[\u0027id\u0027])"},{"line_number":669,"context_line":"        self.agent.network_update(context\u003dNone, network\u003dnetwork)"},{"line_number":670,"context_line":"        self.assertEqual(set(), self.agent.updated_ports)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    def test_update_port_network(self):"},{"line_number":673,"context_line":"        \"\"\"Ensure ports are associated and moved across networks correctly.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_09c5073b","line":670,"in_reply_to":"da20952f_49c53f8c","updated":"2015-08-27 12:02:29.000000000","message":"Aha.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"b5e971b59fa9e6cddcd4ab4dc313af3339fed002","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.agent._update_port_network(TEST_PORT_ID1, TEST_NETWORK_ID1)"},{"line_number":675,"context_line":"        self.agent._update_port_network(TEST_PORT_ID2, TEST_NETWORK_ID1)"},{"line_number":676,"context_line":"        self.agent._update_port_network(TEST_PORT_ID3, TEST_NETWORK_ID2)"},{"line_number":677,"context_line":"        self.agent._update_port_network(TEST_PORT_ID1, TEST_NETWORK_ID2)"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"        self.assertEqual(set([TEST_PORT_ID2]),"},{"line_number":680,"context_line":"                         self.agent.network_ports[TEST_NETWORK_ID1])"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_6994c38a","line":677,"updated":"2015-08-27 11:56:38.000000000","message":"the line above simulates a port changing networks. This is impossible, but I understand here you\u0027re just doing white box testing of operations so it might be ok for me.","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"a8c26b58d8814a24cc0885f5b572c7a6d21e03d1","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.agent._update_port_network(TEST_PORT_ID1, TEST_NETWORK_ID1)"},{"line_number":675,"context_line":"        self.agent._update_port_network(TEST_PORT_ID2, TEST_NETWORK_ID1)"},{"line_number":676,"context_line":"        self.agent._update_port_network(TEST_PORT_ID3, TEST_NETWORK_ID2)"},{"line_number":677,"context_line":"        self.agent._update_port_network(TEST_PORT_ID1, TEST_NETWORK_ID2)"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"        self.assertEqual(set([TEST_PORT_ID2]),"},{"line_number":680,"context_line":"                         self.agent.network_ports[TEST_NETWORK_ID1])"}],"source_content_type":"text/x-python","patch_set":6,"id":"da20952f_5dadf9e7","line":677,"in_reply_to":"da20952f_6994c38a","updated":"2015-08-27 13:08:59.000000000","message":"Come\u0027on, can\u0027t we do that?.\n\nI\u0027m white boxing that it will cleanup from one and add to the other, may be one day we\u0027ll do things like that :)","commit_id":"4cfee8e3179b919d7eb2482cd99dfef48752e0da"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a432641aa342f66a49f19818f67e18f867435753","unresolved":false,"context_lines":[{"line_number":676,"context_line":"        \"\"\"Network update arrives later than port_delete."},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"        But the main agent loop still didn\u0027t process the ports,"},{"line_number":679,"context_line":"        so we ensure the port is not marked for update."},{"line_number":680,"context_line":"        \"\"\""},{"line_number":681,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":682,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_a3a96ae1","line":679,"updated":"2015-08-28 07:01:35.000000000","message":"This kind of description is really helpful :-)","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"5e904f6d9102288d931d6c4f68f7261b7a3cbbfc","unresolved":false,"context_lines":[{"line_number":676,"context_line":"        \"\"\"Network update arrives later than port_delete."},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"        But the main agent loop still didn\u0027t process the ports,"},{"line_number":679,"context_line":"        so we ensure the port is not marked for update."},{"line_number":680,"context_line":"        \"\"\""},{"line_number":681,"context_line":"        network \u003d {\u0027id\u0027: TEST_NETWORK_ID1}"},{"line_number":682,"context_line":"        port \u003d {\u0027id\u0027: TEST_PORT_ID1, \u0027network_id\u0027: network[\u0027id\u0027]}"}],"source_content_type":"text/x-python","patch_set":7,"id":"da20952f_061ce410","line":679,"in_reply_to":"da20952f_a3a96ae1","updated":"2015-08-28 07:13:07.000000000","message":"Thanks :D","commit_id":"b292e197ff8fde50823717263ae0b13fc66c980b"}]}
