)]}'
{"neutron/db/migration/alembic_migrations/versions/157a5d299379_ml2_binding_profile.py":[{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"688c0987af75ce5eeeff51ca9ca9952347e08bb1","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095), nullable\u003dFalse))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUX%2F%2FPWY%3D","line":47,"updated":"2014-02-14 16:06:24.000000000","message":"I forgot to add code like in https://review.openstack.org/#/c/72452/3/neutron/db/migration/alembic_migrations/versions/50d5ba354c23_ml2_binding_vif_details.py to handle the new non-nullable column.","commit_id":"ee388c3112920dfe8a0e1520b0796f809a0bd24e"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"ea53e9a4175cd01fafe6452196775241afb94107","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095), nullable\u003dFalse))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUX%2F%2FNNQ%3D","line":47,"in_reply_to":"AAAAUX%2F%2FPWY%3D","updated":"2014-02-14 21:24:35.000000000","message":"Done","commit_id":"ee388c3112920dfe8a0e1520b0796f809a0bd24e"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"f05b817846de5a0b9bceb847e0cd01903a1f54bc","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095), nullable\u003dFalse))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    # Set profile to \u0027\u0027 for existing binding records"},{"line_number":50,"context_line":"    op.execute(\"UPDATE ml2_port_bindings SET profile\u003d\u0027\u0027\")"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2FJKU%3D","line":47,"updated":"2014-02-16 06:37:05.000000000","message":"I think this operation will fail. You need to provide default value in order to add non-nullable column to existing rows. L50 doesn\u0027t help","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e4be175237da7abe6a98049ab7dba8d005a26ae8","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095), nullable\u003dFalse))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    # Set profile to \u0027\u0027 for existing binding records"},{"line_number":50,"context_line":"    op.execute(\"UPDATE ml2_port_bindings SET profile\u003d\u0027\u0027\")"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B2fs%3D","line":47,"in_reply_to":"AAAAUX%2F%2FJAY%3D","updated":"2014-02-18 17:27:43.000000000","message":"Done","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"8e73610d21cd4d3683654528fa4f866668e44deb","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095), nullable\u003dFalse))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    # Set profile to \u0027\u0027 for existing binding records"},{"line_number":50,"context_line":"    op.execute(\"UPDATE ml2_port_bindings SET profile\u003d\u0027\u0027\")"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2FJAY%3D","line":47,"in_reply_to":"AAAAUX%2F%2FJKU%3D","updated":"2014-02-16 09:00:35.000000000","message":"the default value for add_column method is provided by server_default attribute of Column","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"d4ecc70dc343bc6247db57efac3a81a87fc3ff55","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1uo%3D","line":48,"updated":"2014-02-18 17:43:09.000000000","message":"What about update for existing entries? Isn\u0027t it needed any more?","commit_id":"8039e4b06cde4ae900fc2644e12e004a0e0cde2c"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"d3cc816dd0a37e3d7bfb79d2422e093cd6352746","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1WU%3D","line":48,"in_reply_to":"AAAAUX%2F%2B1Y0%3D","updated":"2014-02-18 18:12:11.000000000","message":"Understood. Will apply this approach in vnic_type patch too","commit_id":"8039e4b06cde4ae900fc2644e12e004a0e0cde2c"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"5c1975c7ff51cfc2d5980170ac46cce25c52c94b","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1Y0%3D","line":48,"in_reply_to":"AAAAUX%2F%2B1uo%3D","updated":"2014-02-18 18:06:59.000000000","message":"According to enikanorov, specifying server_default\u003d\u0027\u0027 will set the value for the new column in existing rows, and the old approach would not work.","commit_id":"8039e4b06cde4ae900fc2644e12e004a0e0cde2c"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"change_message_id":"255bd4251598d4882e7265c8790a72e8b4d14b93","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2Bqx8%3D","line":47,"updated":"2014-02-19 21:58:47.000000000","message":"Not Text?","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"ebcbf21c0b7990c97e13f74c069c9193e0bc209b","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2Bbyg%3D","line":47,"in_reply_to":"AAAAUX%2F%2BpKs%3D","updated":"2014-02-21 06:34:44.000000000","message":"It seems default values cannot be used with sa.Text(), and 4095 chars should be plenty of space, so I added a check to raise InvalidInput if the encoded value is too big.","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"11f8e96fdb8d1c8872ad9de5e83bf71d7a4266f7","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        return"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    op.add_column(\u0027ml2_port_bindings\u0027,"},{"line_number":47,"context_line":"                  sa.Column(\u0027profile\u0027, sa.String(length\u003d4095),"},{"line_number":48,"context_line":"                            nullable\u003dFalse, server_default\u003d\u0027\u0027))"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2BpKs%3D","line":47,"in_reply_to":"AAAAUX%2F%2Bqx8%3D","updated":"2014-02-20 02:17:08.000000000","message":"I agree sa.Text() could be used here, and would have the advantage of not limiting the size of the encoded binding:profile attribute. But my understanding is that Text() is significantly less efficient. Using String(length\u003d4095) follows the precedent set with the configurations field in neutron.db.agents_db.Agent, which is also JSON-encoded. I don\u0027t expect the 4095 limit to be reached in practice, and this attribute cannot be written by normal users, but maybe its worth checking the length after encoding, and raising an exception if the user tries to set a value that\u0027s too long. Or I could switch to Text(). Which do you prefer?","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"500a9450be72c5cb4e199399c399139af5261cfd","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"# revision identifiers, used by Alembic."},{"line_number":27,"context_line":"revision \u003d \u0027157a5d299379\u0027"},{"line_number":28,"context_line":"down_revision \u003d \u00274ca36cfc898c\u0027"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"# Change to [\u0027*\u0027] if this migration applies to all plugins"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2F%2Bl8%3D","line":28,"updated":"2014-02-23 05:50:21.000000000","message":"down revision should  be updated (currently to 27cc183af192)","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e5272382460651b57f4adf46f889e84c12da2053","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"# revision identifiers, used by Alembic."},{"line_number":27,"context_line":"revision \u003d \u0027157a5d299379\u0027"},{"line_number":28,"context_line":"down_revision \u003d \u00274ca36cfc898c\u0027"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"# Change to [\u0027*\u0027] if this migration applies to all plugins"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2F1JI%3D","line":28,"in_reply_to":"AAAAU3%2F%2F%2Bl8%3D","updated":"2014-02-24 17:33:57.000000000","message":"Done","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"}],"neutron/plugins/ml2/db.py":[{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"d4ecc70dc343bc6247db57efac3a81a87fc3ff55","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        except exc.NoResultFound:"},{"line_number":70,"context_line":"            record \u003d models.PortBinding("},{"line_number":71,"context_line":"                port_id\u003dport_id,"},{"line_number":72,"context_line":"                host\u003d\u0027\u0027,"},{"line_number":73,"context_line":"                vif_type\u003dportbindings.VIF_TYPE_UNBOUND,"},{"line_number":74,"context_line":"                cap_port_filter\u003dFalse)"},{"line_number":75,"context_line":"            session.add(record)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1uU%3D","side":"PARENT","line":72,"updated":"2014-02-18 17:43:09.000000000","message":"Why host was removed?","commit_id":"74674077e88feb446fec6a3e958548d6be219b0f"},{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"d3cc816dd0a37e3d7bfb79d2422e093cd6352746","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        except exc.NoResultFound:"},{"line_number":70,"context_line":"            record \u003d models.PortBinding("},{"line_number":71,"context_line":"                port_id\u003dport_id,"},{"line_number":72,"context_line":"                host\u003d\u0027\u0027,"},{"line_number":73,"context_line":"                vif_type\u003dportbindings.VIF_TYPE_UNBOUND,"},{"line_number":74,"context_line":"                cap_port_filter\u003dFalse)"},{"line_number":75,"context_line":"            session.add(record)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1WA%3D","side":"PARENT","line":72,"in_reply_to":"AAAAUX%2F%2B1ak%3D","updated":"2014-02-18 18:12:11.000000000","message":"Fine. Thanks","commit_id":"74674077e88feb446fec6a3e958548d6be219b0f"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"5c1975c7ff51cfc2d5980170ac46cce25c52c94b","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        except exc.NoResultFound:"},{"line_number":70,"context_line":"            record \u003d models.PortBinding("},{"line_number":71,"context_line":"                port_id\u003dport_id,"},{"line_number":72,"context_line":"                host\u003d\u0027\u0027,"},{"line_number":73,"context_line":"                vif_type\u003dportbindings.VIF_TYPE_UNBOUND,"},{"line_number":74,"context_line":"                cap_port_filter\u003dFalse)"},{"line_number":75,"context_line":"            session.add(record)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B1ak%3D","side":"PARENT","line":72,"in_reply_to":"AAAAUX%2F%2B1uU%3D","updated":"2014-02-18 18:06:59.000000000","message":"It was no longer needed once default\u003d\u0027\u0027 was added where the column is defined in model.py.","commit_id":"74674077e88feb446fec6a3e958548d6be219b0f"},{"author":{"_account_id":2031,"name":"Nachi Ueno","email":"nati.ueno@gmail.com","username":"nati-ueno"},"change_message_id":"255bd4251598d4882e7265c8790a72e8b4d14b93","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        except exc.NoResultFound:"},{"line_number":70,"context_line":"            record \u003d models.PortBinding("},{"line_number":71,"context_line":"                port_id\u003dport_id,"},{"line_number":72,"context_line":"                host\u003d\u0027\u0027,"},{"line_number":73,"context_line":"                vif_type\u003dportbindings.VIF_TYPE_UNBOUND,"},{"line_number":74,"context_line":"                cap_port_filter\u003dFalse)"},{"line_number":75,"context_line":"            session.add(record)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2BqxM%3D","side":"PARENT","line":72,"updated":"2014-02-19 21:58:47.000000000","message":"Is this related change?","commit_id":"7fb2d579ae5d14fdb538b6f7fde6f58b533c82ba"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"11f8e96fdb8d1c8872ad9de5e83bf71d7a4266f7","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        except exc.NoResultFound:"},{"line_number":70,"context_line":"            record \u003d models.PortBinding("},{"line_number":71,"context_line":"                port_id\u003dport_id,"},{"line_number":72,"context_line":"                host\u003d\u0027\u0027,"},{"line_number":73,"context_line":"                vif_type\u003dportbindings.VIF_TYPE_UNBOUND,"},{"line_number":74,"context_line":"                cap_port_filter\u003dFalse)"},{"line_number":75,"context_line":"            session.add(record)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2BpTs%3D","side":"PARENT","line":72,"in_reply_to":"AAAAUX%2F%2BqxM%3D","updated":"2014-02-20 02:17:08.000000000","message":"This was changed for consistency. There is no need for code such as this to set the default when there is a default for the column in the model class with the same value.","commit_id":"7fb2d579ae5d14fdb538b6f7fde6f58b533c82ba"}],"neutron/plugins/ml2/models.py":[{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e4be175237da7abe6a98049ab7dba8d005a26ae8","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B2dg%3D","line":55,"updated":"2014-02-18 17:27:43.000000000","message":"I also added default\u003d\u0027\u0027 here for consistency.","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"f05b817846de5a0b9bceb847e0cd01903a1f54bc","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"},{"line_number":59,"context_line":"    driver \u003d sa.Column(sa.String(64))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2FJKI%3D","line":56,"updated":"2014-02-16 06:37:05.000000000","message":"default\u003d\u0027\u0027?","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e4be175237da7abe6a98049ab7dba8d005a26ae8","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"},{"line_number":59,"context_line":"    driver \u003d sa.Column(sa.String(64))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B2eQ%3D","line":56,"in_reply_to":"AAAAUX%2F%2FJKI%3D","updated":"2014-02-18 17:27:43.000000000","message":"Done","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"3bb63e3e51ddfcf9cb4ce46c6a17dd848615b5f8","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"},{"line_number":59,"context_line":"    driver \u003d sa.Column(sa.String(64))"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2Bqow%3D","line":56,"updated":"2014-02-19 22:19:28.000000000","message":"IMHO, it seems strange to use an empty string to represent an empty profile, using NULL for such case seems clearer","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"10a3202c3da9ffa1bef4b7df5f81aa92c08f7ea0","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"},{"line_number":59,"context_line":"    driver \u003d sa.Column(sa.String(64))"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2Bk5w%3D","line":56,"in_reply_to":"AAAAUX%2F%2BpQQ%3D","updated":"2014-02-20 12:22:02.000000000","message":"I learn something, thanks :)","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"11f8e96fdb8d1c8872ad9de5e83bf71d7a4266f7","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":54,"context_line":"                        primary_key\u003dTrue)"},{"line_number":55,"context_line":"    host \u003d sa.Column(sa.String(255), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":56,"context_line":"    profile \u003d sa.Column(sa.String(4095), nullable\u003dFalse, default\u003d\u0027\u0027)"},{"line_number":57,"context_line":"    vif_type \u003d sa.Column(sa.String(64), nullable\u003dFalse)"},{"line_number":58,"context_line":"    cap_port_filter \u003d sa.Column(sa.Boolean, nullable\u003dFalse)"},{"line_number":59,"context_line":"    driver \u003d sa.Column(sa.String(64))"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUX%2F%2BpQQ%3D","line":56,"in_reply_to":"AAAAUX%2F%2Bqow%3D","updated":"2014-02-20 02:17:08.000000000","message":"My understanding, which could be wrong, is that most DBs are more efficient with non-nullable columns. One corroborating article on this is http://dba.stackexchange.com/questions/63/null-or-not-null-by-default. The python code is pretty much the same either way. Also, this follows the precedent set with the configurations field of neutron.db.agents_db.Agent, which is also JSON-encoded.","commit_id":"9854c6b3b8c03880ae65f5ed5453ac6287cda709"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"96742c87fa1fba7f2785a3d9254280f8ce59cc01","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from neutron.db import models_v2"},{"line_number":21,"context_line":"from neutron.extensions import portbindings"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"BINDING_PROFILE_LEN \u003d 4095"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class NetworkSegment(model_base.BASEV2, models_v2.HasId):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAU3%2F%2Ftvo%3D","line":23,"updated":"2014-02-25 05:17:13.000000000","message":"why even limit it?","commit_id":"cb106a719378de69b7656f7f30566dd68e51576b"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"7878ffab1c1a1a93d818a69b56cab43ae65d43e8","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from neutron.db import models_v2"},{"line_number":21,"context_line":"from neutron.extensions import portbindings"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"BINDING_PROFILE_LEN \u003d 4095"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class NetworkSegment(model_base.BASEV2, models_v2.HasId):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAU3%2F%2Ftdg%3D","line":23,"in_reply_to":"AAAAU3%2F%2Fte8%3D","updated":"2014-02-25 05:59:05.000000000","message":"or just string() and not have to deal with a max length, no worries though.","commit_id":"cb106a719378de69b7656f7f30566dd68e51576b"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"9f0a15ae6db7aae1134be74d150cc3e213931c31","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from neutron.db import models_v2"},{"line_number":21,"context_line":"from neutron.extensions import portbindings"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"BINDING_PROFILE_LEN \u003d 4095"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class NetworkSegment(model_base.BASEV2, models_v2.HasId):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAU3%2F%2Fte8%3D","line":23,"in_reply_to":"AAAAU3%2F%2Ftvo%3D","updated":"2014-02-25 05:56:20.000000000","message":"binding.profile is stored in db in ML2 plugin and 4095 is the length of the field of the db. In my understanding there is no special reason we choose 4K not 8K or other length.","commit_id":"cb106a719378de69b7656f7f30566dd68e51576b"}],"neutron/plugins/ml2/plugin.py":[{"author":{"_account_id":6598,"name":"Berezovsky Irena","email":"irenab.dev@gmail.com","username":"irenab"},"change_message_id":"05cada60f220910ecacdde9a0b318bc060df2606","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        if profile_set:"},{"line_number":234,"context_line":"            binding.profile \u003d jsonutils.dumps(profile)"},{"line_number":235,"context_line":"            port[portbindings.PROFILE] \u003d self._get_profile(binding)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        if binding.host:"},{"line_number":238,"context_line":"            self.mechanism_manager.bind_port(mech_context)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2FIyg%3D","line":235,"updated":"2014-02-16 13:58:32.000000000","message":"Shouldn\u0027t the profile be updated once changed?\nThe following code block line 237 updates the port_dict only if binding.host is defined.","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e4be175237da7abe6a98049ab7dba8d005a26ae8","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        if profile_set:"},{"line_number":234,"context_line":"            binding.profile \u003d jsonutils.dumps(profile)"},{"line_number":235,"context_line":"            port[portbindings.PROFILE] \u003d self._get_profile(binding)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        if binding.host:"},{"line_number":238,"context_line":"            self.mechanism_manager.bind_port(mech_context)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B2Xk%3D","line":235,"in_reply_to":"AAAAUX%2F%2B8nM%3D","updated":"2014-02-18 17:27:43.000000000","message":"Line 234 updates the profile in the DB and line 235 updates the profile in the port dictionary, so I think both are updated every time the profile is modified, whether this triggers [re]binding or not. \n\nKyle is correct that line 237 is testing whether we can attempt to [re]bind, which requires host to be non-empty. I added a comment to clarify this.","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":105,"name":"Kyle Mestery","email":"mestery@mestery.com","username":"mestery"},"change_message_id":"41d29d9ea5390ecada9528c5214243cfbedab981","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        if profile_set:"},{"line_number":234,"context_line":"            binding.profile \u003d jsonutils.dumps(profile)"},{"line_number":235,"context_line":"            port[portbindings.PROFILE] \u003d self._get_profile(binding)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        if binding.host:"},{"line_number":238,"context_line":"            self.mechanism_manager.bind_port(mech_context)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B8nM%3D","line":235,"in_reply_to":"AAAAUX%2F%2FIyg%3D","updated":"2014-02-18 02:31:11.000000000","message":"I think we only want to update the port_dict (and thus the binding) if we found a host. Finding a profile is one thing, but without finding a host, we can\u0027t actually bind the port.","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":7183,"name":"Xu Han Peng","email":"xuhanp@linux.vnet.ibm.com","username":"xuhanp"},"change_message_id":"6a4679dd7b3bc32ac6dfd870a95bcf4bd4834e0e","unresolved":false,"context_lines":[{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    def _update_port_dict_binding(self, port, binding):"},{"line_number":244,"context_line":"        port[portbindings.HOST_ID] \u003d binding.host"},{"line_number":245,"context_line":"        port[portbindings.PROFILE] \u003d self._get_profile(binding)"},{"line_number":246,"context_line":"        port[portbindings.VIF_TYPE] \u003d binding.vif_type"},{"line_number":247,"context_line":"        port[portbindings.CAPABILITIES] \u003d {"},{"line_number":248,"context_line":"            portbindings.CAP_PORT_FILTER: binding.cap_port_filter}"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2FCTs%3D","line":245,"updated":"2014-02-17 14:18:39.000000000","message":"_get_profile is executed the second time after line 235. \n\nAlso profile is encoded at line 243 and decoded at line 253. Can this be refactored?","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e4be175237da7abe6a98049ab7dba8d005a26ae8","unresolved":false,"context_lines":[{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    def _update_port_dict_binding(self, port, binding):"},{"line_number":244,"context_line":"        port[portbindings.HOST_ID] \u003d binding.host"},{"line_number":245,"context_line":"        port[portbindings.PROFILE] \u003d self._get_profile(binding)"},{"line_number":246,"context_line":"        port[portbindings.VIF_TYPE] \u003d binding.vif_type"},{"line_number":247,"context_line":"        port[portbindings.CAPABILITIES] \u003d {"},{"line_number":248,"context_line":"            portbindings.CAP_PORT_FILTER: binding.cap_port_filter}"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUX%2F%2B2Iw%3D","line":245,"in_reply_to":"AAAAUX%2F%2FCTs%3D","updated":"2014-02-18 17:27:43.000000000","message":"For now, I\u0027ve changed line 235 to not call _get_profile().\n\nI\u0027d prefer not to do more significant refactoring of this code right now because several different patches are all making similar changes, and because the fix for https://bugs.launchpad.net/neutron/+bug/1276391 will be a better opportunity to optimize the logic here.","commit_id":"f7a5889c999a5634d108ef46b64bf548d3a6fae0"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"2e3f5916416334b3a1ddc8e711cce5ef13a8286a","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        host \u003d attrs and attrs.get(portbindings.HOST_ID)"},{"line_number":211,"context_line":"        host_set \u003d attributes.is_attr_set(host)"},{"line_number":212,"context_line":"        profile \u003d attrs and attrs.get(portbindings.PROFILE)"},{"line_number":213,"context_line":"        profile_set \u003d attributes.is_attr_set(profile)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        if binding.vif_type !\u003d portbindings.VIF_TYPE_UNBOUND:"},{"line_number":216,"context_line":"            if (not host_set and not profile_set and binding.segment and"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2F8dE%3D","line":213,"updated":"2014-02-23 20:17:13.000000000","message":"binding:profile None can be passed in an API request. binding None means to clear binding:profile. In my understanding None has the same meaning as {}.\n\nThe main reason of allowing None is not technically, but at the moment we need to use None to clear binding:profile because there is no way to specify {} in CLI.","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e5272382460651b57f4adf46f889e84c12da2053","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        host \u003d attrs and attrs.get(portbindings.HOST_ID)"},{"line_number":211,"context_line":"        host_set \u003d attributes.is_attr_set(host)"},{"line_number":212,"context_line":"        profile \u003d attrs and attrs.get(portbindings.PROFILE)"},{"line_number":213,"context_line":"        profile_set \u003d attributes.is_attr_set(profile)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        if binding.vif_type !\u003d portbindings.VIF_TYPE_UNBOUND:"},{"line_number":216,"context_line":"            if (not host_set and not profile_set and binding.segment and"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2Fz3E%3D","line":213,"in_reply_to":"AAAAU3%2F%2F8dE%3D","updated":"2014-02-24 17:33:57.000000000","message":"Good catch! Adding a unit test for this as well.","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"2e3f5916416334b3a1ddc8e711cce5ef13a8286a","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        if profile_set:"},{"line_number":234,"context_line":"            binding.profile \u003d jsonutils.dumps(profile)"},{"line_number":235,"context_line":"            if len(binding.profile) \u003e 4095:"},{"line_number":236,"context_line":"                msg \u003d _(\"binding:profile value too large\")"},{"line_number":237,"context_line":"                raise exc.InvalidInput(error_message\u003dmsg)"},{"line_number":238,"context_line":"            port[portbindings.PROFILE] \u003d profile"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2F8dA%3D","line":235,"updated":"2014-02-23 20:17:13.000000000","message":"4095 should be defined as a constant.","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"},{"author":{"_account_id":1689,"name":"Robert Kukura","email":"rk@theep.net","username":"rkukura"},"change_message_id":"e5272382460651b57f4adf46f889e84c12da2053","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        if profile_set:"},{"line_number":234,"context_line":"            binding.profile \u003d jsonutils.dumps(profile)"},{"line_number":235,"context_line":"            if len(binding.profile) \u003e 4095:"},{"line_number":236,"context_line":"                msg \u003d _(\"binding:profile value too large\")"},{"line_number":237,"context_line":"                raise exc.InvalidInput(error_message\u003dmsg)"},{"line_number":238,"context_line":"            port[portbindings.PROFILE] \u003d profile"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAU3%2F%2F1Bs%3D","line":235,"in_reply_to":"AAAAU3%2F%2F8dA%3D","updated":"2014-02-24 17:33:57.000000000","message":"Done","commit_id":"35f6b44f92f924d3f66322f5b837518d9b7899a3"}]}
